Implemented repository writing:
* fleshed out RepositoryWriterImpl * renamed BRepositoryHeader to BRepositoryInfo (in accordance with BPackageInfo) * adjusted BRepositoryInfo to be able to parse itself from a driver_settings file * added package_repo binary (only 'create' works as of yet) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40405 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
78a471321c
commit
0d68f6afb3
|
@ -55,6 +55,7 @@ public:
|
|||
const BString& Description() const;
|
||||
const BString& Vendor() const;
|
||||
const BString& Packager() const;
|
||||
const BString& Checksum() const;
|
||||
|
||||
uint32 Flags() const;
|
||||
|
||||
|
@ -81,6 +82,7 @@ public:
|
|||
void SetDescription(const BString& description);
|
||||
void SetVendor(const BString& vendor);
|
||||
void SetPackager(const BString& packager);
|
||||
void SetChecksum(const BString& checksum);
|
||||
|
||||
void SetFlags(uint32 flags);
|
||||
|
||||
|
@ -120,6 +122,9 @@ public:
|
|||
void Clear();
|
||||
|
||||
public:
|
||||
static status_t GetArchitectureByName(const BString& name,
|
||||
BPackageArchitecture& _architecture);
|
||||
|
||||
static const char* kElementNames[];
|
||||
static const char* kArchitectureNames[];
|
||||
|
||||
|
@ -152,6 +157,8 @@ private:
|
|||
BObjectList<BPackageResolvableExpression> fFreshensList;
|
||||
|
||||
BObjectList<BString> fReplacesList;
|
||||
|
||||
BString fChecksum;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ enum BPackageInfoAttributeIndex {
|
|||
B_PACKAGE_INFO_REPLACES, // list of resolvables that this package
|
||||
// will replace (upon update)
|
||||
B_PACKAGE_INFO_FLAGS,
|
||||
B_PACKAGE_INFO_CHECKSUM, // sha256-checksum
|
||||
//
|
||||
B_PACKAGE_INFO_ENUM_COUNT,
|
||||
};
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
namespace BPackageKit {
|
||||
|
||||
|
||||
namespace BHPKG {
|
||||
class BPackageResolvableData;
|
||||
}
|
||||
using BHPKG::BPackageResolvableData;
|
||||
|
||||
|
||||
/*
|
||||
* Defines a resolvable (something other packages can depend upon).
|
||||
* Each resolvable is defined as a name (with an optional type prefix)
|
||||
|
@ -39,6 +45,8 @@ namespace BPackageKit {
|
|||
class BPackageResolvable {
|
||||
public:
|
||||
BPackageResolvable();
|
||||
BPackageResolvable(
|
||||
const BPackageResolvableData& data);
|
||||
BPackageResolvable(const BString& name,
|
||||
BPackageResolvableType type
|
||||
= B_PACKAGE_RESOLVABLE_TYPE_DEFAULT,
|
||||
|
|
|
@ -15,6 +15,12 @@
|
|||
namespace BPackageKit {
|
||||
|
||||
|
||||
namespace BHPKG {
|
||||
class BPackageResolvableExpressionData;
|
||||
}
|
||||
using BHPKG::BPackageResolvableExpressionData;
|
||||
|
||||
|
||||
/*
|
||||
* Expresses a constraint on a specific resolvable, either just a name
|
||||
* or a name plus a relational operator and a version.
|
||||
|
@ -33,6 +39,9 @@ namespace BPackageKit {
|
|||
class BPackageResolvableExpression {
|
||||
public:
|
||||
BPackageResolvableExpression();
|
||||
BPackageResolvableExpression(
|
||||
const BPackageResolvableExpressionData& data
|
||||
);
|
||||
BPackageResolvableExpression(
|
||||
const BString& name,
|
||||
BPackageResolvableOperator _op
|
||||
|
|
|
@ -12,9 +12,17 @@
|
|||
namespace BPackageKit {
|
||||
|
||||
|
||||
namespace BHPKG {
|
||||
class BPackageVersionData;
|
||||
}
|
||||
using BHPKG::BPackageVersionData;
|
||||
|
||||
|
||||
class BPackageVersion {
|
||||
public:
|
||||
BPackageVersion();
|
||||
BPackageVersion(
|
||||
const BPackageVersionData& data);
|
||||
BPackageVersion(const BString& major,
|
||||
const BString& minor, const BString& micro,
|
||||
uint8 release);
|
||||
|
|
|
@ -9,15 +9,12 @@
|
|||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/RepositoryHeader.h>
|
||||
#include <package/RepositoryInfo.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
//class RepositoryHeader;
|
||||
|
||||
|
||||
class BRepositoryCache {
|
||||
public:
|
||||
BRepositoryCache();
|
||||
|
@ -27,7 +24,7 @@ public:
|
|||
status_t SetTo(const BEntry& entry);
|
||||
status_t InitCheck() const;
|
||||
|
||||
const BRepositoryHeader& Header() const;
|
||||
const BRepositoryInfo& Info() const;
|
||||
const BEntry& Entry() const;
|
||||
bool IsUserSpecific() const;
|
||||
|
||||
|
@ -37,7 +34,7 @@ private:
|
|||
status_t fInitStatus;
|
||||
|
||||
BEntry fEntry;
|
||||
BRepositoryHeader fHeader;
|
||||
BRepositoryInfo fInfo;
|
||||
bool fIsUserSpecific;
|
||||
};
|
||||
|
||||
|
|
|
@ -2,55 +2,60 @@
|
|||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PACKAGE__REPOSITORY_HEADER_H_
|
||||
#define _PACKAGE__REPOSITORY_HEADER_H_
|
||||
#ifndef _PACKAGE__REPOSITORY_INFO_H_
|
||||
#define _PACKAGE__REPOSITORY_INFO_H_
|
||||
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/PackageArchitecture.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
class BRepositoryHeader : public BArchivable {
|
||||
class BRepositoryInfo : public BArchivable {
|
||||
typedef BArchivable inherited;
|
||||
|
||||
public:
|
||||
BRepositoryHeader();
|
||||
BRepositoryHeader(BMessage* data);
|
||||
virtual ~BRepositoryHeader();
|
||||
BRepositoryInfo();
|
||||
BRepositoryInfo(BMessage* data);
|
||||
BRepositoryInfo(const BEntry& entry);
|
||||
virtual ~BRepositoryInfo();
|
||||
|
||||
virtual status_t Archive(BMessage* data, bool deep = true) const;
|
||||
|
||||
status_t SetTo(const BMessage* data);
|
||||
status_t SetTo(const BEntry& entry);
|
||||
status_t InitCheck() const;
|
||||
|
||||
const BString& Name() const;
|
||||
const BString& OriginalBaseURL() const;
|
||||
const BString& Vendor() const;
|
||||
const BString& ShortDescription() const;
|
||||
const BString& LongDescription() const;
|
||||
const BString& Summary() const;
|
||||
uint8 Priority() const;
|
||||
BPackageArchitecture Architecture() const;
|
||||
|
||||
void SetName(const BString& name);
|
||||
void SetOriginalBaseURL(const BString& url);
|
||||
void SetVendor(const BString& vendor);
|
||||
void SetShortDescription(const BString& description);
|
||||
void SetLongDescription(const BString& description);
|
||||
void SetSummary(const BString& summary);
|
||||
void SetPriority(uint8 priority);
|
||||
void SetArchitecture(BPackageArchitecture arch);
|
||||
|
||||
public:
|
||||
static BRepositoryHeader* Instantiate(BMessage* data);
|
||||
static BRepositoryInfo* Instantiate(BMessage* data);
|
||||
|
||||
static const uint8 kDefaultPriority;
|
||||
|
||||
static const char* kNameField;
|
||||
static const char* kURLField;
|
||||
static const char* kVendorField;
|
||||
static const char* kShortDescriptionField;
|
||||
static const char* kLongDescriptionField;
|
||||
static const char* kSummaryField;
|
||||
static const char* kPriorityField;
|
||||
static const char* kArchitectureField;
|
||||
|
||||
private:
|
||||
status_t fInitStatus;
|
||||
|
@ -58,13 +63,13 @@ private:
|
|||
BString fName;
|
||||
BString fOriginalBaseURL;
|
||||
BString fVendor;
|
||||
BString fShortDescription;
|
||||
BString fLongDescription;
|
||||
BString fSummary;
|
||||
uint8 fPriority;
|
||||
BPackageArchitecture fArchitecture;
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
||||
|
||||
#endif // _PACKAGE__REPOSITORY_HEADER_H_
|
||||
#endif // _PACKAGE__REPOSITORY_INFO_H_
|
|
@ -47,6 +47,7 @@ public:
|
|||
virtual status_t HandlePackageAttribute(
|
||||
const BPackageInfoAttributeValue& value
|
||||
) = 0;
|
||||
virtual status_t HandlePackageAttributesDone() = 0;
|
||||
|
||||
virtual void HandleErrorOccurred() = 0;
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace BPackageKit {
|
|||
|
||||
|
||||
class BPackageInfo;
|
||||
class BRepositoryInfo;
|
||||
|
||||
|
||||
namespace BHPKG {
|
||||
|
@ -38,6 +39,8 @@ public:
|
|||
virtual void OnPackageAttributesSizeInfo(uint32 stringCount,
|
||||
uint32 uncompressedSize) = 0;
|
||||
virtual void OnRepositorySizeInfo(uint32 headerSize,
|
||||
uint32 repositoryInfoLength,
|
||||
uint32 packageCount,
|
||||
uint32 packageAttributesSize,
|
||||
uint64 totalSize) = 0;
|
||||
};
|
||||
|
@ -47,7 +50,8 @@ class BRepositoryWriter {
|
|||
public:
|
||||
public:
|
||||
BRepositoryWriter(
|
||||
BRepositoryWriterListener* listener);
|
||||
BRepositoryWriterListener* listener,
|
||||
const BRepositoryInfo* repositoryInfo);
|
||||
~BRepositoryWriter();
|
||||
|
||||
status_t Init(const char* fileName);
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
ActivateRepositoryConfigJob(
|
||||
const BContext& context,
|
||||
const BString& title,
|
||||
const BEntry& archivedRepoHeaderEntry,
|
||||
const BEntry& archivedRepoInfoEntry,
|
||||
const BString& repositoryBaseURL,
|
||||
const BDirectory& targetDirectory);
|
||||
virtual ~ActivateRepositoryConfigJob();
|
||||
|
@ -37,7 +37,7 @@ protected:
|
|||
virtual void Cleanup(status_t jobResult);
|
||||
|
||||
private:
|
||||
BEntry fArchivedRepoHeaderEntry;
|
||||
BEntry fArchivedRepoInfoEntry;
|
||||
BString fRepositoryBaseURL;
|
||||
BDirectory fTargetDirectory;
|
||||
BEntry fTargetEntry;
|
||||
|
|
|
@ -8,17 +8,21 @@
|
|||
|
||||
#include <Entry.h>
|
||||
|
||||
#include <package/hpkg/PackageContentHandler.h>
|
||||
#include <package/hpkg/RepositoryWriter.h>
|
||||
#include <package/hpkg/WriterImplBase.h>
|
||||
#include <package/PackageInfo.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
namespace BHPKG {
|
||||
|
||||
|
||||
class BDataReader;
|
||||
class BErrorOutput;
|
||||
class BPackageEntry;
|
||||
class BPackageEntryAttribute;
|
||||
class BPackageInfoAttributeValue;
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
@ -26,26 +30,54 @@ namespace BPrivate {
|
|||
|
||||
struct hpkg_header;
|
||||
|
||||
class RepositoryWriterImpl : public WriterImplBase {
|
||||
class RepositoryWriterImpl
|
||||
: public WriterImplBase, private BPackageContentHandler {
|
||||
public:
|
||||
RepositoryWriterImpl(
|
||||
BRepositoryWriterListener* listener);
|
||||
BRepositoryWriterListener* listener,
|
||||
const BRepositoryInfo* repositoryInfo);
|
||||
~RepositoryWriterImpl();
|
||||
|
||||
status_t Init(const char* fileName);
|
||||
status_t AddPackage(const BEntry& packageEntry);
|
||||
status_t Finish();
|
||||
|
||||
private:
|
||||
// BPackageContentHandler
|
||||
virtual status_t HandleEntry(BPackageEntry* entry);
|
||||
virtual status_t HandleEntryAttribute(BPackageEntry* entry,
|
||||
BPackageEntryAttribute* attribute);
|
||||
virtual status_t HandleEntryDone(BPackageEntry* entry);
|
||||
|
||||
virtual status_t HandlePackageAttribute(
|
||||
const BPackageInfoAttributeValue& value
|
||||
);
|
||||
virtual status_t HandlePackageAttributesDone();
|
||||
|
||||
virtual void HandleErrorOccurred();
|
||||
|
||||
private:
|
||||
status_t _Init(const char* fileName);
|
||||
status_t _AddPackage(const BEntry& packageEntry);
|
||||
status_t _Finish();
|
||||
|
||||
status_t _RegisterCurrentPackageInfo();
|
||||
status_t _WriteRepositoryInfo(
|
||||
ssize_t& _repositoryInfoLength);
|
||||
off_t _WritePackageAttributes(
|
||||
hpkg_repo_header& header);
|
||||
hpkg_repo_header& header,
|
||||
off_t startOffset);
|
||||
|
||||
struct PackageNameSet;
|
||||
|
||||
private:
|
||||
BRepositoryWriterListener* fListener;
|
||||
|
||||
const BRepositoryInfo* fRepositoryInfo;
|
||||
|
||||
BPackageInfo fPackageInfo;
|
||||
uint32 fPackageCount;
|
||||
PackageNameSet* fPackageNames;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,9 @@ struct hpkg_repo_header {
|
|||
uint16 version;
|
||||
uint64 total_size;
|
||||
|
||||
// repository header
|
||||
uint32 repository_header_length;
|
||||
|
||||
// package attributes section
|
||||
uint32 attributes_compression;
|
||||
uint32 attributes_length_compressed;
|
||||
|
|
|
@ -264,6 +264,12 @@ struct Volume::PackageLoaderContentHandler : BPackageContentHandler {
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandlePackageAttributesDone()
|
||||
{
|
||||
// TODO!
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual void HandleErrorOccurred()
|
||||
{
|
||||
fErrorOccurred = true;
|
||||
|
|
|
@ -255,6 +255,7 @@ SubInclude HAIKU_TOP src bin mkdos ;
|
|||
SubInclude HAIKU_TOP src bin mkfs ;
|
||||
SubInclude HAIKU_TOP src bin multiuser ;
|
||||
SubInclude HAIKU_TOP src bin package ;
|
||||
SubInclude HAIKU_TOP src bin package_repo ;
|
||||
SubInclude HAIKU_TOP src bin patch ;
|
||||
SubInclude HAIKU_TOP src bin pc ;
|
||||
SubInclude HAIKU_TOP src bin pcmcia-cs ;
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
printf("TOC size: %10llu\n", tocSize);
|
||||
printf("package attributes size: %10lu\n", packageAttributesSize);
|
||||
printf("total size: %10llu\n", totalSize);
|
||||
|
||||
printf("-----------------------------------\n");
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -229,6 +229,11 @@ struct PackageContentExtractHandler : BPackageContentHandler {
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandlePackageAttributesDone()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual void HandleErrorOccurred()
|
||||
{
|
||||
fErrorOccurred = true;
|
||||
|
|
|
@ -144,7 +144,7 @@ struct PackageContentListHandler : BPackageContentHandler {
|
|||
break;
|
||||
|
||||
case B_PACKAGE_INFO_ARCHITECTURE:
|
||||
printf("\tarchitecure: %s\n",
|
||||
printf("\tarchitecture: %s\n",
|
||||
BPackageInfo::kArchitectureNames[value.unsignedInt]);
|
||||
break;
|
||||
|
||||
|
@ -226,6 +226,11 @@ struct PackageContentListHandler : BPackageContentHandler {
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandlePackageAttributesDone()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual void HandleErrorOccurred()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <package/hpkg/PackageWriter.h>
|
||||
|
||||
|
||||
extern const char* __progname;
|
||||
const char* kCommandName = __progname;
|
||||
|
@ -28,7 +26,9 @@ static const char* kUsage =
|
|||
" create [ <options> ] <package>\n"
|
||||
" Creates package file <package> from contents of current directory.\n"
|
||||
"\n"
|
||||
" -C <dir> - Change to directory <dir> before starting.\n"
|
||||
" -C <dir> - Change to directory <dir> before starting.\n"
|
||||
" -q - be quiet (don't show any output except for errors).\n"
|
||||
" -v - be verbose (show more info about created package).\n"
|
||||
"\n"
|
||||
" dump [ <options> ] <package>\n"
|
||||
" Dumps the TOC section of package file <package>. For debugging only.\n"
|
||||
|
@ -36,7 +36,7 @@ static const char* kUsage =
|
|||
" extract [ <options> ] <package>\n"
|
||||
" Extracts the contents of package file <package>.\n"
|
||||
"\n"
|
||||
" -C <dir> - Change to directory <dir> before extracting the "
|
||||
" -C <dir> - Change to directory <dir> before extracting the "
|
||||
"contents\n"
|
||||
" of the archive.\n"
|
||||
"\n"
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
SubDir HAIKU_TOP src bin package_repo ;
|
||||
|
||||
UsePrivateHeaders kernel shared ;
|
||||
|
||||
DEFINES += B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT ;
|
||||
# TODO: Remove when it is complete!
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src bin package ] ;
|
||||
|
||||
BinCommand package_repo :
|
||||
BlockBufferCacheNoLock.cpp
|
||||
command_create.cpp
|
||||
command_list.cpp
|
||||
package_repo.cpp
|
||||
StandardErrorOutput.cpp
|
||||
:
|
||||
package be
|
||||
$(TARGET_LIBSUPC++)
|
||||
;
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <package/hpkg/HPKGDefs.h>
|
||||
#include <package/hpkg/RepositoryWriter.h>
|
||||
#include <package/PackageInfo.h>
|
||||
#include <package/RepositoryInfo.h>
|
||||
|
||||
#include "package.h"
|
||||
#include "StandardErrorOutput.h"
|
||||
|
||||
|
||||
using BPackageKit::BHPKG::BRepositoryWriterListener;
|
||||
using BPackageKit::BHPKG::BRepositoryWriter;
|
||||
using namespace BPackageKit;
|
||||
|
||||
|
||||
class RepositoryWriterListener : public BRepositoryWriterListener {
|
||||
public:
|
||||
RepositoryWriterListener(bool verbose, bool quiet)
|
||||
: fVerbose(verbose), fQuiet(quiet)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void PrintErrorVarArgs(const char* format, va_list args)
|
||||
{
|
||||
vfprintf(stderr, format, args);
|
||||
}
|
||||
|
||||
virtual void OnPackageAdded(const BPackageInfo& packageInfo)
|
||||
{
|
||||
if (fQuiet)
|
||||
return;
|
||||
|
||||
printf("%s (%s)\n", packageInfo.Name().String(),
|
||||
packageInfo.Version().ToString().String());
|
||||
if (fVerbose) {
|
||||
printf("\tsummary: %s\n", packageInfo.Summary().String());
|
||||
printf("\tvendor: %s\n", packageInfo.Vendor().String());
|
||||
printf("\tpackager: %s\n", packageInfo.Packager().String());
|
||||
if (uint32 flags = packageInfo.Flags()) {
|
||||
printf("\tflags:\n");
|
||||
if ((flags & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0)
|
||||
printf("\t\tapprove_license\n");
|
||||
if ((flags & B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0)
|
||||
printf("\t\tsystem_package\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnPackageAttributesSizeInfo(uint32 stringCount,
|
||||
uint32 uncompressedSize)
|
||||
{
|
||||
if (fQuiet || !fVerbose)
|
||||
return;
|
||||
|
||||
printf("----- Package Attribute Info ---------------------\n");
|
||||
printf("string count: %10lu\n", stringCount);
|
||||
printf("package attributes size: %10lu (uncompressed)\n",
|
||||
uncompressedSize);
|
||||
}
|
||||
|
||||
virtual void OnRepositorySizeInfo(uint32 headerSize,
|
||||
uint32 repositoryInfoSize, uint32 packageCount,
|
||||
uint32 packageAttributesSize, uint64 totalSize)
|
||||
{
|
||||
if (fQuiet)
|
||||
return;
|
||||
|
||||
printf("----- Package Repository Info -----\n");
|
||||
printf("package count %10lu\n", packageCount);
|
||||
printf("-----------------------------------\n");
|
||||
printf("header size: %10lu\n", headerSize);
|
||||
printf("repository header size: %10lu\n", repositoryInfoSize);
|
||||
printf("package attributes size: %10lu\n", packageAttributesSize);
|
||||
printf("total size: %10llu\n", totalSize);
|
||||
printf("-----------------------------------\n");
|
||||
}
|
||||
|
||||
private:
|
||||
bool fVerbose;
|
||||
bool fQuiet;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
command_create(int argc, const char* const* argv)
|
||||
{
|
||||
const char* changeToDirectory = NULL;
|
||||
bool quiet = false;
|
||||
bool verbose = false;
|
||||
|
||||
while (true) {
|
||||
static struct option sLongOptions[] = {
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "quiet", no_argument, 0, 'q' },
|
||||
{ "verbose", no_argument, 0, 'v' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
opterr = 0; // don't print errors
|
||||
int c = getopt_long(argc, (char**)argv, "+C:hqv", sLongOptions, NULL);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'C':
|
||||
changeToDirectory = optarg;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_usage_and_exit(false);
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
quiet = true;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
print_usage_and_exit(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The remaining arguments are the repository info file plus one or more
|
||||
// package files, i.e. at least two more arguments.
|
||||
if (optind + 2 >= argc)
|
||||
print_usage_and_exit(true);
|
||||
|
||||
const char* repositoryInfoFileName = argv[optind++];
|
||||
const char* const* packageFileNames = argv + optind;
|
||||
|
||||
RepositoryWriterListener listener(verbose, quiet);
|
||||
|
||||
BEntry repositoryInfoEntry(repositoryInfoFileName);
|
||||
if (!repositoryInfoEntry.Exists()) {
|
||||
listener.PrintError(
|
||||
"Error: given repository-info file '%s' doesn't exist!\n",
|
||||
repositoryInfoFileName);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// determine path for 'repo' file from given info file
|
||||
BEntry repositoryParentEntry;
|
||||
repositoryInfoEntry.GetParent(&repositoryParentEntry);
|
||||
BPath repositoryPath;
|
||||
if (repositoryParentEntry.GetPath(&repositoryPath) != B_OK) {
|
||||
listener.PrintError(
|
||||
"Error: can't determine path of given repository-info file!\n");
|
||||
return 1;
|
||||
}
|
||||
repositoryPath.Append("repo");
|
||||
|
||||
// create repository
|
||||
BRepositoryInfo repositoryInfo(repositoryInfoEntry);
|
||||
status_t result = repositoryInfo.InitCheck();
|
||||
if (result != B_OK) {
|
||||
listener.PrintError(
|
||||
"Error: can't parse given repository-info file : %s\n",
|
||||
strerror(result));
|
||||
return 1;
|
||||
}
|
||||
BRepositoryWriter repositoryWriter(&listener, &repositoryInfo);
|
||||
if ((result = repositoryWriter.Init(repositoryPath.Path())) != B_OK) {
|
||||
listener.PrintError("Error: can't initialize repository-writer : %s\n",
|
||||
strerror(result));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// change directory, if requested
|
||||
if (changeToDirectory != NULL) {
|
||||
if (chdir(changeToDirectory) != 0) {
|
||||
listener.PrintError(
|
||||
"Error: Failed to change the current working directory to "
|
||||
"\"%s\": %s\n", changeToDirectory, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// add all given package files
|
||||
for (int i = 0; i < argc - optind; ++i) {
|
||||
if (verbose)
|
||||
printf("reading package '%s' ...\n", packageFileNames[i]);
|
||||
BEntry entry(packageFileNames[i]);
|
||||
result = repositoryWriter.AddPackage(entry);
|
||||
if (result != B_OK)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// write the repository
|
||||
result = repositoryWriter.Finish();
|
||||
if (result != B_OK)
|
||||
return 1;
|
||||
|
||||
if (verbose) {
|
||||
printf("\nsuccessfully created repository '%s'\n",
|
||||
repositoryPath.Path());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <package/hpkg/PackageContentHandler.h>
|
||||
#include <package/hpkg/PackageEntry.h>
|
||||
#include <package/hpkg/PackageEntryAttribute.h>
|
||||
#include <package/hpkg/PackageInfoAttributeValue.h>
|
||||
#include <package/hpkg/PackageReader.h>
|
||||
|
||||
#include <package/PackageInfo.h>
|
||||
|
||||
#include "package.h"
|
||||
#include "StandardErrorOutput.h"
|
||||
|
||||
|
||||
using namespace BPackageKit::BHPKG;
|
||||
using namespace BPackageKit;
|
||||
|
||||
|
||||
struct PackageContentListHandler : BPackageContentHandler {
|
||||
PackageContentListHandler(bool listAttributes)
|
||||
:
|
||||
fLevel(0),
|
||||
fListAttribute(listAttributes)
|
||||
{
|
||||
}
|
||||
|
||||
virtual status_t HandleEntry(BPackageEntry* entry)
|
||||
{
|
||||
fLevel++;
|
||||
|
||||
int indentation = (fLevel - 1) * 2;
|
||||
printf("%*s", indentation, "");
|
||||
|
||||
// name and size
|
||||
printf("%-*s", indentation < 32 ? 32 - indentation : 0, entry->Name());
|
||||
printf(" %8llu", entry->Data().UncompressedSize());
|
||||
|
||||
// time
|
||||
struct tm* time = localtime(&entry->ModifiedTime().tv_sec);
|
||||
printf(" %04d-%02d-%02d %02d:%02d:%02d",
|
||||
1900 + time->tm_year, time->tm_mon + 1, time->tm_mday,
|
||||
time->tm_hour, time->tm_min, time->tm_sec);
|
||||
|
||||
// file type
|
||||
mode_t mode = entry->Mode();
|
||||
if (S_ISREG(mode))
|
||||
printf(" -");
|
||||
else if (S_ISDIR(mode))
|
||||
printf(" d");
|
||||
else if (S_ISLNK(mode))
|
||||
printf(" l");
|
||||
else
|
||||
printf(" ?");
|
||||
|
||||
// permissions
|
||||
char buffer[4];
|
||||
printf("%s", _PermissionString(buffer, mode >> 6,
|
||||
(mode & S_ISUID) != 0));
|
||||
printf("%s", _PermissionString(buffer, mode >> 3,
|
||||
(mode & S_ISGID) != 0));
|
||||
printf("%s", _PermissionString(buffer, mode, false));
|
||||
|
||||
// print the symlink path
|
||||
if (S_ISLNK(mode))
|
||||
printf(" -> %s", entry->SymlinkPath());
|
||||
|
||||
printf("\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandleEntryAttribute(BPackageEntry* entry,
|
||||
BPackageEntryAttribute* attribute)
|
||||
{
|
||||
if (!fListAttribute)
|
||||
return B_OK;
|
||||
|
||||
int indentation = fLevel * 2;
|
||||
printf("%*s<", indentation, "");
|
||||
printf("%-*s %8llu", indentation < 31 ? 31 - indentation : 0,
|
||||
attribute->Name(), attribute->Data().UncompressedSize());
|
||||
|
||||
uint32 type = attribute->Type();
|
||||
if (isprint(type & 0xff) && isprint((type >> 8) & 0xff)
|
||||
&& isprint((type >> 16) & 0xff) && isprint(type >> 24)) {
|
||||
printf(" '%c%c%c%c'", int(type >> 24), int((type >> 16) & 0xff),
|
||||
int((type >> 8) & 0xff), int(type & 0xff));
|
||||
} else
|
||||
printf(" %#lx", type);
|
||||
|
||||
printf(">\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandleEntryDone(BPackageEntry* entry)
|
||||
{
|
||||
fLevel--;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandlePackageAttribute(
|
||||
const BPackageInfoAttributeValue& value)
|
||||
{
|
||||
switch (value.attributeIndex) {
|
||||
case B_PACKAGE_INFO_NAME:
|
||||
printf("package-attributes:\n");
|
||||
printf("\tname: %s\n", value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_SUMMARY:
|
||||
printf("\tsummary: %s\n", value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_DESCRIPTION:
|
||||
printf("\tdescription: %s\n", value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_VENDOR:
|
||||
printf("\tvendor: %s\n", value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_PACKAGER:
|
||||
printf("\tpackager: %s\n", value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_FLAGS:
|
||||
if (value.unsignedInt == 0)
|
||||
break;
|
||||
printf("\tflags:\n");
|
||||
if ((value.unsignedInt & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0)
|
||||
printf("\t\tapprove_license\n");
|
||||
if ((value.unsignedInt & B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0)
|
||||
printf("\t\tsystem_package\n");
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_ARCHITECTURE:
|
||||
printf("\tarchitecture: %s\n",
|
||||
BPackageInfo::kArchitectureNames[value.unsignedInt]);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_VERSION:
|
||||
printf("\tversion: %s.%s.%s-%d\n", value.version.major,
|
||||
value.version.minor, value.version.micro,
|
||||
value.version.release);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_COPYRIGHTS:
|
||||
printf("\tcopyright: %s\n", value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_LICENSES:
|
||||
printf("\tlicense: %s\n", value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_PROVIDES:
|
||||
printf("\tprovides: %s", value.resolvable.name);
|
||||
if (value.resolvable.haveVersion) {
|
||||
printf(" = ");
|
||||
_PrintPackageVersion(value.resolvable.version);
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_REQUIRES:
|
||||
printf("\trequires: %s", value.resolvableExpression.name);
|
||||
if (value.resolvableExpression.haveOpAndVersion) {
|
||||
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
|
||||
value.resolvableExpression.op]);
|
||||
_PrintPackageVersion(value.resolvableExpression.version);
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_SUPPLEMENTS:
|
||||
printf("\tsupplements: %s", value.resolvableExpression.name);
|
||||
if (value.resolvableExpression.haveOpAndVersion) {
|
||||
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
|
||||
value.resolvableExpression.op]);
|
||||
_PrintPackageVersion(value.resolvableExpression.version);
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_CONFLICTS:
|
||||
printf("\tconflicts: %s", value.resolvableExpression.name);
|
||||
if (value.resolvableExpression.haveOpAndVersion) {
|
||||
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
|
||||
value.resolvableExpression.op]);
|
||||
_PrintPackageVersion(value.resolvableExpression.version);
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_FRESHENS:
|
||||
printf("\tfreshens: %s", value.resolvableExpression.name);
|
||||
if (value.resolvableExpression.haveOpAndVersion) {
|
||||
printf(" %s ", BPackageResolvableExpression::kOperatorNames[
|
||||
value.resolvableExpression.op]);
|
||||
_PrintPackageVersion(value.resolvableExpression.version);
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_REPLACES:
|
||||
printf("\treplaces: %s\n", value.string);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf(
|
||||
"*** Invalid package attribute section: unexpected "
|
||||
"package attribute index %d encountered\n",
|
||||
value.attributeIndex);
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandlePackageAttributesDone()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual void HandleErrorOccurred()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
static const char* _PermissionString(char* buffer, uint32 mode, bool sticky)
|
||||
{
|
||||
buffer[0] = (mode & 0x4) != 0 ? 'r' : '-';
|
||||
buffer[1] = (mode & 0x2) != 0 ? 'w' : '-';
|
||||
|
||||
if ((mode & 0x1) != 0)
|
||||
buffer[2] = sticky ? 's' : 'x';
|
||||
else
|
||||
buffer[2] = '-';
|
||||
|
||||
buffer[3] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void _PrintPackageVersion(const BPackageVersionData& version)
|
||||
{
|
||||
printf("%s", version.major);
|
||||
if (version.minor != NULL && version.minor[0] != '\0')
|
||||
printf(".%s", version.minor);
|
||||
if (version.micro != NULL && version.micro[0] != '\0')
|
||||
printf(".%s", version.micro);
|
||||
if (version.release > 0)
|
||||
printf("-%d", version.release);
|
||||
}
|
||||
|
||||
private:
|
||||
int fLevel;
|
||||
bool fListAttribute;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
command_list(int argc, const char* const* argv)
|
||||
{
|
||||
bool listAttributes = false;
|
||||
|
||||
while (true) {
|
||||
static struct option sLongOptions[] = {
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
opterr = 0; // don't print errors
|
||||
int c = getopt_long(argc, (char**)argv, "+ha", sLongOptions, NULL);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'a':
|
||||
listAttributes = true;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_usage_and_exit(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
print_usage_and_exit(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// One argument should remain -- the package file name.
|
||||
if (optind + 1 != argc)
|
||||
print_usage_and_exit(true);
|
||||
|
||||
const char* packageFileName = argv[optind++];
|
||||
|
||||
// open package
|
||||
StandardErrorOutput errorOutput;
|
||||
BPackageReader packageReader(&errorOutput);
|
||||
status_t error = packageReader.Init(packageFileName);
|
||||
printf("Init(): %s\n", strerror(error));
|
||||
if (error != B_OK)
|
||||
return 1;
|
||||
|
||||
// list
|
||||
PackageContentListHandler handler(listAttributes);
|
||||
error = packageReader.ParseContent(&handler);
|
||||
printf("ParseContent(): %s\n", strerror(error));
|
||||
if (error != B_OK)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "package_repo.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern const char* __progname;
|
||||
const char* kCommandName = __progname;
|
||||
|
||||
|
||||
static const char* kUsage =
|
||||
"Usage: %s <command> <command args>\n"
|
||||
"Creates or inspects a Haiku package repository file.\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" create [ <options> ] <package-repo> <package-file ...> \n"
|
||||
" Creates package repository file <package-repo> from the given\n"
|
||||
" package files.\n"
|
||||
"\n"
|
||||
" -C <dir> - Change to directory <dir> before starting.\n"
|
||||
" -q - be quiet (don't show any output except for errors).\n"
|
||||
" -v - be verbose (list package attributes as encountered).\n"
|
||||
"\n"
|
||||
" list [ <options> ] <package-repo>\n"
|
||||
" Lists the contents of package repository file <package-repo>.\n"
|
||||
"\n"
|
||||
" -v - be verbose (list attributes of all packages found).\n"
|
||||
"\n"
|
||||
"Common Options:\n"
|
||||
" -h, --help - Print this usage info.\n"
|
||||
;
|
||||
|
||||
|
||||
void
|
||||
print_usage_and_exit(bool error)
|
||||
{
|
||||
fprintf(error ? stderr : stdout, kUsage, kCommandName);
|
||||
exit(error ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, const char* const* argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
print_usage_and_exit(true);
|
||||
|
||||
const char* command = argv[1];
|
||||
if (strcmp(command, "create") == 0)
|
||||
return command_create(argc - 1, argv + 1);
|
||||
|
||||
if (strcmp(command, "list") == 0)
|
||||
return command_list(argc - 1, argv + 1);
|
||||
|
||||
if (strcmp(command, "help") == 0)
|
||||
print_usage_and_exit(false);
|
||||
else
|
||||
print_usage_and_exit(true);
|
||||
|
||||
// never gets here
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PACKAGE_REPO_H
|
||||
#define PACKAGE_REPO_H
|
||||
|
||||
|
||||
void print_usage_and_exit(bool error);
|
||||
|
||||
int command_create(int argc, const char* const* argv);
|
||||
int command_list(int argc, const char* const* argv);
|
||||
|
||||
|
||||
#endif // PACKAGE_REPO_H
|
|
@ -9,14 +9,9 @@
|
|||
|
||||
#include <package/ActivateRepositoryConfigJob.h>
|
||||
|
||||
#include <File.h>
|
||||
#include <Message.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#include <package/Context.h>
|
||||
#include <package/RepositoryConfig.h>
|
||||
#include <package/RepositoryHeader.h>
|
||||
#include <package/RepositoryInfo.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
@ -26,11 +21,11 @@ namespace BPrivate {
|
|||
|
||||
ActivateRepositoryConfigJob::ActivateRepositoryConfigJob(
|
||||
const BContext& context, const BString& title,
|
||||
const BEntry& archivedRepoHeaderEntry, const BString& repositoryBaseURL,
|
||||
const BEntry& archivedRepoInfoEntry, const BString& repositoryBaseURL,
|
||||
const BDirectory& targetDirectory)
|
||||
:
|
||||
inherited(context, title),
|
||||
fArchivedRepoHeaderEntry(archivedRepoHeaderEntry),
|
||||
fArchivedRepoInfoEntry(archivedRepoInfoEntry),
|
||||
fRepositoryBaseURL(repositoryBaseURL),
|
||||
fTargetDirectory(targetDirectory)
|
||||
{
|
||||
|
@ -45,26 +40,15 @@ ActivateRepositoryConfigJob::~ActivateRepositoryConfigJob()
|
|||
status_t
|
||||
ActivateRepositoryConfigJob::Execute()
|
||||
{
|
||||
BFile archiveFile(&fArchivedRepoHeaderEntry, B_READ_ONLY);
|
||||
status_t result = archiveFile.InitCheck();
|
||||
BRepositoryInfo repoInfo(fArchivedRepoInfoEntry);
|
||||
status_t result = repoInfo.InitCheck();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
BMessage archive;
|
||||
if ((result = archive.Unflatten(&archiveFile)) != B_OK)
|
||||
return result;
|
||||
|
||||
BRepositoryHeader* repoHeader = BRepositoryHeader::Instantiate(&archive);
|
||||
if (repoHeader == NULL)
|
||||
return B_BAD_DATA;
|
||||
ObjectDeleter<BRepositoryHeader> repoHeaderDeleter(repoHeader);
|
||||
if ((result = repoHeader->InitCheck()) != B_OK)
|
||||
return result;
|
||||
|
||||
fTargetEntry.SetTo(&fTargetDirectory, repoHeader->Name().String());
|
||||
fTargetEntry.SetTo(&fTargetDirectory, repoInfo.Name().String());
|
||||
if (fTargetEntry.Exists()) {
|
||||
BString description = BString("A repository configuration for ")
|
||||
<< repoHeader->Name() << " already exists.";
|
||||
<< repoInfo.Name() << " already exists.";
|
||||
BString question("overwrite?");
|
||||
bool yes = fContext.DecisionProvider().YesNoDecisionNeeded(
|
||||
description, question, "yes", "no", "no");
|
||||
|
@ -77,9 +61,9 @@ ActivateRepositoryConfigJob::Execute()
|
|||
// create and store the configuration (injecting the BaseURL that was
|
||||
// actually used)
|
||||
BRepositoryConfig repoConfig;
|
||||
repoConfig.SetName(repoHeader->Name());
|
||||
repoConfig.SetName(repoInfo.Name());
|
||||
repoConfig.SetBaseURL(fRepositoryBaseURL);
|
||||
repoConfig.SetPriority(repoHeader->Priority());
|
||||
repoConfig.SetPriority(repoInfo.Priority());
|
||||
if ((result = repoConfig.Store(fTargetEntry)) != B_OK)
|
||||
return result;
|
||||
|
||||
|
|
|
@ -48,13 +48,13 @@ AddRepositoryRequest::CreateInitialJobs()
|
|||
return B_NO_INIT;
|
||||
|
||||
BEntry tempEntry;
|
||||
result = fContext.GetNewTempfile("repoheader-", &tempEntry);
|
||||
result = fContext.GetNewTempfile("repoinfo-", &tempEntry);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
BString repoHeaderURL = BString(fRepositoryBaseURL) << "/" << "repo.header";
|
||||
BString repoInfoURL = BString(fRepositoryBaseURL) << "/" << "repo.info";
|
||||
FetchFileJob* fetchJob = new (std::nothrow) FetchFileJob(fContext,
|
||||
BString("Fetching repository header from ") << fRepositoryBaseURL,
|
||||
repoHeaderURL, tempEntry);
|
||||
BString("Fetching repository info from ") << fRepositoryBaseURL,
|
||||
repoInfoURL, tempEntry);
|
||||
if (fetchJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
if ((result = QueueJob(fetchJob)) != B_OK) {
|
||||
|
|
|
@ -25,6 +25,7 @@ HPKG_SOURCES =
|
|||
PackageReaderImpl.cpp
|
||||
PackageWriter.cpp
|
||||
PackageWriterImpl.cpp
|
||||
RepositoryWriter.cpp
|
||||
RepositoryWriterImpl.cpp
|
||||
Strings.cpp
|
||||
WriterImplBase.cpp
|
||||
|
@ -56,7 +57,7 @@ SharedLibrary libpackage.so
|
|||
RemoveRepositoryJob.cpp
|
||||
RepositoryCache.cpp
|
||||
RepositoryConfig.cpp
|
||||
RepositoryHeader.cpp
|
||||
RepositoryInfo.cpp
|
||||
Request.cpp
|
||||
TempfileManager.cpp
|
||||
ValidateChecksumJob.cpp
|
||||
|
|
|
@ -809,6 +809,7 @@ const char* BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = {
|
|||
"freshens",
|
||||
"replaces",
|
||||
"flags",
|
||||
"checksum", // not being parsed, computed externally
|
||||
};
|
||||
|
||||
|
||||
|
@ -936,6 +937,13 @@ BPackageInfo::Packager() const
|
|||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BPackageInfo::Checksum() const
|
||||
{
|
||||
return fChecksum;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
BPackageInfo::Flags() const
|
||||
{
|
||||
|
@ -1048,6 +1056,13 @@ BPackageInfo::SetPackager(const BString& packager)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
BPackageInfo::SetChecksum(const BString& checksum)
|
||||
{
|
||||
fChecksum = checksum;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BPackageInfo::SetVersion(const BPackageVersion& version)
|
||||
{
|
||||
|
@ -1226,8 +1241,10 @@ BPackageInfo::Clear()
|
|||
fDescription.Truncate(0);
|
||||
fVendor.Truncate(0);
|
||||
fPackager.Truncate(0);
|
||||
fVersion.Clear();
|
||||
fChecksum.Truncate(0);
|
||||
fFlags = 0;
|
||||
fArchitecture = B_PACKAGE_ARCHITECTURE_ENUM_COUNT;
|
||||
fVersion.Clear();
|
||||
fCopyrightList.MakeEmpty();
|
||||
fLicenseList.MakeEmpty();
|
||||
fRequiresList.MakeEmpty();
|
||||
|
@ -1239,4 +1256,17 @@ BPackageInfo::Clear()
|
|||
}
|
||||
|
||||
|
||||
/*static*/ status_t
|
||||
BPackageInfo::GetArchitectureByName(const BString& name,
|
||||
BPackageArchitecture& _architecture)
|
||||
{
|
||||
for (int i = 0; i < B_PACKAGE_ARCHITECTURE_ENUM_COUNT; ++i) {
|
||||
if (name.ICompare(kArchitectureNames[i]) == 0) {
|
||||
_architecture = (BPackageArchitecture)i;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <package/PackageResolvable.h>
|
||||
|
||||
#include <package/hpkg/PackageInfoAttributeValue.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
@ -27,6 +29,15 @@ BPackageResolvable::BPackageResolvable()
|
|||
}
|
||||
|
||||
|
||||
BPackageResolvable::BPackageResolvable(const BPackageResolvableData& data)
|
||||
:
|
||||
fName(data.name),
|
||||
fType(data.type),
|
||||
fVersion(data.version)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BPackageResolvable::BPackageResolvable(const BString& name,
|
||||
BPackageResolvableType type, const BPackageVersion& version)
|
||||
:
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <package/PackageResolvableExpression.h>
|
||||
|
||||
#include <package/hpkg/PackageInfoAttributeValue.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
@ -29,6 +31,16 @@ BPackageResolvableExpression::BPackageResolvableExpression()
|
|||
}
|
||||
|
||||
|
||||
BPackageResolvableExpression::BPackageResolvableExpression(
|
||||
const BPackageResolvableExpressionData& data)
|
||||
:
|
||||
fName(data.name),
|
||||
fOperator(data.op),
|
||||
fVersion(data.version)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BPackageResolvableExpression::BPackageResolvableExpression(const BString& name,
|
||||
BPackageResolvableOperator _operator, const BPackageVersion& version)
|
||||
:
|
||||
|
@ -46,10 +58,8 @@ BPackageResolvableExpression::InitCheck() const
|
|||
return B_NO_INIT;
|
||||
|
||||
// either both or none of operator and version must be set
|
||||
if ((fOperator == B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT
|
||||
&& fVersion.InitCheck() == B_OK)
|
||||
|| (fOperator >= 0 && fOperator < B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT
|
||||
&& fVersion.InitCheck() != B_OK))
|
||||
if ((fOperator >= 0 && fOperator < B_PACKAGE_RESOLVABLE_OP_ENUM_COUNT)
|
||||
!= (fVersion.InitCheck() == B_OK))
|
||||
return B_NO_INIT;
|
||||
|
||||
return B_OK;
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <NaturalCompare.h>
|
||||
|
||||
#include <package/hpkg/PackageInfoAttributeValue.h>
|
||||
|
||||
|
||||
using BPrivate::NaturalCompare;
|
||||
|
||||
|
@ -20,6 +22,16 @@ BPackageVersion::BPackageVersion()
|
|||
}
|
||||
|
||||
|
||||
BPackageVersion::BPackageVersion(const BPackageVersionData& data)
|
||||
:
|
||||
fMajor(data.major),
|
||||
fMinor(data.minor),
|
||||
fMicro(data.micro),
|
||||
fRelease(data.release)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BPackageVersion::BPackageVersion(const BString& major, const BString& minor,
|
||||
const BString& micro, uint8 release)
|
||||
:
|
||||
|
|
|
@ -55,10 +55,10 @@ BRepositoryCache::Entry() const
|
|||
}
|
||||
|
||||
|
||||
const BRepositoryHeader&
|
||||
BRepositoryCache::Header() const
|
||||
const BRepositoryInfo&
|
||||
BRepositoryCache::Info() const
|
||||
{
|
||||
return fHeader;
|
||||
return fInfo;
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,7 +90,7 @@ BRepositoryCache::SetTo(const BEntry& entry)
|
|||
if ((result = headerMsg.Unflatten(&file)) != B_OK)
|
||||
return result;
|
||||
|
||||
if ((result = fHeader.SetTo(&headerMsg)) != B_OK)
|
||||
if ((result = fInfo.SetTo(&headerMsg)) != B_OK)
|
||||
return result;
|
||||
|
||||
BPath userSettingsPath;
|
||||
|
|
|
@ -1,202 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/RepositoryHeader.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
const uint8 BRepositoryHeader::kDefaultPriority = 50;
|
||||
|
||||
const char* BRepositoryHeader::kNameField = "name";
|
||||
const char* BRepositoryHeader::kURLField = "url";
|
||||
const char* BRepositoryHeader::kVendorField = "vendor";
|
||||
const char* BRepositoryHeader::kShortDescriptionField = "shortDescr";
|
||||
const char* BRepositoryHeader::kLongDescriptionField = "longDescr";
|
||||
const char* BRepositoryHeader::kPriorityField = "priority";
|
||||
|
||||
|
||||
BRepositoryHeader::BRepositoryHeader()
|
||||
:
|
||||
fInitStatus(B_NO_INIT),
|
||||
fPriority(kDefaultPriority)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BRepositoryHeader::BRepositoryHeader(BMessage* data)
|
||||
:
|
||||
inherited(data)
|
||||
{
|
||||
fInitStatus = SetTo(data);
|
||||
}
|
||||
|
||||
|
||||
BRepositoryHeader::~BRepositoryHeader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*static*/ BRepositoryHeader*
|
||||
BRepositoryHeader::Instantiate(BMessage* data)
|
||||
{
|
||||
if (validate_instantiation(data, "BPackageKit::BRepositoryHeader"))
|
||||
return new (std::nothrow) BRepositoryHeader(data);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryHeader::Archive(BMessage* data, bool deep) const
|
||||
{
|
||||
status_t result = inherited::Archive(data, deep);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
if ((result = data->AddString(kNameField, fName)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->AddString(kURLField, fOriginalBaseURL)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->AddString(kVendorField, fVendor)) != B_OK)
|
||||
return result;
|
||||
result = data->AddString(kShortDescriptionField, fShortDescription);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
result = data->AddString(kLongDescriptionField, fLongDescription);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
if ((result = data->AddUInt8(kPriorityField, fPriority)) != B_OK)
|
||||
return result;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryHeader::InitCheck() const
|
||||
{
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryHeader::SetTo(const BMessage* data)
|
||||
{
|
||||
if (data == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t result;
|
||||
if ((result = data->FindString(kNameField, &fName)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->FindString(kURLField, &fOriginalBaseURL)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->FindString(kVendorField, &fVendor)) != B_OK)
|
||||
return result;
|
||||
result = data->FindString(kShortDescriptionField, &fShortDescription);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
result = data->FindString(kLongDescriptionField, &fLongDescription);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
if ((result = data->FindUInt8(kPriorityField, &fPriority)) != B_OK)
|
||||
return result;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BRepositoryHeader::Name() const
|
||||
{
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BRepositoryHeader::OriginalBaseURL() const
|
||||
{
|
||||
return fOriginalBaseURL;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BRepositoryHeader::Vendor() const
|
||||
{
|
||||
return fVendor;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BRepositoryHeader::ShortDescription() const
|
||||
{
|
||||
return fShortDescription;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BRepositoryHeader::LongDescription() const
|
||||
{
|
||||
return fLongDescription;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
BRepositoryHeader::Priority() const
|
||||
{
|
||||
return fPriority;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryHeader::SetName(const BString& name)
|
||||
{
|
||||
fName = name;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryHeader::SetOriginalBaseURL(const BString& url)
|
||||
{
|
||||
fOriginalBaseURL = url;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryHeader::SetVendor(const BString& vendor)
|
||||
{
|
||||
fVendor = vendor;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryHeader::SetShortDescription(const BString& description)
|
||||
{
|
||||
fShortDescription = description;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryHeader::SetLongDescription(const BString& description)
|
||||
{
|
||||
fLongDescription = description;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryHeader::SetPriority(uint8 priority)
|
||||
{
|
||||
fPriority = priority;
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/RepositoryInfo.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <driver_settings.h>
|
||||
#include <File.h>
|
||||
|
||||
#include <package/PackageInfo.h>
|
||||
|
||||
|
||||
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";
|
||||
|
||||
|
||||
BRepositoryInfo::BRepositoryInfo()
|
||||
:
|
||||
fInitStatus(B_NO_INIT),
|
||||
fPriority(kDefaultPriority),
|
||||
fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BRepositoryInfo::BRepositoryInfo(BMessage* data)
|
||||
:
|
||||
inherited(data)
|
||||
{
|
||||
fInitStatus = SetTo(data);
|
||||
}
|
||||
|
||||
|
||||
BRepositoryInfo::BRepositoryInfo(const BEntry& entry)
|
||||
{
|
||||
SetTo(entry);
|
||||
}
|
||||
|
||||
|
||||
BRepositoryInfo::~BRepositoryInfo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*static*/ BRepositoryInfo*
|
||||
BRepositoryInfo::Instantiate(BMessage* data)
|
||||
{
|
||||
if (validate_instantiation(data, "BPackageKit::BRepositoryInfo"))
|
||||
return new (std::nothrow) BRepositoryInfo(data);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryInfo::Archive(BMessage* data, bool deep) const
|
||||
{
|
||||
status_t result = inherited::Archive(data, deep);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
if ((result = data->AddString(kNameField, fName)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->AddString(kURLField, fOriginalBaseURL)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->AddString(kVendorField, fVendor)) != B_OK)
|
||||
return result;
|
||||
result = data->AddString(kSummaryField, fSummary);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
if ((result = data->AddUInt8(kPriorityField, fPriority)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->AddUInt8(kArchitectureField, fArchitecture)) != B_OK)
|
||||
return result;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryInfo::InitCheck() const
|
||||
{
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryInfo::SetTo(const BMessage* data)
|
||||
{
|
||||
if (data == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t result;
|
||||
if ((result = data->FindString(kNameField, &fName)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->FindString(kURLField, &fOriginalBaseURL)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->FindString(kVendorField, &fVendor)) != B_OK)
|
||||
return result;
|
||||
result = data->FindString(kSummaryField, &fSummary);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
if ((result = data->FindUInt8(kPriorityField, &fPriority)) != B_OK)
|
||||
return result;
|
||||
result = data->FindUInt8(kArchitectureField, (uint8*)&fArchitecture);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRepositoryInfo::SetTo(const BEntry& entry)
|
||||
{
|
||||
BFile file(&entry, B_READ_ONLY);
|
||||
status_t result = file.InitCheck();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
off_t size;
|
||||
if ((result = file.GetSize(&size)) != B_OK)
|
||||
return result;
|
||||
|
||||
BString configString;
|
||||
char* buffer = configString.LockBuffer(size);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if ((result = file.Read(buffer, size)) < size) {
|
||||
configString.UnlockBuffer(0);
|
||||
return (result >= 0) ? B_IO_ERROR : result;
|
||||
}
|
||||
|
||||
buffer[size] = '\0';
|
||||
configString.UnlockBuffer(size);
|
||||
|
||||
void* settingsHandle = parse_driver_settings_string(configString.String());
|
||||
if (settingsHandle == NULL)
|
||||
return B_BAD_DATA;
|
||||
|
||||
const char* name = get_driver_parameter(settingsHandle, "name", NULL, NULL);
|
||||
const char* url = get_driver_parameter(settingsHandle, "url", NULL, NULL);
|
||||
const char* vendor
|
||||
= get_driver_parameter(settingsHandle, "vendor", NULL, NULL);
|
||||
const char* summary
|
||||
= get_driver_parameter(settingsHandle, "summary", NULL, NULL);
|
||||
const char* priorityString
|
||||
= get_driver_parameter(settingsHandle, "priority", NULL, NULL);
|
||||
const char* architectureString
|
||||
= get_driver_parameter(settingsHandle, "architecture", NULL, NULL);
|
||||
|
||||
unload_driver_settings(settingsHandle);
|
||||
|
||||
if (name == NULL || *name == '\0' || url == NULL || *url == '\0'
|
||||
|| vendor == NULL || *vendor == '\0'
|
||||
|| summary == NULL || *summary == '\0'
|
||||
|| priorityString == NULL || *priorityString == '\0'
|
||||
|| architectureString == NULL || *architectureString == '\0') {
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
BPackageArchitecture architecture;
|
||||
if (BPackageInfo::GetArchitectureByName(architectureString, architecture)
|
||||
!= B_OK) {
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
fName = name;
|
||||
fOriginalBaseURL = url;
|
||||
fVendor = vendor;
|
||||
fSummary = summary;
|
||||
fPriority = atoi(priorityString);
|
||||
fArchitecture = architecture;
|
||||
|
||||
fInitStatus = B_OK;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BRepositoryInfo::Name() const
|
||||
{
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BRepositoryInfo::OriginalBaseURL() const
|
||||
{
|
||||
return fOriginalBaseURL;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BRepositoryInfo::Vendor() const
|
||||
{
|
||||
return fVendor;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
BRepositoryInfo::Summary() const
|
||||
{
|
||||
return fSummary;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
BRepositoryInfo::Priority() const
|
||||
{
|
||||
return fPriority;
|
||||
}
|
||||
|
||||
|
||||
BPackageArchitecture
|
||||
BRepositoryInfo::Architecture() const
|
||||
{
|
||||
return fArchitecture;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryInfo::SetName(const BString& name)
|
||||
{
|
||||
fName = name;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryInfo::SetOriginalBaseURL(const BString& url)
|
||||
{
|
||||
fOriginalBaseURL = url;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryInfo::SetVendor(const BString& vendor)
|
||||
{
|
||||
fVendor = vendor;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryInfo::SetSummary(const BString& summary)
|
||||
{
|
||||
fSummary = summary;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryInfo::SetPriority(uint8 priority)
|
||||
{
|
||||
fPriority = priority;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRepositoryInfo::SetArchitecture(BPackageArchitecture architecture)
|
||||
{
|
||||
fArchitecture = architecture;
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
|
@ -1134,8 +1134,10 @@ PackageReaderImpl::_ParsePackageAttributes(AttributeHandlerContext* context)
|
|||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
if (tag == 0)
|
||||
return B_OK;
|
||||
if (tag == 0) {
|
||||
return
|
||||
context->packageContentHandler->HandlePackageAttributesDone();
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case HPKG_PACKAGE_ATTRIBUTE_NAME:
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <new>
|
||||
|
||||
#include <package/hpkg/RepositoryWriterImpl.h>
|
||||
#include <package/RepositoryInfo.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
@ -16,9 +17,10 @@ namespace BPackageKit {
|
|||
namespace BHPKG {
|
||||
|
||||
|
||||
BRepositoryWriter::BRepositoryWriter(BRepositoryWriterListener* listener)
|
||||
BRepositoryWriter::BRepositoryWriter(BRepositoryWriterListener* listener,
|
||||
const BRepositoryInfo* repositoryInfo)
|
||||
:
|
||||
fImpl(new (std::nothrow) RepositoryWriterImpl(listener))
|
||||
fImpl(new (std::nothrow) RepositoryWriterImpl(listener, repositoryInfo))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,17 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
#include <set>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <Message.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <package/hpkg/haiku_package.h>
|
||||
|
||||
#include <package/PackageInfo.h>
|
||||
#include <package/hpkg/PackageInfoAttributeValue.h>
|
||||
#include <package/hpkg/PackageReader.h>
|
||||
#include <package/ChecksumAccessors.h>
|
||||
#include <package/RepositoryInfo.h>
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
@ -23,16 +28,28 @@ namespace BHPKG {
|
|||
namespace BPrivate {
|
||||
|
||||
|
||||
RepositoryWriterImpl::RepositoryWriterImpl(BRepositoryWriterListener* listener)
|
||||
using BPackageKit::BPrivate::GeneralFileChecksumAccessor;
|
||||
|
||||
|
||||
struct RepositoryWriterImpl::PackageNameSet : public std::set<BString> {
|
||||
};
|
||||
|
||||
|
||||
RepositoryWriterImpl::RepositoryWriterImpl(BRepositoryWriterListener* listener,
|
||||
const BRepositoryInfo* repositoryInfo)
|
||||
:
|
||||
WriterImplBase(listener),
|
||||
fListener(listener)
|
||||
fListener(listener),
|
||||
fRepositoryInfo(repositoryInfo),
|
||||
fPackageCount(0),
|
||||
fPackageNames(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RepositoryWriterImpl::~RepositoryWriterImpl()
|
||||
{
|
||||
delete fPackageNames;
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +57,7 @@ status_t
|
|||
RepositoryWriterImpl::Init(const char* fileName)
|
||||
{
|
||||
try {
|
||||
fPackageNames = new PackageNameSet();
|
||||
return _Init(fileName);
|
||||
} catch (status_t error) {
|
||||
return error;
|
||||
|
@ -78,6 +96,129 @@ RepositoryWriterImpl::Finish()
|
|||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandleEntry(BPackageEntry* entry)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandleEntryAttribute(BPackageEntry* entry,
|
||||
BPackageEntryAttribute* attribute)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandleEntryDone(BPackageEntry* entry)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandlePackageAttribute(
|
||||
const BPackageInfoAttributeValue& value)
|
||||
{
|
||||
switch (value.attributeIndex) {
|
||||
case B_PACKAGE_INFO_NAME:
|
||||
fPackageInfo.SetName(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_SUMMARY:
|
||||
fPackageInfo.SetSummary(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_DESCRIPTION:
|
||||
fPackageInfo.SetDescription(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_VENDOR:
|
||||
{
|
||||
fPackageInfo.SetVendor(value.string);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_PACKAGE_INFO_PACKAGER:
|
||||
fPackageInfo.SetPackager(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_FLAGS:
|
||||
fPackageInfo.SetFlags(value.unsignedInt);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_ARCHITECTURE:
|
||||
{
|
||||
fPackageInfo.SetArchitecture(
|
||||
(BPackageArchitecture)value.unsignedInt);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_PACKAGE_INFO_VERSION:
|
||||
fPackageInfo.SetVersion(value.version);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_COPYRIGHTS:
|
||||
fPackageInfo.AddCopyright(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_LICENSES:
|
||||
fPackageInfo.AddLicense(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_PROVIDES:
|
||||
fPackageInfo.AddProvides(value.resolvable);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_REQUIRES:
|
||||
fPackageInfo.AddRequires(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_SUPPLEMENTS:
|
||||
fPackageInfo.AddSupplements(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_CONFLICTS:
|
||||
fPackageInfo.AddConflicts(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_FRESHENS:
|
||||
fPackageInfo.AddFreshens(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_REPLACES:
|
||||
fPackageInfo.AddReplaces(value.string);
|
||||
break;
|
||||
|
||||
default:
|
||||
fListener->PrintError(
|
||||
"Invalid package attribute section: unexpected package "
|
||||
"attribute index %d encountered\n", value.attributeIndex);
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandlePackageAttributesDone()
|
||||
{
|
||||
status_t result = _RegisterCurrentPackageInfo();
|
||||
fPackageInfo.Clear();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryWriterImpl::HandleErrorOccurred()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::_Init(const char* fileName)
|
||||
{
|
||||
|
@ -90,15 +231,24 @@ RepositoryWriterImpl::_Finish()
|
|||
{
|
||||
hpkg_repo_header header;
|
||||
|
||||
// write package attributes
|
||||
off_t totalSize = _WritePackageAttributes(header);
|
||||
// write repository header
|
||||
ssize_t repositoryInfoLength;
|
||||
status_t result = _WriteRepositoryInfo(repositoryInfoLength);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
fListener->OnRepositorySizeInfo(sizeof(header),
|
||||
header.repository_header_length
|
||||
= B_HOST_TO_BENDIAN_INT32(repositoryInfoLength);
|
||||
|
||||
// write package attributes
|
||||
off_t totalSize = _WritePackageAttributes(header,
|
||||
sizeof(header) + repositoryInfoLength);
|
||||
|
||||
fListener->OnRepositorySizeInfo(sizeof(header), repositoryInfoLength,
|
||||
fPackageCount,
|
||||
B_BENDIAN_TO_HOST_INT32(header.attributes_length_compressed),
|
||||
totalSize);
|
||||
|
||||
// prepare the header
|
||||
|
||||
// general
|
||||
header.magic = B_HOST_TO_BENDIAN_INT32(B_HPKG_REPO_MAGIC);
|
||||
header.header_size = B_HOST_TO_BENDIAN_INT16((uint16)sizeof(header));
|
||||
|
@ -116,17 +266,119 @@ RepositoryWriterImpl::_Finish()
|
|||
status_t
|
||||
RepositoryWriterImpl::_AddPackage(const BEntry& packageEntry)
|
||||
{
|
||||
// TODO!
|
||||
status_t result = packageEntry.InitCheck();
|
||||
if (result != B_OK) {
|
||||
fListener->PrintError("entry not initialized!\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
BPath packagePath;
|
||||
if ((result = packageEntry.GetPath(&packagePath)) != B_OK) {
|
||||
fListener->PrintError("can't get path for entry!\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
BPackageReader packageReader(fListener);
|
||||
if ((result = packageReader.Init(packagePath.Path())) != B_OK) {
|
||||
fListener->PrintError("can't create package reader!\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
fPackageInfo.Clear();
|
||||
|
||||
GeneralFileChecksumAccessor checksumAccessor(packageEntry);
|
||||
BString checksum;
|
||||
if ((result = checksumAccessor.GetChecksum(checksum)) != B_OK) {
|
||||
fListener->PrintError("can't compute checksum!\n");
|
||||
return result;
|
||||
}
|
||||
fPackageInfo.SetChecksum(checksum);
|
||||
|
||||
return packageReader.ParseContent(this);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::_RegisterCurrentPackageInfo()
|
||||
{
|
||||
status_t result = fPackageInfo.InitCheck();
|
||||
if (result != B_OK) {
|
||||
fListener->PrintError("package %s has incomplete package-info!\n",
|
||||
fPackageInfo.Name().String());
|
||||
return result;
|
||||
}
|
||||
|
||||
// reject package with a name that we've seen already
|
||||
PackageNameSet::const_iterator namePos
|
||||
= fPackageNames->find(fPackageInfo.Name());
|
||||
if (namePos != fPackageNames->end()) {
|
||||
fListener->PrintError("package %s has already been added!\n",
|
||||
fPackageInfo.Name().String());
|
||||
return B_NAME_IN_USE;
|
||||
}
|
||||
|
||||
// all packages must have the same vendor as the repository
|
||||
const BString& expectedVendor = fRepositoryInfo->Vendor();
|
||||
if (fPackageInfo.Vendor().ICompare(expectedVendor) != 0) {
|
||||
fListener->PrintError("package '%s' has unexpected vendor '%s' "
|
||||
"(expected '%s')!\n", fPackageInfo.Name().String(),
|
||||
fPackageInfo.Vendor().String(), expectedVendor.String());
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
// all packages must have an architecture that's compatible with the one
|
||||
// used by the repository
|
||||
BPackageArchitecture expectedArchitecture = fRepositoryInfo->Architecture();
|
||||
if (fPackageInfo.Architecture() != expectedArchitecture
|
||||
&& fPackageInfo.Architecture() != B_PACKAGE_ARCHITECTURE_ANY) {
|
||||
fListener->PrintError(
|
||||
"package '%s' has non-matching architecture '%s' "
|
||||
"(expected '%s' or '%s')!\n", fPackageInfo.Name().String(),
|
||||
BPackageInfo::kArchitectureNames[fPackageInfo.Architecture()],
|
||||
BPackageInfo::kArchitectureNames[expectedArchitecture],
|
||||
BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ANY]
|
||||
);
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
fPackageNames->insert(fPackageInfo.Name());
|
||||
|
||||
RegisterPackageInfo(PackageAttributes(), fPackageInfo);
|
||||
fPackageCount++;
|
||||
fListener->OnPackageAdded(fPackageInfo);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::_WriteRepositoryInfo(ssize_t& _repositoryInfoLength)
|
||||
{
|
||||
BMessage archive;
|
||||
status_t result = fRepositoryInfo->Archive(&archive);
|
||||
if (result != B_OK) {
|
||||
fListener->PrintError("can't archive repository header!\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
_repositoryInfoLength = archive.FlattenedSize();
|
||||
char buffer[_repositoryInfoLength];
|
||||
if ((result = archive.Flatten(buffer, _repositoryInfoLength)) != B_OK) {
|
||||
fListener->PrintError("can't flatten repository header!\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
off_t startOffset = sizeof(hpkg_repo_header);
|
||||
WriteBuffer(buffer, _repositoryInfoLength, startOffset);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
off_t
|
||||
RepositoryWriterImpl::_WritePackageAttributes(hpkg_repo_header& header)
|
||||
RepositoryWriterImpl::_WritePackageAttributes(hpkg_repo_header& header,
|
||||
off_t startOffset)
|
||||
{
|
||||
// write the package attributes (zlib writer on top of a file writer)
|
||||
off_t startOffset = sizeof(header);
|
||||
FDDataWriter realWriter(FD(), startOffset, fListener);
|
||||
ZlibDataWriter zlibWriter(&realWriter);
|
||||
SetDataWriter(&zlibWriter);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <Message.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/RepositoryHeader.h>
|
||||
#include <package/RepositoryInfo.h>
|
||||
|
||||
|
||||
using namespace BPackageKit;
|
||||
|
@ -20,20 +20,20 @@ main(int argc, const char** argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
BRepositoryHeader repoHeader;
|
||||
repoHeader.SetName(argv[1]);
|
||||
repoHeader.SetOriginalBaseURL(argv[2]);
|
||||
repoHeader.SetPriority(atoi(argv[3]));
|
||||
BRepositoryInfo repoInfo;
|
||||
repoInfo.SetName(argv[1]);
|
||||
repoInfo.SetOriginalBaseURL(argv[2]);
|
||||
repoInfo.SetPriority(atoi(argv[3]));
|
||||
|
||||
BMessage repoHeaderArchive;
|
||||
status_t result = repoHeader.Archive(&repoHeaderArchive);
|
||||
BMessage repoInfoArchive;
|
||||
status_t result = repoInfo.Archive(&repoInfoArchive);
|
||||
if (result != B_OK) {
|
||||
fprintf(stderr, "couldn't archive repository-header\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
BFile output(argv[1], B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
|
||||
if ((result = repoHeaderArchive.Flatten(&output)) != B_OK) {
|
||||
if ((result = repoInfoArchive.Flatten(&output)) != B_OK) {
|
||||
fprintf(stderr, "couldn't flatten repository-header archive\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue