[haiku-commits] BRANCH weinhold-github.new-hpkg-format [a6248fb] src/kits/package src/kits/package/hpkg headers/os/package headers/os/package/hpkg headers/private/package/hpkg

  • From: weinhold-github.new-hpkg-format <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 23 May 2013 21:30:36 +0200 (CEST)

added 7 changesets to branch 'refs/remotes/weinhold-github/new-hpkg-format'
old head: ef6c87440805bde7c7da1210d6fcdced1d2a8cb6
new head: a6248fb34dbb67a65c05e76f857655525928a81a
overview: https://github.com/weinhold/HaikuPM/compare/ef6c874...a6248fb

----------------------------------------------------------------------------

3dade74: Declare some string constants actually const

0df6aba: Add "source" package architecture

4e8fb56: Package/repository file format: Add a minor version header field
  
  * Add minor_version to hpkg_header and hpkg_repo_header and make
    heap_compression uint16.
  * If the minor version of a package/repository file is greater than the
    current one unknown attributes are ignored without error. This allows
    introducing new harmless attributes without making the resulting files
    unreadable for older package kit versions.

7f8532a: RepositoryWriterImpl: Write the heap fields in the header

434494e: PackageFileHeapWriter::RemoveDataRanges(): Fix empty heap check

ccf6308: hpkg attribute tags: use 7 bits for attribute ID
  
  ATM the 6 bits suffice, but there isn't that much headroom.

a6248fb: 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.

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

29 files changed, 1084 insertions(+), 135 deletions(-)
.../build/os/package/GlobalSettingsFileInfo.h    |   1 +
.../build/os/package/SettingsFileUpdateType.h    |   1 +
headers/build/os/package/UserSettingsFileInfo.h  |   1 +
headers/os/package/GlobalSettingsFileInfo.h      |  41 ++
headers/os/package/PackageArchitecture.h         |   3 +-
headers/os/package/PackageInfo.h                 |  43 +-
headers/os/package/PackageInfoAttributes.h       |   6 +-
headers/os/package/RepositoryInfo.h              |  16 +-
headers/os/package/SettingsFileUpdateType.h      |  35 ++
headers/os/package/UserSettingsFileInfo.h        |  39 ++
headers/os/package/hpkg/HPKGDefs.h               |  98 ++---
.../os/package/hpkg/PackageInfoAttributeValue.h  |  15 +
headers/private/package/hpkg/HPKGDefsPrivate.h   |  18 +-
headers/private/package/hpkg/ReaderImplBase.h    |  78 +++-
.../file_systems/packagefs/package/Package.cpp   |   1 +
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                 | 401 ++++++++++++++++++-
src/kits/package/RepositoryInfo.cpp              |  16 +-
src/kits/package/UserSettingsFileInfo.cpp        |  64 +++
src/kits/package/hpkg/PackageFileHeapWriter.cpp  |   2 +-
src/kits/package/hpkg/PackageReaderImpl.cpp      |   6 +-
src/kits/package/hpkg/PackageWriterImpl.cpp      |   3 +-
src/kits/package/hpkg/ReaderImplBase.cpp         | 172 ++++++--
src/kits/package/hpkg/RepositoryReaderImpl.cpp   |   3 +-
src/kits/package/hpkg/RepositoryWriterImpl.cpp   |  11 +-
src/kits/package/hpkg/WriterImplBase.cpp         |  45 +++

############################################################################

Commit:      3dade743c7671618f404e1e8cbcfb48be8fef491
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue May 21 21:20:51 2013 UTC

Declare some string constants actually const

----------------------------------------------------------------------------

diff --git a/headers/os/package/PackageInfo.h b/headers/os/package/PackageInfo.h
index f2b08b2..c51bb8f 100644
--- a/headers/os/package/PackageInfo.h
+++ b/headers/os/package/PackageInfo.h
@@ -161,8 +161,8 @@ public:
                                                                        
ParseErrorListener* listener = NULL);
 
 public:
-       static  const char*                     kElementNames[];
-       static  const char*                     kArchitectureNames[];
+       static  const char*     const   kElementNames[];
+       static  const char*     const   kArchitectureNames[];
 
 private:
                        class Parser;
diff --git a/headers/os/package/RepositoryInfo.h 
b/headers/os/package/RepositoryInfo.h
index b74f017..db69dc6 100644
--- a/headers/os/package/RepositoryInfo.h
+++ b/headers/os/package/RepositoryInfo.h
@@ -57,14 +57,14 @@ public:
 
        static  const uint8                     kDefaultPriority;
 
-       static  const char*                     kNameField;
-       static  const char*                     kURLField;
-       static  const char*                     kVendorField;
-       static  const char*                     kSummaryField;
-       static  const char*                     kPriorityField;
-       static  const char*                     kArchitectureField;
-       static  const char*                     kLicenseNameField;
-       static  const char*                     kLicenseTextField;
+       static  const char* const       kNameField;
+       static  const char* const       kURLField;
+       static  const char* const       kVendorField;
+       static  const char*     const   kSummaryField;
+       static  const char*     const   kPriorityField;
+       static  const char*     const   kArchitectureField;
+       static  const char*     const   kLicenseNameField;
+       static  const char*     const   kLicenseTextField;
 
 private:
                        status_t                        fInitStatus;
diff --git a/src/kits/package/PackageInfo.cpp b/src/kits/package/PackageInfo.cpp
index 6e6553e..a7c0830 100644
--- a/src/kits/package/PackageInfo.cpp
+++ b/src/kits/package/PackageInfo.cpp
@@ -966,7 +966,7 @@ BPackageInfo::Parser::_IsValidResolvableName(const char* 
string,
 }
 
 
-const char* BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = {
+const char* const BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = {
        "name",
        "summary",
        "description",
@@ -990,7 +990,7 @@ const char* 
BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = {
 };
 
 
-const char*
+const char* const
 BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = {
        "any",
        "x86",
diff --git a/src/kits/package/RepositoryInfo.cpp 
b/src/kits/package/RepositoryInfo.cpp
index 5dce7e1..ea042fe 100644
--- a/src/kits/package/RepositoryInfo.cpp
+++ b/src/kits/package/RepositoryInfo.cpp
@@ -26,14 +26,14 @@ namespace BPackageKit {
 
 const uint8 BRepositoryInfo::kDefaultPriority  = 50;
 
-const char* BRepositoryInfo::kNameField                        = "name";
-const char* BRepositoryInfo::kURLField                 = "url";
-const char* BRepositoryInfo::kVendorField              = "vendor";
-const char* BRepositoryInfo::kSummaryField             = "summary";
-const char* BRepositoryInfo::kPriorityField            = "priority";
-const char* BRepositoryInfo::kArchitectureField        = "architecture";
-const char* BRepositoryInfo::kLicenseNameField = "licenseName";
-const char* BRepositoryInfo::kLicenseTextField = "licenseText";
+const char* const BRepositoryInfo::kNameField                  = "name";
+const char* const BRepositoryInfo::kURLField                   = "url";
+const char* const BRepositoryInfo::kVendorField                        = 
"vendor";
+const char* const BRepositoryInfo::kSummaryField               = "summary";
+const char* const BRepositoryInfo::kPriorityField              = "priority";
+const char* const BRepositoryInfo::kArchitectureField  = "architecture";
+const char* const BRepositoryInfo::kLicenseNameField   = "licenseName";
+const char* const BRepositoryInfo::kLicenseTextField   = "licenseText";
 
 
 BRepositoryInfo::BRepositoryInfo()

############################################################################

Commit:      0df6aba9c9853e629bfb3d3e578c750a7babf2cb
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue May 21 21:21:06 2013 UTC

Add "source" package architecture

----------------------------------------------------------------------------

diff --git a/headers/os/package/PackageArchitecture.h 
b/headers/os/package/PackageArchitecture.h
index 100bf8d..2527e1b 100644
--- a/headers/os/package/PackageArchitecture.h
+++ b/headers/os/package/PackageArchitecture.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_ARCHITECTURE_H_
@@ -13,6 +13,7 @@ enum BPackageArchitecture {
        B_PACKAGE_ARCHITECTURE_ANY              = 0,
        B_PACKAGE_ARCHITECTURE_X86              = 1,
        B_PACKAGE_ARCHITECTURE_X86_GCC2 = 2,
+       B_PACKAGE_ARCHITECTURE_SOURCE   = 3,
        //
        B_PACKAGE_ARCHITECTURE_ENUM_COUNT,
 };
diff --git a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp 
b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
index 541ec3f..4e55e7e 100644
--- a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
+++ b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp
@@ -61,6 +61,7 @@ const char* const 
kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = {
        "any",
        "x86",
        "x86_gcc2",
+       "source",
 };
 
 
diff --git a/src/kits/package/PackageInfo.cpp b/src/kits/package/PackageInfo.cpp
index a7c0830..b6fa351 100644
--- a/src/kits/package/PackageInfo.cpp
+++ b/src/kits/package/PackageInfo.cpp
@@ -995,6 +995,7 @@ 
BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = {
        "any",
        "x86",
        "x86_gcc2",
+       "source",
 };
 
 

############################################################################

Commit:      4e8fb564566d6933e6ce7111280d77949fa19b30
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue May 21 22:20:13 2013 UTC

Package/repository file format: Add a minor version header field

* Add minor_version to hpkg_header and hpkg_repo_header and make
  heap_compression uint16.
* If the minor version of a package/repository file is greater than the
  current one unknown attributes are ignored without error. This allows
  introducing new harmless attributes without making the resulting files
  unreadable for older package kit versions.

----------------------------------------------------------------------------

diff --git a/headers/os/package/hpkg/HPKGDefs.h 
b/headers/os/package/hpkg/HPKGDefs.h
index 9f1029e..f1e2ed5 100644
--- a/headers/os/package/hpkg/HPKGDefs.h
+++ b/headers/os/package/hpkg/HPKGDefs.h
@@ -16,11 +16,13 @@ namespace BHPKG {
 
 // magic & version of package and repository files
 enum {
-       B_HPKG_MAGIC    = 'hpkg',
-       B_HPKG_VERSION  = 2,
+       B_HPKG_MAGIC                            = 'hpkg',
+       B_HPKG_VERSION                          = 2,
+       B_HPKG_MINOR_VERSION            = 0,
        //
-       B_HPKG_REPO_MAGIC       = 'hpkr',
-       B_HPKG_REPO_VERSION     = 2
+       B_HPKG_REPO_MAGIC                       = 'hpkr',
+       B_HPKG_REPO_VERSION                     = 2,
+       B_HPKG_REPO_MINOR_VERSION       = 0
 };
 
 
diff --git a/headers/private/package/hpkg/HPKGDefsPrivate.h 
b/headers/private/package/hpkg/HPKGDefsPrivate.h
index ce8837d..cfc6143 100644
--- a/headers/private/package/hpkg/HPKGDefsPrivate.h
+++ b/headers/private/package/hpkg/HPKGDefsPrivate.h
@@ -24,9 +24,10 @@ struct hpkg_header {
        uint16  header_size;
        uint16  version;
        uint64  total_size;
+       uint16  minor_version;
 
        // heap
-       uint32  heap_compression;
+       uint16  heap_compression;
        uint32  heap_chunk_size;
        uint64  heap_size_compressed;
        uint64  heap_size_uncompressed;
@@ -50,9 +51,10 @@ struct hpkg_repo_header {
        uint16  header_size;
        uint16  version;
        uint64  total_size;
+       uint16  minor_version;
 
        // heap
-       uint32  heap_compression;
+       uint16  heap_compression;
        uint32  heap_chunk_size;
        uint64  heap_size_compressed;
        uint64  heap_size_uncompressed;
diff --git a/headers/private/package/hpkg/ReaderImplBase.h 
b/headers/private/package/hpkg/ReaderImplBase.h
index 5324812..de25a3f 100644
--- a/headers/private/package/hpkg/ReaderImplBase.h
+++ b/headers/private/package/hpkg/ReaderImplBase.h
@@ -72,6 +72,9 @@ protected:
 
                        BErrorOutput*           ErrorOutput() const;
 
+                       uint16                          MinorFormatVersion() 
const
+                                                                       { 
return fMinorFormatVersion; }
+
                        uint64                          UncompressedHeapSize() 
const;
 
                        PackageFileHeapReader* RawHeapReader() const
@@ -175,6 +178,7 @@ private:
                        BErrorOutput*           fErrorOutput;
                        int                                     fFD;
                        bool                            fOwnsFD;
+                       uint16                          fMinorFormatVersion;
 
                        PackageFileHeapReader* fRawHeapReader;
                        BAbstractBufferedDataReader* fHeapReader;
@@ -199,7 +203,8 @@ public:
                                BLowLevelPackageContentHandler* lowLevelHandler;
                        };
                        bool                                    
hasLowLevelHandler;
-               
+                       bool                                    
ignoreUnknownAttributes;
+
                        BHPKGPackageSectionID   section;
 
 public:
@@ -207,12 +212,14 @@ public:
                                                                        
BErrorOutput* errorOutput,
                                                                        
BPackageContentHandler*
                                                                                
packageContentHandler,
-                                                                       
BHPKGPackageSectionID section);
+                                                                       
BHPKGPackageSectionID section,
+                                                                       bool 
ignoreUnknownAttributes);
                                                                
AttributeHandlerContext(
                                                                        
BErrorOutput* errorOutput,
                                                                        
BLowLevelPackageContentHandler*
                                                                                
lowLevelHandler,
-                                                                       
BHPKGPackageSectionID section);
+                                                                       
BHPKGPackageSectionID section,
+                                                                       bool 
ignoreUnknownAttributes);
 
                        void                            ErrorOccurred();
 };
@@ -375,6 +382,8 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, 
uint32 flags)
                return B_MISMATCHED_VALUES;
        }
 
+       fMinorFormatVersion = B_BENDIAN_TO_HOST_INT16(header.minor_version);
+
        // header size
        uint64 heapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
        if (heapOffset < (off_t)sizeof(header)) {
@@ -405,7 +414,7 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, 
uint32 flags)
        }
 
        error = InitHeapReader(
-               B_BENDIAN_TO_HOST_INT32(header.heap_compression),
+               B_BENDIAN_TO_HOST_INT16(header.heap_compression),
                B_BENDIAN_TO_HOST_INT32(header.heap_chunk_size), heapOffset,
                compressedHeapSize,
                B_BENDIAN_TO_HOST_INT64(header.heap_size_uncompressed));
diff --git a/src/kits/package/hpkg/PackageReaderImpl.cpp 
b/src/kits/package/hpkg/PackageReaderImpl.cpp
index 83ff096..370a89a 100644
--- a/src/kits/package/hpkg/PackageReaderImpl.cpp
+++ b/src/kits/package/hpkg/PackageReaderImpl.cpp
@@ -375,7 +375,8 @@ status_t
 PackageReaderImpl::ParseContent(BPackageContentHandler* contentHandler)
 {
        AttributeHandlerContext context(ErrorOutput(), contentHandler,
-               B_HPKG_SECTION_PACKAGE_ATTRIBUTES);
+               B_HPKG_SECTION_PACKAGE_ATTRIBUTES,
+               MinorFormatVersion() > B_HPKG_MINOR_VERSION);
        RootAttributeHandler rootAttributeHandler;
 
        status_t error
@@ -394,7 +395,8 @@ status_t
 PackageReaderImpl::ParseContent(BLowLevelPackageContentHandler* contentHandler)
 {
        AttributeHandlerContext context(ErrorOutput(), contentHandler,
-               B_HPKG_SECTION_PACKAGE_ATTRIBUTES);
+               B_HPKG_SECTION_PACKAGE_ATTRIBUTES,
+               MinorFormatVersion() > B_HPKG_MINOR_VERSION);
        LowLevelAttributeHandler rootAttributeHandler;
 
        status_t error
diff --git a/src/kits/package/hpkg/PackageWriterImpl.cpp 
b/src/kits/package/hpkg/PackageWriterImpl.cpp
index b7fc37a..228e1db 100644
--- a/src/kits/package/hpkg/PackageWriterImpl.cpp
+++ b/src/kits/package/hpkg/PackageWriterImpl.cpp
@@ -1077,7 +1077,7 @@ PackageWriterImpl::_Finish()
 
        uint64 compressedHeapSize = fHeapWriter->CompressedHeapSize();
 
-       header.heap_compression = 
B_HOST_TO_BENDIAN_INT32(B_HPKG_COMPRESSION_ZLIB);
+       header.heap_compression = 
B_HOST_TO_BENDIAN_INT16(B_HPKG_COMPRESSION_ZLIB);
        header.heap_chunk_size = 
B_HOST_TO_BENDIAN_INT32(fHeapWriter->ChunkSize());
        header.heap_size_compressed = B_HOST_TO_BENDIAN_INT64(
                fHeapWriter->CompressedHeapSize());
@@ -1104,6 +1104,7 @@ PackageWriterImpl::_Finish()
        header.header_size = B_HOST_TO_BENDIAN_INT16(fHeaderSize);
        header.version = B_HOST_TO_BENDIAN_INT16(B_HPKG_VERSION);
        header.total_size = B_HOST_TO_BENDIAN_INT64(totalSize);
+       header.minor_version = B_HOST_TO_BENDIAN_INT16(B_HPKG_MINOR_VERSION);
 
        // write the header
        RawWriteBuffer(&header, sizeof(hpkg_header), 0);
diff --git a/src/kits/package/hpkg/ReaderImplBase.cpp 
b/src/kits/package/hpkg/ReaderImplBase.cpp
index ba4b0b5..a9d6ec8 100644
--- a/src/kits/package/hpkg/ReaderImplBase.cpp
+++ b/src/kits/package/hpkg/ReaderImplBase.cpp
@@ -39,11 +39,12 @@ static const size_t kScratchBufferSize = 64 * 1024;
 
 ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
        BErrorOutput* errorOutput, BPackageContentHandler* 
packageContentHandler,
-       BHPKGPackageSectionID section)
+       BHPKGPackageSectionID section, bool ignoreUnknownAttributes)
        :
        errorOutput(errorOutput),
        packageContentHandler(packageContentHandler),
        hasLowLevelHandler(false),
+       ignoreUnknownAttributes(ignoreUnknownAttributes),
        section(section)
 {
 }
@@ -51,11 +52,12 @@ 
ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
 
 ReaderImplBase::AttributeHandlerContext::AttributeHandlerContext(
        BErrorOutput* errorOutput, BLowLevelPackageContentHandler* 
lowLevelHandler,
-       BHPKGPackageSectionID section)
+       BHPKGPackageSectionID section, bool ignoreUnknownAttributes)
        :
        errorOutput(errorOutput),
        lowLevelHandler(lowLevelHandler),
        hasLowLevelHandler(true),
+       ignoreUnknownAttributes(ignoreUnknownAttributes),
        section(section)
 {
 }
@@ -140,6 +142,9 @@ 
ReaderImplBase::PackageVersionAttributeHandler::HandleAttribute(
                        break;
 
                default:
+                       if (context->ignoreUnknownAttributes)
+                               break;
+
                        context->errorOutput->PrintError("Error: Invalid 
package "
                                "attribute section: unexpected package 
attribute id %d "
                                "encountered when parsing package version\n", 
id);
@@ -212,6 +217,9 @@ 
ReaderImplBase::PackageResolvableAttributeHandler::HandleAttribute(
                        break;
 
                default:
+                       if (context->ignoreUnknownAttributes)
+                               break;
+
                        context->errorOutput->PrintError("Error: Invalid 
package "
                                "attribute section: unexpected package 
attribute id %d "
                                "encountered when parsing package 
resolvable\n", id);
@@ -281,6 +289,9 @@ 
ReaderImplBase::PackageResolvableExpressionAttributeHandler::HandleAttribute(
                        return B_OK;
 
                default:
+                       if (context->ignoreUnknownAttributes)
+                               break;
+
                        context->errorOutput->PrintError("Error: Invalid 
package "
                                "attribute section: unexpected package 
attribute id %d "
                                "encountered when parsing package 
resolvable-expression\n",
@@ -445,6 +456,9 @@ ReaderImplBase::PackageAttributeHandler::HandleAttribute(
                        break;
 
                default:
+                       if (context->ignoreUnknownAttributes)
+                               break;
+
                        context->errorOutput->PrintError(
                                "Error: Invalid package attribute section: 
unexpected "
                                "package attribute id %d encountered\n", id);
diff --git a/src/kits/package/hpkg/RepositoryReaderImpl.cpp 
b/src/kits/package/hpkg/RepositoryReaderImpl.cpp
index 98867ab..a9a5b1c 100644
--- a/src/kits/package/hpkg/RepositoryReaderImpl.cpp
+++ b/src/kits/package/hpkg/RepositoryReaderImpl.cpp
@@ -141,7 +141,8 @@ 
RepositoryReaderImpl::ParseContent(BRepositoryContentHandler* contentHandler)
        status_t result = contentHandler->HandleRepositoryInfo(fRepositoryInfo);
        if (result == B_OK) {
                AttributeHandlerContext context(ErrorOutput(), contentHandler,
-                       B_HPKG_SECTION_PACKAGE_ATTRIBUTES);
+                       B_HPKG_SECTION_PACKAGE_ATTRIBUTES,
+                       MinorFormatVersion() > B_HPKG_REPO_MINOR_VERSION);
                PackageAttributeHandler rootAttributeHandler;
                result = ParsePackageAttributesSection(&context, 
&rootAttributeHandler);
        }
diff --git a/src/kits/package/hpkg/RepositoryWriterImpl.cpp 
b/src/kits/package/hpkg/RepositoryWriterImpl.cpp
index ec9cf99..619d6d2 100644
--- a/src/kits/package/hpkg/RepositoryWriterImpl.cpp
+++ b/src/kits/package/hpkg/RepositoryWriterImpl.cpp
@@ -285,6 +285,7 @@ RepositoryWriterImpl::_Finish()
        header.header_size = B_HOST_TO_BENDIAN_INT16((uint16)sizeof(header));
        header.version = B_HOST_TO_BENDIAN_INT16(B_HPKG_REPO_VERSION);
        header.total_size = B_HOST_TO_BENDIAN_INT64(totalSize);
+       header.minor_version = 
B_HOST_TO_BENDIAN_INT16(B_HPKG_REPO_MINOR_VERSION);
 
        RawWriteBuffer(&header, sizeof(header), 0);
 

############################################################################

Commit:      7f8532a2fd01cd2f575f9ec4a26e8dcceb3ba71f
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue May 21 22:20:50 2013 UTC

RepositoryWriterImpl: Write the heap fields in the header

----------------------------------------------------------------------------

diff --git a/src/kits/package/hpkg/RepositoryWriterImpl.cpp 
b/src/kits/package/hpkg/RepositoryWriterImpl.cpp
index 619d6d2..e2751e6 100644
--- a/src/kits/package/hpkg/RepositoryWriterImpl.cpp
+++ b/src/kits/package/hpkg/RepositoryWriterImpl.cpp
@@ -273,8 +273,14 @@ RepositoryWriterImpl::_Finish()
        result = fHeapWriter->Finish();
        if (result != B_OK)
                return result;
-       uint64 totalSize = fHeapWriter->HeapOffset()
-               + fHeapWriter->CompressedHeapSize();
+       uint64 compressedHeapSize = fHeapWriter->CompressedHeapSize();
+       uint64 totalSize = fHeapWriter->HeapOffset() + compressedHeapSize;
+
+       header.heap_compression = 
B_HOST_TO_BENDIAN_INT16(B_HPKG_COMPRESSION_ZLIB);
+       header.heap_chunk_size = 
B_HOST_TO_BENDIAN_INT32(fHeapWriter->ChunkSize());
+       header.heap_size_compressed = 
B_HOST_TO_BENDIAN_INT64(compressedHeapSize);
+       header.heap_size_uncompressed = B_HOST_TO_BENDIAN_INT64(
+               fHeapWriter->UncompressedHeapSize());
 
        fListener->OnRepositoryDone(sizeof(header), infoLength,
                fRepositoryInfo->LicenseNames().CountStrings(), fPackageCount,

############################################################################

Commit:      434494e9bdadd595330e2b6100fd11682ee530cc
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Thu May 23 19:07:08 2013 UTC

PackageFileHeapWriter::RemoveDataRanges(): Fix empty heap check

----------------------------------------------------------------------------

diff --git a/src/kits/package/hpkg/PackageFileHeapWriter.cpp 
b/src/kits/package/hpkg/PackageFileHeapWriter.cpp
index 5c24945..7bf45fa 100644
--- a/src/kits/package/hpkg/PackageFileHeapWriter.cpp
+++ b/src/kits/package/hpkg/PackageFileHeapWriter.cpp
@@ -291,7 +291,7 @@ PackageFileHeapWriter::RemoveDataRanges(
        if (rangeCount == 0)
                return;
 
-       if (fOffsets.IsEmpty()) {
+       if (fUncompressedHeapSize == 0) {
                fErrorOutput->PrintError("Can't remove ranges from empty 
heap\n");
                throw status_t(B_BAD_VALUE);
        }

############################################################################

Commit:      ccf6308d3d82abf7b739c1ed43bd0a94bb48038d
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Thu May 23 19:17:29 2013 UTC

hpkg attribute tags: use 7 bits for attribute ID

ATM the 6 bits suffice, but there isn't that much headroom.

----------------------------------------------------------------------------

diff --git a/headers/private/package/hpkg/HPKGDefsPrivate.h 
b/headers/private/package/hpkg/HPKGDefsPrivate.h
index cfc6143..3966cd6 100644
--- a/headers/private/package/hpkg/HPKGDefsPrivate.h
+++ b/headers/private/package/hpkg/HPKGDefsPrivate.h
@@ -71,11 +71,11 @@ struct hpkg_repo_header {
 
 
 // attribute tag arithmetics
-// (using 6 bits for id, 3 for type, 1 for hasChildren and 2 for encoding)
+// (using 7 bits for id, 3 for type, 1 for hasChildren and 2 for encoding)
 static inline uint16
 compose_attribute_tag(uint16 id, uint16 type, uint16 encoding, bool 
hasChildren)
 {
-       return ((encoding << 10) | (uint16(hasChildren ? 1 : 0) << 9) | (type 
<< 6)
+       return ((encoding << 11) | (uint16(hasChildren ? 1 : 0) << 10) | (type 
<< 7)
                        | id)
                + 1;
 }
@@ -84,28 +84,28 @@ compose_attribute_tag(uint16 id, uint16 type, uint16 
encoding, bool hasChildren)
 static inline uint16
 attribute_tag_encoding(uint16 tag)
 {
-       return ((tag - 1) >> 10) & 0x3;
+       return ((tag - 1) >> 11) & 0x3;
 }
 
 
 static inline bool
 attribute_tag_has_children(uint16 tag)
 {
-       return (((tag - 1) >> 9) & 0x1) != 0;
+       return (((tag - 1) >> 10) & 0x1) != 0;
 }
 
 
 static inline uint16
 attribute_tag_type(uint16 tag)
 {
-       return ((tag - 1) >> 6) & 0x7;
+       return ((tag - 1) >> 7) & 0x7;
 }
 
 
 static inline uint16
 attribute_tag_id(uint16 tag)
 {
-       return (tag - 1) & 0x3f;
+       return (tag - 1) & 0x7f;
 }
 
 

############################################################################

Commit:      a6248fb34dbb67a65c05e76f857655525928a81a
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Thu May 23 19:29:18 2013 UTC

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.

----------------------------------------------------------------------------

diff --git a/headers/build/os/package/GlobalSettingsFileInfo.h 
b/headers/build/os/package/GlobalSettingsFileInfo.h
new file mode 100644
index 0000000..6e17a15
--- /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 0000000..ab52190
--- /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 0000000..dfb2034
--- /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 0000000..735e250
--- /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 <package/SettingsFileUpdateType.h>
+#include <String.h>
+
+
+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 c51bb8f..ade89a0 100644
--- a/headers/os/package/PackageInfo.h
+++ b/headers/os/package/PackageInfo.h
@@ -11,12 +11,14 @@
 #include <String.h>
 #include <StringList.h>
 
+#include <package/GlobalSettingsFileInfo.h>
 #include <package/PackageArchitecture.h>
 #include <package/PackageFlags.h>
 #include <package/PackageInfoAttributes.h>
 #include <package/PackageResolvable.h>
 #include <package/PackageResolvableExpression.h>
 #include <package/PackageVersion.h>
+#include <package/UserSettingsFileInfo.h>
 
 
 class BEntry;
@@ -79,6 +81,11 @@ public:
                        const BStringList&      URLList() const;
                        const BStringList&      SourceURLList() const;
 
+                       const BObjectList<BGlobalSettingsFileInfo>&
+                                                                       
GlobalSettingsFileInfos() const;
+                       const BObjectList<BUserSettingsFileInfo>&
+                                                                       
UserSettingsFileInfos() const;
+
                        const BObjectList<BPackageResolvable>&  ProvidesList() 
const;
                        const BObjectList<BPackageResolvableExpression>&
                                                                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<BPackageResolvableExpression>
                                ResolvableExpressionList;
 
+                       typedef BObjectList<BGlobalSettingsFileInfo>
+                               GlobalSettingsFileInfoList;
+                       typedef BObjectList<BUserSettingsFileInfo>
+                               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<BGlobalSettingsFileInfo> 
fGlobalSettingsFileInfos;
+                       BObjectList<BUserSettingsFileInfo> 
fUserSettingsFileInfos;
+
                        ResolvableList          fProvidesList;
 
                        ResolvableExpressionList fRequiresList;
diff --git a/headers/os/package/PackageInfoAttributes.h 
b/headers/os/package/PackageInfoAttributes.h
index 83fbd4d..89b6814 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 0000000..2ddb6f2
--- /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 <String.h>
+
+
+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 0000000..c4639f7
--- /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 <String.h>
+
+
+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 f1e2ed5..f2d6e9e 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 7372612..700f5d5 100644
--- a/headers/os/package/hpkg/PackageInfoAttributeValue.h
+++ b/headers/os/package/hpkg/PackageInfoAttributeValue.h
@@ -13,6 +13,7 @@
 #include <package/PackageArchitecture.h>
 #include <package/PackageInfoAttributes.h>
 #include <package/PackageResolvableOperator.h>
+#include <package/SettingsFileUpdateType.h>
 
 
 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 de25a3f..7072dad 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@xxxxxx.
+ * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Copyright 2011, Oliver Tappe <zooey@xxxxxxxxxxxxxxx>
  * 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 caebcbf..219f03c 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 0b911b3..1851ee6 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 0000000..36229ae
--- /dev/null
+++ b/src/kits/package/GlobalSettingsFileInfo.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <package/GlobalSettingsFileInfo.h>
+
+
+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 8ea1026..ee058a1 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 b6fa351..34e14ee 100644
--- a/src/kits/package/PackageInfo.cpp
+++ b/src/kits/package/PackageInfo.cpp
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <algorithm>
 #include <new>
 
 #include <File.h>
@@ -108,6 +109,10 @@ private:
                                                                        
BObjectList<BPackageResolvableExpression>*
                                                                                
value,
                                                                        
BString* _basePackage = NULL);
+                       void                            
_ParseGlobalSettingsFileInfos(
+                                                                       
GlobalSettingsFileInfoList* infos);
+                       void                            
_ParseUserSettingsFileInfos(
+                                                                       
UserSettingsFileInfoList* infos);
 
                        void                            _Parse(BPackageInfo* 
packageInfo);
 
@@ -757,6 +762,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)
 {
        bool seen[B_PACKAGE_INFO_ENUM_COUNT];
@@ -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<typename Value>
+       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<BGlobalSettingsFileInfo>&
+BPackageInfo::GlobalSettingsFileInfos() const
+{
+       return fGlobalSettingsFileInfos;
+}
+
+
+const BObjectList<BUserSettingsFileInfo>&
+BPackageInfo::UserSettingsFileInfos() const
+{
+       return fUserSettingsFileInfos;
+}
+
+
 const BObjectList<BPackageResolvable>&
 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)
@@ -2188,6 +2419,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 0000000..b232798
--- /dev/null
+++ b/src/kits/package/UserSettingsFileInfo.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <package/UserSettingsFileInfo.h>
+
+
+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 a9d6ec8..08f2787 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(
 }
 
 
+// #pragma mark - GlobalSettingsFileInfoAttributeHandler
+
+
+ReaderImplBase::GlobalSettingsFileInfoAttributeHandler
+       ::GlobalSettingsFileInfoAttributeHandler(
+               BPackageInfoAttributeValue& packageInfoValue)
+       :
+       PackageInfoAttributeHandlerBase(packageInfoValue)
+{
+}
+
+
 status_t
-ReaderImplBase::PackageResolvableExpressionAttributeHandler::Delete(
-       AttributeHandlerContext* context)
+ReaderImplBase::GlobalSettingsFileInfoAttributeHandler::HandleAttribute(
+       AttributeHandlerContext* context, uint8 id, const AttributeValue& value,
+       AttributeHandler** _handler)
 {
-       status_t error = context->packageContentHandler->HandlePackageAttribute(
-               fPackageInfoValue);
-       fPackageInfoValue.Clear();
+       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;
 
-       delete this;
-       return error;
+               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 0e3e6aa..d204e7d 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<BGlobalSettingsFileInfo>& 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<BUserSettingsFileInfo>& 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(


Other related posts:

  • » [haiku-commits] BRANCH weinhold-github.new-hpkg-format [a6248fb] src/kits/package src/kits/package/hpkg headers/os/package headers/os/package/hpkg headers/private/package/hpkg - weinhold-github . new-hpkg-format