From fe707a23fc6dc0bccb3e80201bf3e4146dcde74e Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 23 May 2013 21:29:18 +0200 Subject: [PATCH] hpkg format: Add attributes for declaring settings files Global and user settings files can be declared. For global ones an update policy can be specified. If not specified, the settings file is not included in the package, but created by the program (or user) later. If an update type is specified, it defines what to do with the settings file when updating the package to a newer version. User settings files are never included in the package; they are always created by the program or the user. If the package contains a template/ default settings file, it can be declared, but for informative purposes only. --- .../build/os/package/GlobalSettingsFileInfo.h | 1 + .../build/os/package/SettingsFileUpdateType.h | 1 + .../build/os/package/UserSettingsFileInfo.h | 1 + headers/os/package/GlobalSettingsFileInfo.h | 41 ++ headers/os/package/PackageInfo.h | 39 ++ headers/os/package/PackageInfoAttributes.h | 6 +- headers/os/package/SettingsFileUpdateType.h | 35 ++ headers/os/package/UserSettingsFileInfo.h | 39 ++ headers/os/package/hpkg/HPKGDefs.h | 88 ++-- .../package/hpkg/PackageInfoAttributeValue.h | 15 + headers/private/package/hpkg/ReaderImplBase.h | 61 ++- src/bin/package/command_list.cpp | 22 + src/build/libpackage/Jamfile | 2 + src/kits/package/GlobalSettingsFileInfo.cpp | 74 ++++ src/kits/package/Jamfile | 2 + src/kits/package/PackageInfo.cpp | 396 +++++++++++++++++- src/kits/package/UserSettingsFileInfo.cpp | 64 +++ src/kits/package/hpkg/ReaderImplBase.cpp | 158 +++++-- src/kits/package/hpkg/WriterImplBase.cpp | 45 ++ 19 files changed, 999 insertions(+), 91 deletions(-) create mode 100644 headers/build/os/package/GlobalSettingsFileInfo.h create mode 100644 headers/build/os/package/SettingsFileUpdateType.h create mode 100644 headers/build/os/package/UserSettingsFileInfo.h create mode 100644 headers/os/package/GlobalSettingsFileInfo.h create mode 100644 headers/os/package/SettingsFileUpdateType.h create mode 100644 headers/os/package/UserSettingsFileInfo.h create mode 100644 src/kits/package/GlobalSettingsFileInfo.cpp create mode 100644 src/kits/package/UserSettingsFileInfo.cpp diff --git a/headers/build/os/package/GlobalSettingsFileInfo.h b/headers/build/os/package/GlobalSettingsFileInfo.h new file mode 100644 index 0000000000..6e17a15d21 --- /dev/null +++ b/headers/build/os/package/GlobalSettingsFileInfo.h @@ -0,0 +1 @@ +#include <../os/package/GlobalSettingsFileInfo.h> diff --git a/headers/build/os/package/SettingsFileUpdateType.h b/headers/build/os/package/SettingsFileUpdateType.h new file mode 100644 index 0000000000..ab52190853 --- /dev/null +++ b/headers/build/os/package/SettingsFileUpdateType.h @@ -0,0 +1 @@ +#include <../os/package/SettingsFileUpdateType.h> diff --git a/headers/build/os/package/UserSettingsFileInfo.h b/headers/build/os/package/UserSettingsFileInfo.h new file mode 100644 index 0000000000..dfb2034eee --- /dev/null +++ b/headers/build/os/package/UserSettingsFileInfo.h @@ -0,0 +1 @@ +#include <../os/package/UserSettingsFileInfo.h> diff --git a/headers/os/package/GlobalSettingsFileInfo.h b/headers/os/package/GlobalSettingsFileInfo.h new file mode 100644 index 0000000000..735e250e17 --- /dev/null +++ b/headers/os/package/GlobalSettingsFileInfo.h @@ -0,0 +1,41 @@ +/* + * Copyright 2013, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef _PACKAGE__GLOBAL_SETTINGS_FILE_INFO_H_ +#define _PACKAGE__GLOBAL_SETTINGS_FILE_INFO_H_ + + +#include +#include + + +namespace BPackageKit { + + +class BGlobalSettingsFileInfo { +public: + BGlobalSettingsFileInfo(); + BGlobalSettingsFileInfo(const BString& path, + BSettingsFileUpdateType updateType); + ~BGlobalSettingsFileInfo(); + + status_t InitCheck() const; + + const BString& Path() const; + bool IsIncluded() const; + BSettingsFileUpdateType UpdateType() const; + + void SetTo(const BString& path, + BSettingsFileUpdateType updateType); + +private: + BString fPath; + BSettingsFileUpdateType fUpdateType; +}; + + +} // namespace BPackageKit + + +#endif // _PACKAGE__GLOBAL_SETTINGS_FILE_INFO_H_ diff --git a/headers/os/package/PackageInfo.h b/headers/os/package/PackageInfo.h index c51bb8f182..ade89a03cc 100644 --- a/headers/os/package/PackageInfo.h +++ b/headers/os/package/PackageInfo.h @@ -11,12 +11,14 @@ #include #include +#include #include #include #include #include #include #include +#include class BEntry; @@ -79,6 +81,11 @@ public: const BStringList& URLList() const; const BStringList& SourceURLList() const; + const BObjectList& + GlobalSettingsFileInfos() const; + const BObjectList& + UserSettingsFileInfos() const; + const BObjectList& ProvidesList() const; const BObjectList& RequiresList() const; @@ -120,6 +127,14 @@ public: void ClearSourceURLList(); status_t AddSourceURL(const BString& url); + void ClearGlobalSettingsFileInfos(); + status_t AddGlobalSettingsFileInfo( + const BGlobalSettingsFileInfo& info); + + void ClearUserSettingsFileInfos(); + status_t AddUserSettingsFileInfo( + const BUserSettingsFileInfo& info); + void ClearProvidesList(); status_t AddProvides(const BPackageResolvable& provides); @@ -163,6 +178,7 @@ public: public: static const char* const kElementNames[]; static const char* const kArchitectureNames[]; + static const char* const kSettingsFileUpdateTypes[]; private: class Parser; @@ -175,6 +191,11 @@ private: typedef BObjectList ResolvableExpressionList; + typedef BObjectList + GlobalSettingsFileInfoList; + typedef BObjectList + UserSettingsFileInfoList; + private: status_t _ReadFromPackageFile( const PackageFileLocation& fileLocation); @@ -189,6 +210,15 @@ private: const char* field, const ResolvableExpressionList& expressions); + static status_t _AddGlobalSettingsFileInfos(BMessage* archive, + const char* field, + const GlobalSettingsFileInfoList& + infos); + static status_t _AddUserSettingsFileInfos(BMessage* archive, + const char* field, + const UserSettingsFileInfoList& + infos); + static status_t _ExtractVersion(BMessage* archive, const char* field, int32 index, BPackageVersion& _version); @@ -200,6 +230,12 @@ private: static status_t _ExtractResolvableExpressions(BMessage* archive, const char* field, ResolvableExpressionList& _expressions); + static status_t _ExtractGlobalSettingsFileInfos( + BMessage* archive, const char* field, + GlobalSettingsFileInfoList& _infos); + static status_t _ExtractUserSettingsFileInfos( + BMessage* archive, const char* field, + UserSettingsFileInfoList& _infos); private: BString fName; @@ -220,6 +256,9 @@ private: BStringList fURLList; BStringList fSourceURLList; + BObjectList fGlobalSettingsFileInfos; + BObjectList fUserSettingsFileInfos; + ResolvableList fProvidesList; ResolvableExpressionList fRequiresList; diff --git a/headers/os/package/PackageInfoAttributes.h b/headers/os/package/PackageInfoAttributes.h index 83fbd4d1d1..89b6814c58 100644 --- a/headers/os/package/PackageInfoAttributes.h +++ b/headers/os/package/PackageInfoAttributes.h @@ -1,5 +1,5 @@ /* - * Copyright 2011, Haiku, Inc. + * Copyright 2011-2013, Haiku, Inc. * Distributed under the terms of the MIT License. */ #ifndef _PACKAGE__PACKAGE_INFO_ATTRIBUTES_H_ @@ -41,6 +41,10 @@ enum BPackageInfoAttributeID { B_PACKAGE_INFO_INSTALL_PATH, // package install path; only for package // building B_PACKAGE_INFO_BASE_PACKAGE, // name of the base package for this package + B_PACKAGE_INFO_GLOBAL_SETTINGS_FILES, + // list of global settings file infos + B_PACKAGE_INFO_USER_SETTINGS_FILES, + // list of user settings file infos // B_PACKAGE_INFO_ENUM_COUNT, }; diff --git a/headers/os/package/SettingsFileUpdateType.h b/headers/os/package/SettingsFileUpdateType.h new file mode 100644 index 0000000000..2ddb6f2bbb --- /dev/null +++ b/headers/os/package/SettingsFileUpdateType.h @@ -0,0 +1,35 @@ +/* + * Copyright 2013, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef _PACKAGE__SETTINGS_FILE_UPDATE_TYPE_H_ +#define _PACKAGE__SETTINGS_FILE_UPDATE_TYPE_H_ + + +#include + + +namespace BPackageKit { + + +// global settings file update types -- specifies behavior in case the previous +// version of a settings file provided by a package has been changed by the +// user. +enum BSettingsFileUpdateType { + B_SETTINGS_FILE_UPDATE_TYPE_KEEP_OLD = 0, + // the old settings file can be kept + B_SETTINGS_FILE_UPDATE_TYPE_MANUAL = 1, + // the old settings file needs to be updated manually + B_SETTINGS_FILE_UPDATE_TYPE_AUTO_MERGE = 2, + // try a three-way merge + + B_SETTINGS_FILE_UPDATE_TYPE_ENUM_COUNT, + + B_SETTINGS_FILE_UPDATE_TYPE_DEFAULT = B_SETTINGS_FILE_UPDATE_TYPE_KEEP_OLD +}; + + +} // namespace BPackageKit + + +#endif // _PACKAGE__SETTINGS_FILE_UPDATE_TYPE_H_ diff --git a/headers/os/package/UserSettingsFileInfo.h b/headers/os/package/UserSettingsFileInfo.h new file mode 100644 index 0000000000..c4639f7972 --- /dev/null +++ b/headers/os/package/UserSettingsFileInfo.h @@ -0,0 +1,39 @@ +/* + * Copyright 2013, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef _PACKAGE__USER_SETTINGS_FILE_INFO_H_ +#define _PACKAGE__USER_SETTINGS_FILE_INFO_H_ + + +#include + + +namespace BPackageKit { + + +class BUserSettingsFileInfo { +public: + BUserSettingsFileInfo(); + BUserSettingsFileInfo(const BString& path, + const BString& templatePath = BString()); + ~BUserSettingsFileInfo(); + + status_t InitCheck() const; + + const BString& Path() const; + const BString& TemplatePath() const; + + void SetTo(const BString& path, + const BString& templatePath = BString()); + +private: + BString fPath; + BString fTemplatePath; +}; + + +} // namespace BPackageKit + + +#endif // _PACKAGE__USER_SETTINGS_FILE_INFO_H_ diff --git a/headers/os/package/hpkg/HPKGDefs.h b/headers/os/package/hpkg/HPKGDefs.h index f1e2ed58fa..f2d6e9e1e8 100644 --- a/headers/os/package/hpkg/HPKGDefs.h +++ b/headers/os/package/hpkg/HPKGDefs.h @@ -86,48 +86,52 @@ extern const char* const B_HPKG_PACKAGE_INFO_FILE_NAME; // package attribute IDs enum BHPKGAttributeID { - B_HPKG_ATTRIBUTE_ID_DIRECTORY_ENTRY = 0, - B_HPKG_ATTRIBUTE_ID_FILE_TYPE = 1, - B_HPKG_ATTRIBUTE_ID_FILE_PERMISSIONS = 2, - B_HPKG_ATTRIBUTE_ID_FILE_USER = 3, - B_HPKG_ATTRIBUTE_ID_FILE_GROUP = 4, - B_HPKG_ATTRIBUTE_ID_FILE_ATIME = 5, - B_HPKG_ATTRIBUTE_ID_FILE_MTIME = 6, - B_HPKG_ATTRIBUTE_ID_FILE_CRTIME = 7, - B_HPKG_ATTRIBUTE_ID_FILE_ATIME_NANOS = 8, - B_HPKG_ATTRIBUTE_ID_FILE_MTIME_NANOS = 9, - B_HPKG_ATTRIBUTE_ID_FILE_CRTIM_NANOS = 10, - B_HPKG_ATTRIBUTE_ID_FILE_ATTRIBUTE = 11, - B_HPKG_ATTRIBUTE_ID_FILE_ATTRIBUTE_TYPE = 12, - B_HPKG_ATTRIBUTE_ID_DATA = 13, - B_HPKG_ATTRIBUTE_ID_SYMLINK_PATH = 14, - B_HPKG_ATTRIBUTE_ID_PACKAGE_NAME = 15, - B_HPKG_ATTRIBUTE_ID_PACKAGE_SUMMARY = 16, - B_HPKG_ATTRIBUTE_ID_PACKAGE_DESCRIPTION = 17, - B_HPKG_ATTRIBUTE_ID_PACKAGE_VENDOR = 18, - B_HPKG_ATTRIBUTE_ID_PACKAGE_PACKAGER = 19, - B_HPKG_ATTRIBUTE_ID_PACKAGE_FLAGS = 20, - B_HPKG_ATTRIBUTE_ID_PACKAGE_ARCHITECTURE = 21, - B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR = 22, - B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MINOR = 23, - B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MICRO = 24, - B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_REVISION = 25, - B_HPKG_ATTRIBUTE_ID_PACKAGE_COPYRIGHT = 26, - B_HPKG_ATTRIBUTE_ID_PACKAGE_LICENSE = 27, - B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES = 28, - B_HPKG_ATTRIBUTE_ID_PACKAGE_REQUIRES = 29, - B_HPKG_ATTRIBUTE_ID_PACKAGE_SUPPLEMENTS = 30, - B_HPKG_ATTRIBUTE_ID_PACKAGE_CONFLICTS = 31, - B_HPKG_ATTRIBUTE_ID_PACKAGE_FRESHENS = 32, - B_HPKG_ATTRIBUTE_ID_PACKAGE_REPLACES = 33, - B_HPKG_ATTRIBUTE_ID_PACKAGE_RESOLVABLE_OPERATOR = 34, - B_HPKG_ATTRIBUTE_ID_PACKAGE_CHECKSUM = 35, - B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_PRE_RELEASE = 36, - B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES_COMPATIBLE = 37, - B_HPKG_ATTRIBUTE_ID_PACKAGE_URL = 38, - B_HPKG_ATTRIBUTE_ID_PACKAGE_SOURCE_URL = 39, - B_HPKG_ATTRIBUTE_ID_PACKAGE_INSTALL_PATH = 40, - B_HPKG_ATTRIBUTE_ID_PACKAGE_BASE_PACKAGE = 41, + B_HPKG_ATTRIBUTE_ID_DIRECTORY_ENTRY = 0, + B_HPKG_ATTRIBUTE_ID_FILE_TYPE = 1, + B_HPKG_ATTRIBUTE_ID_FILE_PERMISSIONS = 2, + B_HPKG_ATTRIBUTE_ID_FILE_USER = 3, + B_HPKG_ATTRIBUTE_ID_FILE_GROUP = 4, + B_HPKG_ATTRIBUTE_ID_FILE_ATIME = 5, + B_HPKG_ATTRIBUTE_ID_FILE_MTIME = 6, + B_HPKG_ATTRIBUTE_ID_FILE_CRTIME = 7, + B_HPKG_ATTRIBUTE_ID_FILE_ATIME_NANOS = 8, + B_HPKG_ATTRIBUTE_ID_FILE_MTIME_NANOS = 9, + B_HPKG_ATTRIBUTE_ID_FILE_CRTIM_NANOS = 10, + B_HPKG_ATTRIBUTE_ID_FILE_ATTRIBUTE = 11, + B_HPKG_ATTRIBUTE_ID_FILE_ATTRIBUTE_TYPE = 12, + B_HPKG_ATTRIBUTE_ID_DATA = 13, + B_HPKG_ATTRIBUTE_ID_SYMLINK_PATH = 14, + B_HPKG_ATTRIBUTE_ID_PACKAGE_NAME = 15, + B_HPKG_ATTRIBUTE_ID_PACKAGE_SUMMARY = 16, + B_HPKG_ATTRIBUTE_ID_PACKAGE_DESCRIPTION = 17, + B_HPKG_ATTRIBUTE_ID_PACKAGE_VENDOR = 18, + B_HPKG_ATTRIBUTE_ID_PACKAGE_PACKAGER = 19, + B_HPKG_ATTRIBUTE_ID_PACKAGE_FLAGS = 20, + B_HPKG_ATTRIBUTE_ID_PACKAGE_ARCHITECTURE = 21, + B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MAJOR = 22, + B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MINOR = 23, + B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_MICRO = 24, + B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_REVISION = 25, + B_HPKG_ATTRIBUTE_ID_PACKAGE_COPYRIGHT = 26, + B_HPKG_ATTRIBUTE_ID_PACKAGE_LICENSE = 27, + B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES = 28, + B_HPKG_ATTRIBUTE_ID_PACKAGE_REQUIRES = 29, + B_HPKG_ATTRIBUTE_ID_PACKAGE_SUPPLEMENTS = 30, + B_HPKG_ATTRIBUTE_ID_PACKAGE_CONFLICTS = 31, + B_HPKG_ATTRIBUTE_ID_PACKAGE_FRESHENS = 32, + B_HPKG_ATTRIBUTE_ID_PACKAGE_REPLACES = 33, + B_HPKG_ATTRIBUTE_ID_PACKAGE_RESOLVABLE_OPERATOR = 34, + B_HPKG_ATTRIBUTE_ID_PACKAGE_CHECKSUM = 35, + B_HPKG_ATTRIBUTE_ID_PACKAGE_VERSION_PRE_RELEASE = 36, + B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES_COMPATIBLE = 37, + B_HPKG_ATTRIBUTE_ID_PACKAGE_URL = 38, + B_HPKG_ATTRIBUTE_ID_PACKAGE_SOURCE_URL = 39, + B_HPKG_ATTRIBUTE_ID_PACKAGE_INSTALL_PATH = 40, + B_HPKG_ATTRIBUTE_ID_PACKAGE_BASE_PACKAGE = 41, + B_HPKG_ATTRIBUTE_ID_PACKAGE_GLOBAL_SETTINGS_FILE = 42, + B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SETTINGS_FILE = 43, + B_HPKG_ATTRIBUTE_ID_PACKAGE_SETTINGS_FILE_UPDATE_TYPE = 44, + B_HPKG_ATTRIBUTE_ID_PACKAGE_SETTINGS_FILE_TEMPLATE = 45, // B_HPKG_ATTRIBUTE_ID_ENUM_COUNT, }; diff --git a/headers/os/package/hpkg/PackageInfoAttributeValue.h b/headers/os/package/hpkg/PackageInfoAttributeValue.h index 7372612063..700f5d533c 100644 --- a/headers/os/package/hpkg/PackageInfoAttributeValue.h +++ b/headers/os/package/hpkg/PackageInfoAttributeValue.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace BPackageKit { @@ -46,6 +47,18 @@ struct BPackageResolvableExpressionData { }; +struct BGlobalSettingsFileInfoData { + const char* path; + BSettingsFileUpdateType updateType; +}; + + +struct BUserSettingsFileInfoData { + const char* path; + const char* templatePath; +}; + + struct BPackageInfoAttributeValue { union { uint64 unsignedInt; @@ -53,6 +66,8 @@ struct BPackageInfoAttributeValue { BPackageVersionData version; BPackageResolvableData resolvable; BPackageResolvableExpressionData resolvableExpression; + BGlobalSettingsFileInfoData globalSettingsFileInfo; + BUserSettingsFileInfoData userSettingsFileInfo; }; BPackageInfoAttributeID attributeID; diff --git a/headers/private/package/hpkg/ReaderImplBase.h b/headers/private/package/hpkg/ReaderImplBase.h index de25a3fa59..7072daddc8 100644 --- a/headers/private/package/hpkg/ReaderImplBase.h +++ b/headers/private/package/hpkg/ReaderImplBase.h @@ -1,5 +1,5 @@ /* - * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2011, Oliver Tappe * Distributed under the terms of the MIT License. */ @@ -97,9 +97,12 @@ protected: class AttributeHandlerContext; class AttributeHandler; class IgnoreAttributeHandler; + class PackageInfoAttributeHandlerBase; class PackageVersionAttributeHandler; class PackageResolvableAttributeHandler; class PackageResolvableExpressionAttributeHandler; + class GlobalSettingsFileInfoAttributeHandler; + class UserSettingsFileInfoAttributeHandler; class PackageAttributeHandler; class LowLevelAttributeHandler; @@ -247,7 +250,22 @@ class ReaderImplBase::IgnoreAttributeHandler : public AttributeHandler { }; -class ReaderImplBase::PackageVersionAttributeHandler : public AttributeHandler { +class ReaderImplBase::PackageInfoAttributeHandlerBase + : public AttributeHandler { +public: + PackageInfoAttributeHandlerBase( + BPackageInfoAttributeValue& + packageInfoValue); + + virtual status_t Delete(AttributeHandlerContext* context); + +protected: + BPackageInfoAttributeValue& fPackageInfoValue; +}; + + +class ReaderImplBase::PackageVersionAttributeHandler + : public PackageInfoAttributeHandlerBase { public: PackageVersionAttributeHandler( BPackageInfoAttributeValue& @@ -263,14 +281,13 @@ public: virtual status_t Delete(AttributeHandlerContext* context); private: - BPackageInfoAttributeValue& fPackageInfoValue; BPackageVersionData& fPackageVersionData; bool fNotify; }; class ReaderImplBase::PackageResolvableAttributeHandler - : public AttributeHandler { + : public PackageInfoAttributeHandlerBase { public: PackageResolvableAttributeHandler( BPackageInfoAttributeValue& @@ -280,16 +297,11 @@ public: AttributeHandlerContext* context, uint8 id, const AttributeValue& value, AttributeHandler** _handler); - - virtual status_t Delete(AttributeHandlerContext* context); - -private: - BPackageInfoAttributeValue& fPackageInfoValue; }; class ReaderImplBase::PackageResolvableExpressionAttributeHandler - : public AttributeHandler { + : public PackageInfoAttributeHandlerBase { public: PackageResolvableExpressionAttributeHandler( BPackageInfoAttributeValue& @@ -299,11 +311,34 @@ public: AttributeHandlerContext* context, uint8 id, const AttributeValue& value, AttributeHandler** _handler); +}; - virtual status_t Delete(AttributeHandlerContext* context); -private: - BPackageInfoAttributeValue& fPackageInfoValue; +class ReaderImplBase::GlobalSettingsFileInfoAttributeHandler + : public PackageInfoAttributeHandlerBase { +public: + GlobalSettingsFileInfoAttributeHandler( + BPackageInfoAttributeValue& + packageInfoValue); + + virtual status_t HandleAttribute( + AttributeHandlerContext* context, uint8 id, + const AttributeValue& value, + AttributeHandler** _handler); +}; + + +class ReaderImplBase::UserSettingsFileInfoAttributeHandler + : public PackageInfoAttributeHandlerBase { +public: + UserSettingsFileInfoAttributeHandler( + BPackageInfoAttributeValue& + packageInfoValue); + + virtual status_t HandleAttribute( + AttributeHandlerContext* context, uint8 id, + const AttributeValue& value, + AttributeHandler** _handler); }; diff --git a/src/bin/package/command_list.cpp b/src/bin/package/command_list.cpp index caebcbf878..219f03c3c3 100644 --- a/src/bin/package/command_list.cpp +++ b/src/bin/package/command_list.cpp @@ -288,6 +288,28 @@ struct PackageContentListHandler : VersionPolicy::PackageContentHandler { printf("\treplaces: %s\n", value.string); break; + case B_PACKAGE_INFO_GLOBAL_SETTINGS_FILES: + printf("\tglobal settings file: %s", + value.globalSettingsFileInfo.path); + if (value.globalSettingsFileInfo.updateType + < B_SETTINGS_FILE_UPDATE_TYPE_ENUM_COUNT) { + printf(" %s\n", + BPackageInfo::kSettingsFileUpdateTypes[ + value.globalSettingsFileInfo.updateType]); + } else + printf("\n"); + break; + + case B_PACKAGE_INFO_USER_SETTINGS_FILES: + printf("\tuser settings file: %s", + value.userSettingsFileInfo.path); + if (value.userSettingsFileInfo.templatePath != NULL) { + printf(" template %s\n", + value.userSettingsFileInfo.templatePath); + } else + printf("\n"); + break; + case B_PACKAGE_INFO_INSTALL_PATH: printf("\tinstall path: %s\n", value.string); break; diff --git a/src/build/libpackage/Jamfile b/src/build/libpackage/Jamfile index 0b911b3988..1851ee6222 100644 --- a/src/build/libpackage/Jamfile +++ b/src/build/libpackage/Jamfile @@ -31,6 +31,7 @@ HPKG_SOURCES = DataWriters.cpp ErrorOutput.cpp FDDataReader.cpp + GlobalSettingsFileInfo.cpp HPKGDefs.cpp PackageContentHandler.cpp PackageData.cpp @@ -50,6 +51,7 @@ HPKG_SOURCES = RepositoryWriter.cpp RepositoryWriterImpl.cpp Strings.cpp + UserSettingsFileInfo.cpp WriterImplBase.cpp # V1 support diff --git a/src/kits/package/GlobalSettingsFileInfo.cpp b/src/kits/package/GlobalSettingsFileInfo.cpp new file mode 100644 index 0000000000..36229ae5a4 --- /dev/null +++ b/src/kits/package/GlobalSettingsFileInfo.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include + + +namespace BPackageKit { + + +BGlobalSettingsFileInfo::BGlobalSettingsFileInfo() + : + fPath(), + fUpdateType(B_SETTINGS_FILE_UPDATE_TYPE_ENUM_COUNT) +{ +} + + +BGlobalSettingsFileInfo::BGlobalSettingsFileInfo(const BString& path, + BSettingsFileUpdateType updateType) + : + fPath(path), + fUpdateType(updateType) +{ +} + + +BGlobalSettingsFileInfo::~BGlobalSettingsFileInfo() +{ +} + + +status_t +BGlobalSettingsFileInfo::InitCheck() const +{ + if (fPath.IsEmpty()) + return B_NO_INIT; + return B_OK; +} + + +const BString& +BGlobalSettingsFileInfo::Path() const +{ + return fPath; +} + + +bool +BGlobalSettingsFileInfo::IsIncluded() const +{ + return fUpdateType != B_SETTINGS_FILE_UPDATE_TYPE_ENUM_COUNT; +} + + +BSettingsFileUpdateType +BGlobalSettingsFileInfo::UpdateType() const +{ + return fUpdateType; +} + + +void +BGlobalSettingsFileInfo::SetTo(const BString& path, + BSettingsFileUpdateType updateType) +{ + fPath = path; + fUpdateType = updateType; +} + + +} // namespace BPackageKit diff --git a/src/kits/package/Jamfile b/src/kits/package/Jamfile index 8ea102622a..ee058a1336 100644 --- a/src/kits/package/Jamfile +++ b/src/kits/package/Jamfile @@ -21,6 +21,7 @@ HPKG_SOURCES = DataWriters.cpp ErrorOutput.cpp FDDataReader.cpp + GlobalSettingsFileInfo.cpp HPKGDefs.cpp PackageContentHandler.cpp PackageData.cpp @@ -41,6 +42,7 @@ HPKG_SOURCES = RepositoryWriter.cpp RepositoryWriterImpl.cpp Strings.cpp + UserSettingsFileInfo.cpp WriterImplBase.cpp # V1 support diff --git a/src/kits/package/PackageInfo.cpp b/src/kits/package/PackageInfo.cpp index b6fa351944..34e14eeb2e 100644 --- a/src/kits/package/PackageInfo.cpp +++ b/src/kits/package/PackageInfo.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -108,6 +109,10 @@ private: BObjectList* value, BString* _basePackage = NULL); + void _ParseGlobalSettingsFileInfos( + GlobalSettingsFileInfoList* infos); + void _ParseUserSettingsFileInfos( + UserSettingsFileInfoList* infos); void _Parse(BPackageInfo* packageInfo); @@ -756,6 +761,119 @@ BPackageInfo::Parser::_ParseResolvableExprList( } +void +BPackageInfo::Parser::_ParseGlobalSettingsFileInfos( + GlobalSettingsFileInfoList* infos) +{ + struct GlobalSettingsFileInfoParser : public ListElementParser { + Parser& parser; + GlobalSettingsFileInfoList* infos; + + GlobalSettingsFileInfoParser(Parser& parser, + GlobalSettingsFileInfoList* infos) + : + parser(parser), + infos(infos) + { + } + + virtual void operator()(const Token& token) + { + if (token.type != TOKEN_WORD && token.type != TOKEN_QUOTED_STRING) { + throw ParseError("expected string (a settings file path)", + token.pos); + } + + BSettingsFileUpdateType updateType + = B_SETTINGS_FILE_UPDATE_TYPE_ENUM_COUNT; + + Token nextToken = parser._NextToken(); + if (nextToken.type == TOKEN_WORD) { + const char* const* end = kSettingsFileUpdateTypes + + B_SETTINGS_FILE_UPDATE_TYPE_ENUM_COUNT; + const char* const* found = std::find(kSettingsFileUpdateTypes, + end, nextToken.text); + if (found == end) { + throw ParseError(BString("expected an update type"), + nextToken.pos); + } + updateType = (BSettingsFileUpdateType)( + found - kSettingsFileUpdateTypes); + } else if (nextToken.type == TOKEN_ITEM_SEPARATOR + || nextToken.type == TOKEN_CLOSE_BRACE) { + parser._RewindTo(nextToken); + } else { + throw ParseError( + "expected 'included', semicolon, new line or '}'", + nextToken.pos); + } + + if (!infos->AddItem(new BGlobalSettingsFileInfo(token.text, + updateType))) { + throw std::bad_alloc(); + } + } + } resolvableExpressionParser(*this, infos); + + _ParseList(resolvableExpressionParser, false); +} + + +void +BPackageInfo::Parser::_ParseUserSettingsFileInfos( + UserSettingsFileInfoList* infos) +{ + struct UserSettingsFileInfoParser : public ListElementParser { + Parser& parser; + UserSettingsFileInfoList* infos; + + UserSettingsFileInfoParser(Parser& parser, + UserSettingsFileInfoList* infos) + : + parser(parser), + infos(infos) + { + } + + virtual void operator()(const Token& token) + { + if (token.type != TOKEN_WORD && token.type != TOKEN_QUOTED_STRING) { + throw ParseError("expected string (a settings file path)", + token.pos); + } + + BString templatePath; + + Token nextToken = parser._NextToken(); + if (nextToken.type == TOKEN_WORD && nextToken.text == "template") { + nextToken = parser._NextToken(); + if (nextToken.type != TOKEN_WORD + && nextToken.type != TOKEN_QUOTED_STRING) { + throw ParseError( + "expected string (a settings template file path)", + nextToken.pos); + } + templatePath = nextToken.text; + } else if (nextToken.type == TOKEN_ITEM_SEPARATOR + || nextToken.type == TOKEN_CLOSE_BRACE) { + parser._RewindTo(nextToken); + } else { + throw ParseError( + "expected 'template', semicolon, new line or '}'", + nextToken.pos); + } + + if (!infos->AddItem(new BUserSettingsFileInfo(token.text, + templatePath))) { + throw std::bad_alloc(); + } + } + } resolvableExpressionParser(*this, infos); + + _ParseList(resolvableExpressionParser, false); +} + + void BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) { @@ -857,6 +975,16 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo) _ParseStringList(&packageInfo->fSourceURLList); break; + case B_PACKAGE_INFO_GLOBAL_SETTINGS_FILES: + _ParseGlobalSettingsFileInfos( + &packageInfo->fGlobalSettingsFileInfos); + break; + + case B_PACKAGE_INFO_USER_SETTINGS_FILES: + _ParseUserSettingsFileInfos( + &packageInfo->fUserSettingsFileInfos); + break; + case B_PACKAGE_INFO_PROVIDES: _ParseResolvableList(&packageInfo->fProvidesList); break; @@ -987,6 +1115,9 @@ const char* const BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = { "source-urls", "checksum", // not being parsed, computed externally NULL, // install-path -- not settable via .PackageInfo + "base-package", + "global-settings-files", + "user-settings-files", }; @@ -999,6 +1130,14 @@ BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = { }; +const char* const BPackageInfo::kSettingsFileUpdateTypes[ + B_SETTINGS_FILE_UPDATE_TYPE_ENUM_COUNT] = { + "keep-old", + "manual", + "auto-merge", +}; + + // #pragma mark - StringBuilder @@ -1119,22 +1258,14 @@ private: int32 count = value.CountItems(); if (count == 1) { - _Write(value.ItemAt(0)->ToString()); - if (!fBasePackage.IsEmpty() - && value.ItemAt(0)->Name() == fBasePackage) { - _Write(" base"); - } + _WriteListElement(value.ItemAt(0)); } else { _Write("{\n", 2); int32 count = value.CountItems(); for (int32 i = 0; i < count; i++) { _Write('\t'); - _Write(value.ItemAt(i)->ToString()); - if (!fBasePackage.IsEmpty() - && value.ItemAt(i)->Name() == fBasePackage) { - _Write(" base"); - } + _WriteListElement(value.ItemAt(i)); _Write('\n'); } @@ -1142,6 +1273,34 @@ private: } } + template + void _WriteListElement(const Value* value) + { + _Write(value->ToString()); + if (!fBasePackage.IsEmpty() + && value->Name() == fBasePackage) { + _Write(" base"); + } + } + + void _WriteListElement(const BGlobalSettingsFileInfo* value) + { + _WriteMaybeQuoted(value->Path()); + if (value->IsIncluded()) { + _Write(' '); + _Write(kSettingsFileUpdateTypes[value->UpdateType()]); + } + } + + void _WriteListElement(const BUserSettingsFileInfo* value) + { + _WriteMaybeQuoted(value->Path()); + if (!value->TemplatePath().IsEmpty()) { + _Write(" template "); + _WriteMaybeQuoted(value->TemplatePath()); + } + } + static inline bool _IsValueEmpty(const char* value) { return value[0] == '\0'; @@ -1342,6 +1501,8 @@ BPackageInfo::BPackageInfo() fLicenseList(5), fURLList(5), fSourceURLList(5), + fGlobalSettingsFileInfos(5, true), + fUserSettingsFileInfos(5, true), fProvidesList(20, true), fRequiresList(20, true), fSupplementsList(20, true), @@ -1361,6 +1522,8 @@ BPackageInfo::BPackageInfo(BMessage* archive, status_t* _error) fLicenseList(5), fURLList(5), fSourceURLList(5), + fGlobalSettingsFileInfos(5, true), + fUserSettingsFileInfos(5, true), fProvidesList(20, true), fRequiresList(20, true), fSupplementsList(20, true), @@ -1386,6 +1549,10 @@ BPackageInfo::BPackageInfo(BMessage* archive, status_t* _error) && (error = _ExtractStringList(archive, "urls", fURLList)) == B_OK && (error = _ExtractStringList(archive, "source-urls", fSourceURLList)) == B_OK + && (error = _ExtractGlobalSettingsFileInfos(archive, + "global-settings-files", fGlobalSettingsFileInfos)) == B_OK + && (error = _ExtractUserSettingsFileInfos(archive, "user-settings-files", + fUserSettingsFileInfos)) == B_OK && (error = _ExtractResolvables(archive, "provides", fProvidesList)) == B_OK && (error = _ExtractResolvableExpressions(archive, "requires", @@ -1605,6 +1772,20 @@ BPackageInfo::SourceURLList() const } +const BObjectList& +BPackageInfo::GlobalSettingsFileInfos() const +{ + return fGlobalSettingsFileInfos; +} + + +const BObjectList& +BPackageInfo::UserSettingsFileInfos() const +{ + return fUserSettingsFileInfos; +} + + const BObjectList& BPackageInfo::ProvidesList() const { @@ -1785,6 +1966,48 @@ BPackageInfo::ClearSourceURLList() } +void +BPackageInfo::ClearGlobalSettingsFileInfos() +{ + fGlobalSettingsFileInfos.MakeEmpty(); +} + + +status_t +BPackageInfo::AddGlobalSettingsFileInfo(const BGlobalSettingsFileInfo& info) +{ + BGlobalSettingsFileInfo* newInfo + = new (std::nothrow) BGlobalSettingsFileInfo(info); + if (newInfo == NULL || !fGlobalSettingsFileInfos.AddItem(newInfo)) { + delete newInfo; + return B_NO_MEMORY; + } + + return B_OK; +} + + +void +BPackageInfo::ClearUserSettingsFileInfos() +{ + fUserSettingsFileInfos.MakeEmpty(); +} + + +status_t +BPackageInfo::AddUserSettingsFileInfo(const BUserSettingsFileInfo& info) +{ + BUserSettingsFileInfo* newInfo + = new (std::nothrow) BUserSettingsFileInfo(info); + if (newInfo == NULL || !fUserSettingsFileInfos.AddItem(newInfo)) { + delete newInfo; + return B_NO_MEMORY; + } + + return B_OK; +} + + status_t BPackageInfo::AddSourceURL(const BString& url) { @@ -1919,6 +2142,8 @@ BPackageInfo::Clear() fLicenseList.MakeEmpty(); fURLList.MakeEmpty(); fSourceURLList.MakeEmpty(); + fGlobalSettingsFileInfos.MakeEmpty(); + fUserSettingsFileInfos.MakeEmpty(); fRequiresList.MakeEmpty(); fProvidesList.MakeEmpty(); fSupplementsList.MakeEmpty(); @@ -1950,6 +2175,10 @@ BPackageInfo::Archive(BMessage* archive, bool deep) const || (error = archive->AddStrings("urls", fURLList)) != B_OK || (error = archive->AddStrings("source-urls", fSourceURLList)) != B_OK + || (error = _AddGlobalSettingsFileInfos(archive, + "global-settings-files", fGlobalSettingsFileInfos)) != B_OK + || (error = _AddUserSettingsFileInfos(archive, + "user-settings-files", fUserSettingsFileInfos)) != B_OK || (error = _AddResolvables(archive, "provides", fProvidesList)) != B_OK || (error = _AddResolvableExpressions(archive, "requires", fRequiresList)) != B_OK @@ -1993,6 +2222,8 @@ BPackageInfo::GetConfigString(BString& _string) const .Write("licenses", fLicenseList) .Write("urls", fURLList) .Write("source-urls", fSourceURLList) + .Write("global-settings-files", fGlobalSettingsFileInfos) + .Write("user-settings-files", fUserSettingsFileInfos) .Write("provides", fProvidesList) .BeginRequires(fBasePackage) .Write("requires", fRequiresList) @@ -2187,6 +2418,60 @@ BPackageInfo::_AddResolvableExpressions(BMessage* archive, const char* field, } +/*static*/ status_t +BPackageInfo::_AddGlobalSettingsFileInfos(BMessage* archive, const char* field, + const GlobalSettingsFileInfoList& infos) +{ + // construct the field names we need + FieldName pathField(field, ":path"); + FieldName updateTypeField(field, ":version"); + + if (!pathField.IsValid() || !updateTypeField.IsValid()) + return B_BAD_VALUE; + + // add fields + int32 count = infos.CountItems(); + for (int32 i = 0; i < count; i++) { + const BGlobalSettingsFileInfo* info = infos.ItemAt(i); + status_t error; + if ((error = archive->AddString(pathField, info->Path())) != B_OK + || (error = archive->AddInt32(updateTypeField, info->UpdateType())) + != B_OK) { + return error; + } + } + + return B_OK; +} + + +/*static*/ status_t +BPackageInfo::_AddUserSettingsFileInfos(BMessage* archive, const char* field, + const UserSettingsFileInfoList& infos) +{ + // construct the field names we need + FieldName pathField(field, ":path"); + FieldName templatePathField(field, ":templatePath"); + + if (!pathField.IsValid() || !templatePathField.IsValid()) + return B_BAD_VALUE; + + // add fields + int32 count = infos.CountItems(); + for (int32 i = 0; i < count; i++) { + const BUserSettingsFileInfo* info = infos.ItemAt(i); + status_t error; + if ((error = archive->AddString(pathField, info->Path())) != B_OK + || (error = archive->AddString(templatePathField, + info->TemplatePath())) != B_OK) { + return error; + } + } + + return B_OK; +} + + /*static*/ status_t BPackageInfo::_ExtractVersion(BMessage* archive, const char* field, int32 index, BPackageVersion& _version) @@ -2362,4 +2647,95 @@ BPackageInfo::_ExtractResolvableExpressions(BMessage* archive, } +/*static*/ status_t +BPackageInfo::_ExtractGlobalSettingsFileInfos(BMessage* archive, + const char* field, GlobalSettingsFileInfoList& _infos) +{ + // construct the field names we need + FieldName pathField(field, ":path"); + FieldName updateTypeField(field, ":version"); + + if (!pathField.IsValid() || !updateTypeField.IsValid()) + return B_BAD_VALUE; + + // get the number of items + type_code type; + int32 count; + if (archive->GetInfo(pathField, &type, &count) != B_OK) { + // the field is missing + return B_OK; + } + + // extract fields + for (int32 i = 0; i < count; i++) { + BString path; + status_t error = archive->FindString(pathField, i, &path); + if (error != B_OK) + return error; + + int32 updateType; + error = archive->FindInt32(updateTypeField, i, &updateType); + if (error != B_OK) + return error; + if (updateType < 0 + || updateType > B_SETTINGS_FILE_UPDATE_TYPE_ENUM_COUNT) { + return B_BAD_DATA; + } + + BGlobalSettingsFileInfo* info + = new(std::nothrow) BGlobalSettingsFileInfo(path, + (BSettingsFileUpdateType)updateType); + if (info == NULL || !_infos.AddItem(info)) { + delete info; + return B_NO_MEMORY; + } + } + + return B_OK; +} + + +/*static*/ status_t +BPackageInfo::_ExtractUserSettingsFileInfos(BMessage* archive, + const char* field, UserSettingsFileInfoList& _infos) +{ + // construct the field names we need + FieldName pathField(field, ":path"); + FieldName templatePathField(field, ":templatePath"); + + if (!pathField.IsValid() || !templatePathField.IsValid()) + return B_BAD_VALUE; + + // get the number of items + type_code type; + int32 count; + if (archive->GetInfo(pathField, &type, &count) != B_OK) { + // the field is missing + return B_OK; + } + + // extract fields + for (int32 i = 0; i < count; i++) { + BString path; + status_t error = archive->FindString(pathField, i, &path); + if (error != B_OK) + return error; + + BString templatePath; + error = archive->FindString(templatePathField, i, &templatePath); + if (error != B_OK) + return error; + + BUserSettingsFileInfo* info + = new(std::nothrow) BUserSettingsFileInfo(path, templatePath); + if (info == NULL || !_infos.AddItem(info)) { + delete info; + return B_NO_MEMORY; + } + } + + return B_OK; +} + + } // namespace BPackageKit diff --git a/src/kits/package/UserSettingsFileInfo.cpp b/src/kits/package/UserSettingsFileInfo.cpp new file mode 100644 index 0000000000..b23279875d --- /dev/null +++ b/src/kits/package/UserSettingsFileInfo.cpp @@ -0,0 +1,64 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include + + +namespace BPackageKit { + + +BUserSettingsFileInfo::BUserSettingsFileInfo() + : + fPath(), + fTemplatePath() +{ +} + + +BUserSettingsFileInfo::BUserSettingsFileInfo(const BString& path, + const BString& templatePath) + : + fPath(path), + fTemplatePath(templatePath) +{ +} + + +BUserSettingsFileInfo::~BUserSettingsFileInfo() +{ +} + + +status_t +BUserSettingsFileInfo::InitCheck() const +{ + return fPath.IsEmpty() ? B_NO_INIT : B_OK; +} + + +const BString& +BUserSettingsFileInfo::Path() const +{ + return fPath; +} + + +const BString& +BUserSettingsFileInfo::TemplatePath() const +{ + return fTemplatePath; +} + + +void +BUserSettingsFileInfo::SetTo(const BString& path, const BString& templatePath) +{ + fPath = path; + fTemplatePath = templatePath; +} + + +} // namespace BPackageKit diff --git a/src/kits/package/hpkg/ReaderImplBase.cpp b/src/kits/package/hpkg/ReaderImplBase.cpp index a9d6ec8d1b..08f2787f32 100644 --- a/src/kits/package/hpkg/ReaderImplBase.cpp +++ b/src/kits/package/hpkg/ReaderImplBase.cpp @@ -105,6 +105,31 @@ ReaderImplBase::AttributeHandler::Delete(AttributeHandlerContext* context) } +// #pragma mark - PackageInfoAttributeHandlerBase + + +ReaderImplBase::PackageInfoAttributeHandlerBase + ::PackageInfoAttributeHandlerBase( + BPackageInfoAttributeValue& packageInfoValue) + : + fPackageInfoValue(packageInfoValue) +{ +} + + +status_t +ReaderImplBase::PackageInfoAttributeHandlerBase::Delete( + AttributeHandlerContext* context) +{ + status_t error = context->packageContentHandler->HandlePackageAttribute( + fPackageInfoValue); + fPackageInfoValue.Clear(); + + delete this; + return error; +} + + // #pragma mark - PackageVersionAttributeHandler @@ -112,7 +137,7 @@ ReaderImplBase::PackageVersionAttributeHandler::PackageVersionAttributeHandler( BPackageInfoAttributeValue& packageInfoValue, BPackageVersionData& versionData, bool notify) : - fPackageInfoValue(packageInfoValue), + PackageInfoAttributeHandlerBase(packageInfoValue), fPackageVersionData(versionData), fNotify(notify) { @@ -179,7 +204,7 @@ ReaderImplBase::PackageResolvableAttributeHandler ::PackageResolvableAttributeHandler( BPackageInfoAttributeValue& packageInfoValue) : - fPackageInfoValue(packageInfoValue) + PackageInfoAttributeHandlerBase(packageInfoValue) { } @@ -230,19 +255,6 @@ ReaderImplBase::PackageResolvableAttributeHandler::HandleAttribute( } -status_t -ReaderImplBase::PackageResolvableAttributeHandler::Delete( - AttributeHandlerContext* context) -{ - status_t error = context->packageContentHandler->HandlePackageAttribute( - fPackageInfoValue); - fPackageInfoValue.Clear(); - - delete this; - return error; -} - - // #pragma mark - PackageResolvableExpressionAttributeHandler @@ -250,7 +262,7 @@ ReaderImplBase::PackageResolvableExpressionAttributeHandler ::PackageResolvableExpressionAttributeHandler( BPackageInfoAttributeValue& packageInfoValue) : - fPackageInfoValue(packageInfoValue) + PackageInfoAttributeHandlerBase(packageInfoValue) { } @@ -303,19 +315,87 @@ ReaderImplBase::PackageResolvableExpressionAttributeHandler::HandleAttribute( } -status_t -ReaderImplBase::PackageResolvableExpressionAttributeHandler::Delete( - AttributeHandlerContext* context) -{ - status_t error = context->packageContentHandler->HandlePackageAttribute( - fPackageInfoValue); - fPackageInfoValue.Clear(); +// #pragma mark - GlobalSettingsFileInfoAttributeHandler - delete this; - return error; + +ReaderImplBase::GlobalSettingsFileInfoAttributeHandler + ::GlobalSettingsFileInfoAttributeHandler( + BPackageInfoAttributeValue& packageInfoValue) + : + PackageInfoAttributeHandlerBase(packageInfoValue) +{ } +status_t +ReaderImplBase::GlobalSettingsFileInfoAttributeHandler::HandleAttribute( + AttributeHandlerContext* context, uint8 id, const AttributeValue& value, + AttributeHandler** _handler) +{ + switch (id) { + case B_HPKG_ATTRIBUTE_ID_PACKAGE_SETTINGS_FILE_UPDATE_TYPE: + if (value.unsignedInt >= B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT) { + context->errorOutput->PrintError( + "Error: Invalid package attribute section: invalid " + "global settings file update type %" B_PRIu64 + " encountered\n", value.unsignedInt); + return B_BAD_DATA; + } + fPackageInfoValue.globalSettingsFileInfo.updateType + = (BSettingsFileUpdateType)value.unsignedInt; + break; + + default: + if (context->ignoreUnknownAttributes) + break; + + context->errorOutput->PrintError("Error: Invalid package " + "attribute section: unexpected package attribute id %d " + "encountered when parsing global settings file info\n", + id); + return B_BAD_DATA; + } + + return B_OK; +} + + +// #pragma mark - UserSettingsFileInfoAttributeHandler + + +ReaderImplBase::UserSettingsFileInfoAttributeHandler + ::UserSettingsFileInfoAttributeHandler( + BPackageInfoAttributeValue& packageInfoValue) + : + PackageInfoAttributeHandlerBase(packageInfoValue) +{ +} + + +status_t +ReaderImplBase::UserSettingsFileInfoAttributeHandler::HandleAttribute( + AttributeHandlerContext* context, uint8 id, const AttributeValue& value, + AttributeHandler** _handler) +{ + switch (id) { + case B_HPKG_ATTRIBUTE_ID_PACKAGE_SETTINGS_FILE_TEMPLATE: + fPackageInfoValue.userSettingsFileInfo.templatePath = value.string; + break; + + default: + if (context->ignoreUnknownAttributes) + break; + + context->errorOutput->PrintError("Error: Invalid package " + "attribute section: unexpected package attribute id %d " + "encountered when parsing user settings file info\n", + id); + return B_BAD_DATA; + } + + return B_OK; +} + // #pragma mark - PackageAttributeHandler @@ -455,6 +535,34 @@ ReaderImplBase::PackageAttributeHandler::HandleAttribute( fPackageInfoValue.SetTo(B_PACKAGE_INFO_INSTALL_PATH, value.string); break; + case B_HPKG_ATTRIBUTE_ID_PACKAGE_GLOBAL_SETTINGS_FILE: + fPackageInfoValue.globalSettingsFileInfo.path = value.string; + fPackageInfoValue.globalSettingsFileInfo.updateType + = B_SETTINGS_FILE_UPDATE_TYPE_ENUM_COUNT; + fPackageInfoValue.attributeID + = B_PACKAGE_INFO_GLOBAL_SETTINGS_FILES; + if (_handler != NULL) { + *_handler + = new(std::nothrow) GlobalSettingsFileInfoAttributeHandler( + fPackageInfoValue); + if (*_handler == NULL) + return B_NO_MEMORY; + } + break; + + case B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SETTINGS_FILE: + fPackageInfoValue.globalSettingsFileInfo.path = value.string; + fPackageInfoValue.attributeID + = B_PACKAGE_INFO_USER_SETTINGS_FILES; + if (_handler != NULL) { + *_handler + = new(std::nothrow) UserSettingsFileInfoAttributeHandler( + fPackageInfoValue); + if (*_handler == NULL) + return B_NO_MEMORY; + } + break; + default: if (context->ignoreUnknownAttributes) break; diff --git a/src/kits/package/hpkg/WriterImplBase.cpp b/src/kits/package/hpkg/WriterImplBase.cpp index 0e3e6aab6c..d204e7d17c 100644 --- a/src/kits/package/hpkg/WriterImplBase.cpp +++ b/src/kits/package/hpkg/WriterImplBase.cpp @@ -435,6 +435,51 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList, attributeList.Add(replaces); } + // global settings file info list + const BObjectList& globalSettingsFileInfos + = packageInfo.GlobalSettingsFileInfos(); + for (int32 i = 0; i < globalSettingsFileInfos.CountItems(); ++i) { + BGlobalSettingsFileInfo* info = globalSettingsFileInfos.ItemAt(i); + PackageAttribute* attribute = new PackageAttribute( + B_HPKG_ATTRIBUTE_ID_PACKAGE_GLOBAL_SETTINGS_FILE, + B_HPKG_ATTRIBUTE_TYPE_STRING, + B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE); + attribute->string = fPackageStringCache.Get(info->Path()); + attributeList.Add(attribute); + + if (info->IsIncluded()) { + PackageAttribute* updateTypeAttribute = new PackageAttribute( + B_HPKG_ATTRIBUTE_ID_PACKAGE_SETTINGS_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& userSettingsFileInfos + = packageInfo.UserSettingsFileInfos(); + for (int32 i = 0; i < userSettingsFileInfos.CountItems(); ++i) { + BUserSettingsFileInfo* info = userSettingsFileInfos.ItemAt(i); + PackageAttribute* attribute = new PackageAttribute( + B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SETTINGS_FILE, + B_HPKG_ATTRIBUTE_TYPE_STRING, + B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE); + attribute->string = fPackageStringCache.Get(info->Path()); + attributeList.Add(attribute); + + if (!info->TemplatePath().IsEmpty()) { + PackageAttribute* templatePathAttribute = new PackageAttribute( + B_HPKG_ATTRIBUTE_ID_PACKAGE_SETTINGS_FILE_TEMPLATE, + B_HPKG_ATTRIBUTE_TYPE_STRING, + B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE); + templatePathAttribute->string + = fPackageStringCache.Get(info->TemplatePath()); + attribute->children.Add(templatePathAttribute); + } + } + // checksum (optional, only exists in repositories) if (packageInfo.Checksum().Length() > 0) { PackageAttribute* checksum = new PackageAttribute(