package list/extract: Add support for hpkg format V1
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009-2011, Ingo Weinhold, [email protected].
|
* Copyright 2009-2013, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -25,19 +25,68 @@
|
|||||||
|
|
||||||
#include <util/OpenHashTable.h>
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
#include <package/BlockBufferCacheNoLock.h>
|
||||||
#include <package/hpkg/PackageContentHandler.h>
|
#include <package/hpkg/PackageContentHandler.h>
|
||||||
#include <package/hpkg/PackageDataReader.h>
|
#include <package/hpkg/PackageDataReader.h>
|
||||||
#include <package/hpkg/PackageEntry.h>
|
#include <package/hpkg/PackageEntry.h>
|
||||||
#include <package/hpkg/PackageEntryAttribute.h>
|
#include <package/hpkg/PackageEntryAttribute.h>
|
||||||
#include <package/hpkg/PackageReader.h>
|
#include <package/hpkg/PackageReader.h>
|
||||||
#include <package/hpkg/StandardErrorOutput.h>
|
#include <package/hpkg/StandardErrorOutput.h>
|
||||||
#include <package/BlockBufferCacheNoLock.h>
|
#include <package/hpkg/v1/PackageContentHandler.h>
|
||||||
|
#include <package/hpkg/v1/PackageDataReader.h>
|
||||||
|
#include <package/hpkg/v1/PackageEntry.h>
|
||||||
|
#include <package/hpkg/v1/PackageEntryAttribute.h>
|
||||||
|
#include <package/hpkg/v1//PackageReader.h>
|
||||||
|
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace BPackageKit::BHPKG;
|
|
||||||
using BPackageKit::BBlockBufferCacheNoLock;
|
using BPackageKit::BBlockBufferCacheNoLock;
|
||||||
|
using BPackageKit::BHPKG::BAbstractBufferedDataReader;
|
||||||
|
using BPackageKit::BHPKG::BBufferDataReader;
|
||||||
|
using BPackageKit::BHPKG::BDataReader;
|
||||||
|
using BPackageKit::BHPKG::BFDDataReader;
|
||||||
|
using BPackageKit::BHPKG::BPackageInfoAttributeValue;
|
||||||
|
using BPackageKit::BHPKG::BStandardErrorOutput;
|
||||||
|
|
||||||
|
|
||||||
|
struct VersionPolicyV1 {
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageContentHandler
|
||||||
|
PackageContentHandler;
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageData PackageData;
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageDataReaderFactory
|
||||||
|
PackageDataReaderFactory;
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageEntry PackageEntry;
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageEntryAttribute
|
||||||
|
PackageEntryAttribute;
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageReader PackageReader;
|
||||||
|
|
||||||
|
static const int kDefaultDataChunkSize
|
||||||
|
= BPackageKit::BHPKG::V1::B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB;
|
||||||
|
|
||||||
|
static inline const char* PackageInfoFileName()
|
||||||
|
{
|
||||||
|
return BPackageKit::BHPKG::V1::B_HPKG_PACKAGE_INFO_FILE_NAME;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VersionPolicyV2 {
|
||||||
|
typedef BPackageKit::BHPKG::BPackageContentHandler PackageContentHandler;
|
||||||
|
typedef BPackageKit::BHPKG::BPackageData PackageData;
|
||||||
|
typedef BPackageKit::BHPKG::BPackageDataReaderFactory
|
||||||
|
PackageDataReaderFactory;
|
||||||
|
typedef BPackageKit::BHPKG::BPackageEntry PackageEntry;
|
||||||
|
typedef BPackageKit::BHPKG::BPackageEntryAttribute PackageEntryAttribute;
|
||||||
|
typedef BPackageKit::BHPKG::BPackageReader PackageReader;
|
||||||
|
|
||||||
|
static const int kDefaultDataChunkSize
|
||||||
|
= BPackageKit::BHPKG::B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB;
|
||||||
|
|
||||||
|
static inline const char* PackageInfoFileName()
|
||||||
|
{
|
||||||
|
return BPackageKit::BHPKG::B_HPKG_PACKAGE_INFO_FILE_NAME;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Entry {
|
struct Entry {
|
||||||
@@ -176,10 +225,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct PackageContentExtractHandler : BPackageContentHandler {
|
template<typename VersionPolicy>
|
||||||
|
struct PackageContentExtractHandler : VersionPolicy::PackageContentHandler {
|
||||||
PackageContentExtractHandler(int packageFileFD)
|
PackageContentExtractHandler(int packageFileFD)
|
||||||
:
|
:
|
||||||
fBufferCache(B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB, 2),
|
fBufferCache(VersionPolicy::kDefaultDataChunkSize, 2),
|
||||||
fPackageFileReader(packageFileFD),
|
fPackageFileReader(packageFileFD),
|
||||||
fDataBuffer(NULL),
|
fDataBuffer(NULL),
|
||||||
fDataBufferSize(0),
|
fDataBufferSize(0),
|
||||||
@@ -280,7 +330,7 @@ struct PackageContentExtractHandler : BPackageContentHandler {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t HandleEntry(BPackageEntry* entry)
|
virtual status_t HandleEntry(typename VersionPolicy::PackageEntry* entry)
|
||||||
{
|
{
|
||||||
// create a token
|
// create a token
|
||||||
Token* token = new(std::nothrow) Token;
|
Token* token = new(std::nothrow) Token;
|
||||||
@@ -385,7 +435,7 @@ struct PackageContentExtractHandler : BPackageContentHandler {
|
|||||||
|
|
||||||
// write data
|
// write data
|
||||||
status_t error;
|
status_t error;
|
||||||
const BPackageData& data = entry->Data();
|
const typename VersionPolicy::PackageData& data = entry->Data();
|
||||||
if (data.IsEncodedInline()) {
|
if (data.IsEncodedInline()) {
|
||||||
BBufferDataReader dataReader(data.InlineData(),
|
BBufferDataReader dataReader(data.InlineData(),
|
||||||
data.CompressedSize());
|
data.CompressedSize());
|
||||||
@@ -452,8 +502,9 @@ struct PackageContentExtractHandler : BPackageContentHandler {
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t HandleEntryAttribute(BPackageEntry* entry,
|
virtual status_t HandleEntryAttribute(
|
||||||
BPackageEntryAttribute* attribute)
|
typename VersionPolicy::PackageEntry* entry,
|
||||||
|
typename VersionPolicy::PackageEntryAttribute* attribute)
|
||||||
{
|
{
|
||||||
// don't write attributes of ignored or implicit entries
|
// don't write attributes of ignored or implicit entries
|
||||||
Token* token = (Token*)entry->UserToken();
|
Token* token = (Token*)entry->UserToken();
|
||||||
@@ -478,7 +529,7 @@ struct PackageContentExtractHandler : BPackageContentHandler {
|
|||||||
|
|
||||||
// write data
|
// write data
|
||||||
status_t error;
|
status_t error;
|
||||||
const BPackageData& data = attribute->Data();
|
const typename VersionPolicy::PackageData& data = attribute->Data();
|
||||||
if (data.IsEncodedInline()) {
|
if (data.IsEncodedInline()) {
|
||||||
BBufferDataReader dataReader(data.InlineData(),
|
BBufferDataReader dataReader(data.InlineData(),
|
||||||
data.CompressedSize());
|
data.CompressedSize());
|
||||||
@@ -491,7 +542,8 @@ struct PackageContentExtractHandler : BPackageContentHandler {
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t HandleEntryDone(BPackageEntry* entry)
|
virtual status_t HandleEntryDone(
|
||||||
|
typename VersionPolicy::PackageEntry* entry)
|
||||||
{
|
{
|
||||||
Token* token = (Token*)entry->UserToken();
|
Token* token = (Token*)entry->UserToken();
|
||||||
|
|
||||||
@@ -561,13 +613,13 @@ private:
|
|||||||
return Entry::Create(parentEntry, name.String(), implicit, _entry);
|
return Entry::Create(parentEntry, name.String(), implicit, _entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _GetParentFDAndEntryName(BPackageEntry* entry, int& _parentFD,
|
void _GetParentFDAndEntryName(typename VersionPolicy::PackageEntry* entry,
|
||||||
const char*& _entryName)
|
int& _parentFD, const char*& _entryName)
|
||||||
{
|
{
|
||||||
_entryName = entry->Name();
|
_entryName = entry->Name();
|
||||||
|
|
||||||
if (fInfoFileName != NULL
|
if (fInfoFileName != NULL
|
||||||
&& strcmp(_entryName, B_HPKG_PACKAGE_INFO_FILE_NAME) == 0) {
|
&& strcmp(_entryName, VersionPolicy::PackageInfoFileName()) == 0) {
|
||||||
_parentFD = AT_FDCWD;
|
_parentFD = AT_FDCWD;
|
||||||
_entryName = fInfoFileName;
|
_entryName = fInfoFileName;
|
||||||
} else {
|
} else {
|
||||||
@@ -576,11 +628,12 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BString _EntryPath(const BPackageEntry* entry)
|
BString _EntryPath(const typename VersionPolicy::PackageEntry* entry)
|
||||||
{
|
{
|
||||||
BString path;
|
BString path;
|
||||||
|
|
||||||
if (const BPackageEntry* parent = entry->Parent()) {
|
if (const typename VersionPolicy::PackageEntry* parent
|
||||||
|
= entry->Parent()) {
|
||||||
path = _EntryPath(parent);
|
path = _EntryPath(parent);
|
||||||
path << '/';
|
path << '/';
|
||||||
}
|
}
|
||||||
@@ -589,12 +642,13 @@ private:
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t _ExtractFileData(BDataReader* dataReader, const BPackageData& data,
|
status_t _ExtractFileData(BDataReader* dataReader,
|
||||||
int fd)
|
const typename VersionPolicy::PackageData& data, int fd)
|
||||||
{
|
{
|
||||||
// create a PackageDataReader
|
// create a PackageDataReader
|
||||||
BAbstractBufferedDataReader* reader;
|
BAbstractBufferedDataReader* reader;
|
||||||
status_t error = BPackageDataReaderFactory(&fBufferCache)
|
status_t error = typename VersionPolicy::PackageDataReaderFactory(
|
||||||
|
&fBufferCache)
|
||||||
.CreatePackageDataReader(dataReader, data, reader);
|
.CreatePackageDataReader(dataReader, data, reader);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
@@ -645,6 +699,83 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename VersionPolicy>
|
||||||
|
static void
|
||||||
|
do_extract(const char* packageFileName, const char* changeToDirectory,
|
||||||
|
const char* packageInfoFileName, const char* const* explicitEntries,
|
||||||
|
int explicitEntryCount, bool ignoreVersionError)
|
||||||
|
{
|
||||||
|
// open package
|
||||||
|
BStandardErrorOutput errorOutput;
|
||||||
|
typename VersionPolicy::PackageReader packageReader(&errorOutput);
|
||||||
|
status_t error = packageReader.Init(packageFileName);
|
||||||
|
if (error != B_OK) {
|
||||||
|
if (ignoreVersionError && error == B_MISMATCHED_VALUES)
|
||||||
|
return;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageContentExtractHandler<VersionPolicy> handler(
|
||||||
|
packageReader.PackageFileFD());
|
||||||
|
error = handler.Init();
|
||||||
|
if (error != B_OK)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
// If entries to extract have been specified explicitly, add those to the
|
||||||
|
// filtered ones.
|
||||||
|
if (explicitEntryCount > 0) {
|
||||||
|
for (int i = 0; i < explicitEntryCount; i++) {
|
||||||
|
const char* entryName = explicitEntries[i];
|
||||||
|
if (entryName[0] == '\0' || entryName[0] == '/') {
|
||||||
|
fprintf(stderr, "Error: Invalid entry name: \"%s\".",
|
||||||
|
entryName);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handler.AddFilterEntry(entryName) != B_OK)
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
handler.SetExtractAll();
|
||||||
|
|
||||||
|
// get the target directory, if requested
|
||||||
|
if (changeToDirectory != NULL) {
|
||||||
|
int currentDirFD = open(changeToDirectory, O_RDONLY);
|
||||||
|
if (currentDirFD < 0) {
|
||||||
|
fprintf(stderr, "Error: Failed to change the current working "
|
||||||
|
"directory to \"%s\": %s\n", changeToDirectory,
|
||||||
|
strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.SetBaseDirectory(currentDirFD);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a package info file name is given, set it.
|
||||||
|
if (packageInfoFileName != NULL)
|
||||||
|
handler.SetPackageInfoFile(packageInfoFileName);
|
||||||
|
|
||||||
|
// extract
|
||||||
|
error = packageReader.ParseContent(&handler);
|
||||||
|
if (error != B_OK)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
// check whether all explicitly specified entries have been extracted
|
||||||
|
if (explicitEntryCount > 0) {
|
||||||
|
for (int i = 0; i < explicitEntryCount; i++) {
|
||||||
|
if (Entry* entry = handler.FindFilterEntry(explicitEntries[i])) {
|
||||||
|
if (!entry->Seen()) {
|
||||||
|
fprintf(stderr, "Warning: Entry \"%s\" not found.\n",
|
||||||
|
explicitEntries[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
command_extract(int argc, const char* const* argv)
|
command_extract(int argc, const char* const* argv)
|
||||||
{
|
{
|
||||||
@@ -681,75 +812,19 @@ command_extract(int argc, const char* const* argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// At least one argument should remain -- the package file name.
|
// At least one argument should remain -- the package file name. Any further
|
||||||
|
// arguments are the names of the entries to extract.
|
||||||
if (optind + 1 > argc)
|
if (optind + 1 > argc)
|
||||||
print_usage_and_exit(true);
|
print_usage_and_exit(true);
|
||||||
|
|
||||||
const char* packageFileName = argv[optind++];
|
const char* packageFileName = argv[optind++];
|
||||||
|
const char* const* explicitEntries = argv + optind;
|
||||||
|
int explicitEntryCount = argc - optind;
|
||||||
|
|
||||||
// open package
|
do_extract<VersionPolicyV2>(packageFileName, changeToDirectory,
|
||||||
BStandardErrorOutput errorOutput;
|
packageInfoFileName, explicitEntries, explicitEntryCount, true);
|
||||||
BPackageReader packageReader(&errorOutput);
|
do_extract<VersionPolicyV1>(packageFileName, changeToDirectory,
|
||||||
status_t error = packageReader.Init(packageFileName);
|
packageInfoFileName, explicitEntries, explicitEntryCount, false);
|
||||||
if (error != B_OK)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
PackageContentExtractHandler handler(packageReader.PackageFileFD());
|
|
||||||
error = handler.Init();
|
|
||||||
if (error != B_OK)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
// If entries to extract have been specified explicitly, add those to the
|
|
||||||
// filtered ones.
|
|
||||||
int explicitEntriesIndex = optind;
|
|
||||||
if (optind < argc) {
|
|
||||||
while (optind < argc) {
|
|
||||||
const char* entryName = argv[optind++];
|
|
||||||
if (entryName[0] == '\0' || entryName[0] == '/') {
|
|
||||||
fprintf(stderr, "Error: Invalid entry name: \"%s\".",
|
|
||||||
entryName);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler.AddFilterEntry(entryName) != B_OK)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
handler.SetExtractAll();
|
|
||||||
|
|
||||||
// get the target directory, if requested
|
|
||||||
if (changeToDirectory != NULL) {
|
|
||||||
int currentDirFD = open(changeToDirectory, O_RDONLY);
|
|
||||||
if (currentDirFD < 0) {
|
|
||||||
fprintf(stderr, "Error: Failed to change the current working "
|
|
||||||
"directory to \"%s\": %s\n", changeToDirectory,
|
|
||||||
strerror(errno));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.SetBaseDirectory(currentDirFD);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a package info file name is given, set it.
|
|
||||||
if (packageInfoFileName != NULL)
|
|
||||||
handler.SetPackageInfoFile(packageInfoFileName);
|
|
||||||
|
|
||||||
// extract
|
|
||||||
error = packageReader.ParseContent(&handler);
|
|
||||||
if (error != B_OK)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
// check whether all explicitly specified entries have been extracted
|
|
||||||
if (explicitEntriesIndex < argc) {
|
|
||||||
for (int i = explicitEntriesIndex; i < argc; i++) {
|
|
||||||
if (Entry* entry = handler.FindFilterEntry(argv[i])) {
|
|
||||||
if (!entry->Seen()) {
|
|
||||||
fprintf(stderr, "Warning: Entry \"%s\" not found.\n",
|
|
||||||
argv[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009-2011, Ingo Weinhold, [email protected].
|
* Copyright 2009-2013, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -18,17 +18,39 @@
|
|||||||
#include <package/hpkg/PackageInfoAttributeValue.h>
|
#include <package/hpkg/PackageInfoAttributeValue.h>
|
||||||
#include <package/hpkg/PackageReader.h>
|
#include <package/hpkg/PackageReader.h>
|
||||||
#include <package/hpkg/StandardErrorOutput.h>
|
#include <package/hpkg/StandardErrorOutput.h>
|
||||||
|
#include <package/hpkg/v1/PackageContentHandler.h>
|
||||||
|
#include <package/hpkg/v1/PackageEntry.h>
|
||||||
|
#include <package/hpkg/v1/PackageEntryAttribute.h>
|
||||||
|
#include <package/hpkg/v1//PackageReader.h>
|
||||||
|
|
||||||
#include <package/PackageInfo.h>
|
#include <package/PackageInfo.h>
|
||||||
|
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace BPackageKit::BHPKG;
|
|
||||||
using namespace BPackageKit;
|
using namespace BPackageKit;
|
||||||
|
using BPackageKit::BHPKG::BPackageInfoAttributeValue;
|
||||||
|
|
||||||
|
|
||||||
struct PackageContentListHandler : BPackageContentHandler {
|
struct VersionPolicyV1 {
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageContentHandler
|
||||||
|
PackageContentHandler;
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageEntry PackageEntry;
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageEntryAttribute
|
||||||
|
PackageEntryAttribute;
|
||||||
|
typedef BPackageKit::BHPKG::V1::BPackageReader PackageReader;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VersionPolicyV2 {
|
||||||
|
typedef BPackageKit::BHPKG::BPackageContentHandler PackageContentHandler;
|
||||||
|
typedef BPackageKit::BHPKG::BPackageEntry PackageEntry;
|
||||||
|
typedef BPackageKit::BHPKG::BPackageEntryAttribute PackageEntryAttribute;
|
||||||
|
typedef BPackageKit::BHPKG::BPackageReader PackageReader;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename VersionPolicy>
|
||||||
|
struct PackageContentListHandler : VersionPolicy::PackageContentHandler {
|
||||||
PackageContentListHandler(bool listAttributes)
|
PackageContentListHandler(bool listAttributes)
|
||||||
:
|
:
|
||||||
fLevel(0),
|
fLevel(0),
|
||||||
@@ -36,7 +58,7 @@ struct PackageContentListHandler : BPackageContentHandler {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t HandleEntry(BPackageEntry* entry)
|
virtual status_t HandleEntry(typename VersionPolicy::PackageEntry* entry)
|
||||||
{
|
{
|
||||||
fLevel++;
|
fLevel++;
|
||||||
|
|
||||||
@@ -80,8 +102,9 @@ struct PackageContentListHandler : BPackageContentHandler {
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t HandleEntryAttribute(BPackageEntry* entry,
|
virtual status_t HandleEntryAttribute(
|
||||||
BPackageEntryAttribute* attribute)
|
typename VersionPolicy::PackageEntry* entry,
|
||||||
|
typename VersionPolicy::PackageEntryAttribute* attribute)
|
||||||
{
|
{
|
||||||
if (!fListAttribute)
|
if (!fListAttribute)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -104,7 +127,8 @@ struct PackageContentListHandler : BPackageContentHandler {
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t HandleEntryDone(BPackageEntry* entry)
|
virtual status_t HandleEntryDone(
|
||||||
|
typename VersionPolicy::PackageEntry* entry)
|
||||||
{
|
{
|
||||||
fLevel--;
|
fLevel--;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -274,27 +298,30 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct PackageContentListPathsHandler : BPackageContentHandler {
|
template<typename VersionPolicy>
|
||||||
|
struct PackageContentListPathsHandler : VersionPolicy::PackageContentHandler {
|
||||||
PackageContentListPathsHandler()
|
PackageContentListPathsHandler()
|
||||||
:
|
:
|
||||||
fPathComponents()
|
fPathComponents()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t HandleEntry(BPackageEntry* entry)
|
virtual status_t HandleEntry(typename VersionPolicy::PackageEntry* entry)
|
||||||
{
|
{
|
||||||
fPathComponents.Add(entry->Name());
|
fPathComponents.Add(entry->Name());
|
||||||
printf("%s\n", fPathComponents.Join("/").String());
|
printf("%s\n", fPathComponents.Join("/").String());
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t HandleEntryAttribute(BPackageEntry* entry,
|
virtual status_t HandleEntryAttribute(
|
||||||
BPackageEntryAttribute* attribute)
|
typename VersionPolicy::PackageEntry* entry,
|
||||||
|
typename VersionPolicy::PackageEntryAttribute* attribute)
|
||||||
{
|
{
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t HandleEntryDone(BPackageEntry* entry)
|
virtual status_t HandleEntryDone(
|
||||||
|
typename VersionPolicy::PackageEntry* entry)
|
||||||
{
|
{
|
||||||
fPathComponents.Remove(fPathComponents.CountStrings() - 1);
|
fPathComponents.Remove(fPathComponents.CountStrings() - 1);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -315,6 +342,36 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename VersionPolicy>
|
||||||
|
static void
|
||||||
|
do_list(const char* packageFileName, bool listAttributes, bool filePathsOnly,
|
||||||
|
bool ignoreVersionError)
|
||||||
|
{
|
||||||
|
// open package
|
||||||
|
BHPKG::BStandardErrorOutput errorOutput;
|
||||||
|
typename VersionPolicy::PackageReader packageReader(&errorOutput);
|
||||||
|
status_t error = packageReader.Init(packageFileName);
|
||||||
|
if (error != B_OK) {
|
||||||
|
if (ignoreVersionError && error == B_MISMATCHED_VALUES)
|
||||||
|
return;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// list
|
||||||
|
if (filePathsOnly) {
|
||||||
|
PackageContentListPathsHandler<VersionPolicy> handler;
|
||||||
|
error = packageReader.ParseContent(&handler);
|
||||||
|
} else {
|
||||||
|
PackageContentListHandler<VersionPolicy> handler(listAttributes);
|
||||||
|
error = packageReader.ParseContent(&handler);
|
||||||
|
}
|
||||||
|
if (error != B_OK)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
command_list(int argc, const char* const* argv)
|
command_list(int argc, const char* const* argv)
|
||||||
{
|
{
|
||||||
@@ -357,23 +414,13 @@ command_list(int argc, const char* const* argv)
|
|||||||
|
|
||||||
const char* packageFileName = argv[optind++];
|
const char* packageFileName = argv[optind++];
|
||||||
|
|
||||||
// open package
|
BHPKG::BStandardErrorOutput errorOutput;
|
||||||
BStandardErrorOutput errorOutput;
|
|
||||||
BPackageReader packageReader(&errorOutput);
|
|
||||||
status_t error = packageReader.Init(packageFileName);
|
|
||||||
if (error != B_OK)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
// list
|
// current package file format version
|
||||||
if (filePathsOnly) {
|
do_list<VersionPolicyV2>(packageFileName, listAttributes, filePathsOnly,
|
||||||
PackageContentListPathsHandler handler;
|
true);
|
||||||
error = packageReader.ParseContent(&handler);
|
do_list<VersionPolicyV1>(packageFileName, listAttributes, filePathsOnly,
|
||||||
} else {
|
false);
|
||||||
PackageContentListHandler handler(listAttributes);
|
|
||||||
error = packageReader.ParseContent(&handler);
|
|
||||||
}
|
|
||||||
if (error != B_OK)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user