* more work on the package kit, repositories can now be added and
refreshed git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40280 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
77a8a5cce3
commit
35edda8f0b
@ -17,20 +17,36 @@ namespace Haiku {
|
||||
namespace Package {
|
||||
|
||||
|
||||
namespace Private {
|
||||
class ActivateRepositoryConfigJob;
|
||||
}
|
||||
using Private::ActivateRepositoryConfigJob;
|
||||
|
||||
|
||||
class AddRepositoryRequest : public Request {
|
||||
typedef Request inherited;
|
||||
|
||||
public:
|
||||
AddRepositoryRequest(const Context& context,
|
||||
const BString& repositoryURL,
|
||||
const BString& repositoryBaseURL,
|
||||
bool asUserRepository);
|
||||
virtual ~AddRepositoryRequest();
|
||||
|
||||
virtual status_t CreateJobsToRun(JobQueue& jobQueue);
|
||||
virtual status_t CreateInitialJobs();
|
||||
|
||||
const BString& RepositoryName() const;
|
||||
|
||||
protected:
|
||||
// JobStateListener
|
||||
virtual void JobSucceeded(Job* job);
|
||||
|
||||
private:
|
||||
BString fRepositoryURL;
|
||||
BString fRepositoryBaseURL;
|
||||
bool fAsUserRepository;
|
||||
|
||||
ActivateRepositoryConfigJob* fActivateJob;
|
||||
|
||||
BString fRepositoryName;
|
||||
};
|
||||
|
||||
|
||||
|
31
headers/os/package/Attributes.h
Normal file
31
headers/os/package/Attributes.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__ATTRIBUTES_H_
|
||||
#define _HAIKU__PACKAGE__ATTRIBUTES_H_
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
// attributes used in package and as file attribute, too
|
||||
extern const char* kNameAttribute;
|
||||
extern const char* kVendorAttribute;
|
||||
extern const char* kVersionAttribute;
|
||||
|
||||
// attributes kept local to packages
|
||||
extern const char* kCopyrightAttribute;
|
||||
extern const char* kLicenseAttribute;
|
||||
extern const char* kProvidesAttribute;
|
||||
extern const char* kRequiresAttribute;
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__ATTRIBUTES_H_
|
@ -6,7 +6,7 @@
|
||||
#define _HAIKU__PACKAGE__CONTEXT_H_
|
||||
|
||||
|
||||
#include <package/TempEntryManager.h>
|
||||
#include <package/TempfileManager.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
@ -15,6 +15,7 @@ namespace Package {
|
||||
|
||||
|
||||
class JobStateListener;
|
||||
using Private::TempfileManager;
|
||||
|
||||
|
||||
struct DecisionProvider {
|
||||
@ -37,7 +38,7 @@ public:
|
||||
Context(DecisionProvider& decisionProvider);
|
||||
~Context();
|
||||
|
||||
TempEntryManager& GetTempEntryManager() const;
|
||||
TempfileManager& GetTempfileManager() const;
|
||||
|
||||
JobStateListener* GetJobStateListener() const;
|
||||
void SetJobStateListener(JobStateListener* listener);
|
||||
@ -45,7 +46,7 @@ public:
|
||||
DecisionProvider& GetDecisionProvider() const;
|
||||
|
||||
private:
|
||||
mutable TempEntryManager fTempEntryManager;
|
||||
mutable TempfileManager fTempfileManager;
|
||||
DecisionProvider& fDecisionProvider;
|
||||
JobStateListener* fJobStateListener;
|
||||
};
|
||||
|
@ -18,6 +18,7 @@ namespace Package {
|
||||
class Context;
|
||||
class Job;
|
||||
|
||||
|
||||
struct JobStateListener {
|
||||
virtual ~JobStateListener();
|
||||
|
||||
@ -51,6 +52,7 @@ public:
|
||||
const BString& Title() const;
|
||||
JobState State() const;
|
||||
status_t Result() const;
|
||||
const BString& ErrorString() const;
|
||||
|
||||
status_t AddStateListener(JobStateListener* listener);
|
||||
status_t RemoveStateListener(
|
||||
@ -65,6 +67,8 @@ protected:
|
||||
virtual status_t Execute() = 0;
|
||||
virtual void Cleanup(status_t jobResult);
|
||||
|
||||
void SetErrorString(const BString&);
|
||||
|
||||
void NotifyStateListeners();
|
||||
|
||||
const Context& fContext;
|
||||
@ -74,6 +78,7 @@ private:
|
||||
|
||||
JobState fState;
|
||||
status_t fResult;
|
||||
BString fErrorString;
|
||||
|
||||
typedef BObjectList<Job> JobList;
|
||||
JobList fDependencies;
|
||||
|
56
headers/os/package/RefreshRepositoryRequest.h
Normal file
56
headers/os/package/RefreshRepositoryRequest.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__REFRESH_REPOSITORY_REQUEST_H_
|
||||
#define _HAIKU__PACKAGE__REFRESH_REPOSITORY_REQUEST_H_
|
||||
|
||||
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/Context.h>
|
||||
#include <package/RepositoryConfig.h>
|
||||
#include <package/Request.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
namespace Private {
|
||||
class ValidateChecksumJob;
|
||||
}
|
||||
using Private::ValidateChecksumJob;
|
||||
|
||||
class RefreshRepositoryRequest : public Request {
|
||||
typedef Request inherited;
|
||||
|
||||
public:
|
||||
RefreshRepositoryRequest(const Context& context,
|
||||
const RepositoryConfig& repoConfig);
|
||||
virtual ~RefreshRepositoryRequest();
|
||||
|
||||
virtual status_t CreateInitialJobs();
|
||||
|
||||
protected:
|
||||
// JobStateListener
|
||||
virtual void JobSucceeded(Job* job);
|
||||
|
||||
private:
|
||||
status_t _FetchRepositoryCache();
|
||||
|
||||
BEntry fFetchedChecksumFile;
|
||||
RepositoryConfig fRepoConfig;
|
||||
|
||||
ValidateChecksumJob* fValidateChecksumJob;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__REFRESH_REPOSITORY_REQUEST_H_
|
@ -2,23 +2,52 @@
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _REPOSITORY_H_
|
||||
#define _REPOSITORY_H_
|
||||
#ifndef _HAIKU__PACKAGE__REPOSITORY_CACHE_H_
|
||||
#define _HAIKU__PACKAGE__REPOSITORY_CACHE_H_
|
||||
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BMessage;
|
||||
class BEntry;
|
||||
|
||||
|
||||
class BRepository {
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
//class RepositoryHeader;
|
||||
|
||||
|
||||
class RepositoryCache {
|
||||
public:
|
||||
BRepository(const char* url);
|
||||
RepositoryCache();
|
||||
RepositoryCache(const BEntry& entry);
|
||||
virtual ~RepositoryCache();
|
||||
|
||||
public:
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
status_t SetTo(const BEntry& entry);
|
||||
status_t InitCheck() const;
|
||||
|
||||
// const RepositoryHeader* Header() const;
|
||||
const BEntry& Entry() const;
|
||||
bool IsUserSpecific() const;
|
||||
|
||||
void SetIsUserSpecific(bool isUserSpecific);
|
||||
|
||||
private:
|
||||
status_t fInitStatus;
|
||||
|
||||
BEntry fEntry;
|
||||
// RepositoryHeader* fHeader;
|
||||
bool fIsUserSpecific;
|
||||
};
|
||||
|
||||
|
||||
#endif // _REPOSITORY_H_
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__REPOSITORY_CACHE_H_
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
@ -34,6 +35,8 @@ public:
|
||||
|
||||
status_t StoreAsConfigFile(const BEntry& entry) const;
|
||||
|
||||
status_t SetTo(const BEntry& entry);
|
||||
status_t SetTo(const BMessage* data);
|
||||
status_t InitCheck() const;
|
||||
|
||||
const BString& Name() const;
|
||||
@ -41,6 +44,8 @@ public:
|
||||
uint8 Priority() const;
|
||||
bool IsUserSpecific() const;
|
||||
|
||||
const BEntry& Entry() const;
|
||||
|
||||
void SetName(const BString& name);
|
||||
void SetURL(const BString& url);
|
||||
void SetPriority(uint8 priority);
|
||||
@ -49,21 +54,20 @@ public:
|
||||
public:
|
||||
static RepositoryConfig* Instantiate(BMessage* data);
|
||||
|
||||
static const uint8 kDefaultPriority = 50;
|
||||
static const uint8 kDefaultPriority;
|
||||
static const char* kNameField;
|
||||
static const char* kURLField;
|
||||
static const char* kPriorityField;
|
||||
|
||||
private:
|
||||
status_t _InitFrom(const BEntry& entry);
|
||||
status_t _InitFrom(const BMessage* data);
|
||||
|
||||
status_t fInitStatus;
|
||||
|
||||
BString fName;
|
||||
BString fURL;
|
||||
uint8 fPriority;
|
||||
bool fIsUserSpecific;
|
||||
|
||||
BEntry fEntry;
|
||||
};
|
||||
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <package/JobQueue.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
@ -15,23 +17,25 @@ namespace Package {
|
||||
|
||||
|
||||
class Context;
|
||||
class Job;
|
||||
class JobQueue;
|
||||
using Private::JobQueue;
|
||||
|
||||
|
||||
class Request {
|
||||
class Request : protected JobStateListener {
|
||||
public:
|
||||
Request(const Context& context);
|
||||
virtual ~Request();
|
||||
|
||||
virtual status_t CreateJobsToRun(JobQueue& jobQueue) = 0;
|
||||
virtual status_t CreateInitialJobs() = 0;
|
||||
|
||||
const Context& GetContext() const;
|
||||
Job* PopRunnableJob();
|
||||
|
||||
protected:
|
||||
status_t QueueJob(Job* job, JobQueue& jobQueue) const;
|
||||
private:
|
||||
status_t QueueJob(Job* job);
|
||||
|
||||
const Context& fContext;
|
||||
|
||||
private:
|
||||
JobQueue fJobQueue;
|
||||
};
|
||||
|
||||
|
||||
|
@ -7,10 +7,14 @@
|
||||
|
||||
|
||||
#include <Entry.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
template <class T> class BObjectList;
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
@ -25,22 +29,39 @@ struct RepositoryConfigVisitor {
|
||||
};
|
||||
|
||||
|
||||
class RepositoryCache;
|
||||
class RepositoryConfig;
|
||||
|
||||
|
||||
class Roster {
|
||||
public:
|
||||
Roster();
|
||||
~Roster();
|
||||
|
||||
status_t GetCommonRepositoryCachePath(BPath* path,
|
||||
bool create = false) const;
|
||||
status_t GetUserRepositoryCachePath(BPath* path,
|
||||
bool create = false) const;
|
||||
|
||||
status_t GetCommonRepositoryConfigPath(BPath* path,
|
||||
bool create = false) const;
|
||||
status_t GetUserRepositoryConfigPath(BPath* path,
|
||||
bool create = false) const;
|
||||
|
||||
status_t GetRepositoryNames(BObjectList<BString>& names);
|
||||
|
||||
status_t VisitCommonRepositoryConfigs(
|
||||
RepositoryConfigVisitor& visitor);
|
||||
status_t VisitUserRepositoryConfigs(
|
||||
RepositoryConfigVisitor& visitor);
|
||||
|
||||
status_t GetRepositoryCache(const BString& name,
|
||||
RepositoryCache* repositoryCache);
|
||||
status_t GetRepositoryConfig(const BString& name,
|
||||
RepositoryConfig* repositoryConfig);
|
||||
private:
|
||||
status_t _GetRepositoryPath(BPath* path, bool create,
|
||||
directory_which whichDir) const;
|
||||
status_t _VisitRepositoryConfigs(const BPath& path,
|
||||
RepositoryConfigVisitor& visitor);
|
||||
|
||||
|
52
headers/private/package/ActivateRepositoryCacheJob.h
Normal file
52
headers/private/package/ActivateRepositoryCacheJob.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__PRIVATE__ACTIVATE_REPOSITORY_CACHE_JOB_H_
|
||||
#define _HAIKU__PACKAGE__PRIVATE__ACTIVATE_REPOSITORY_CACHE_JOB_H_
|
||||
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/Job.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
class ActivateRepositoryCacheJob : public Job {
|
||||
typedef Job inherited;
|
||||
|
||||
public:
|
||||
ActivateRepositoryCacheJob(
|
||||
const Context& context,
|
||||
const BString& title,
|
||||
const BEntry& fetchedRepoCacheEntry,
|
||||
const BString& repositoryName,
|
||||
const BDirectory& targetDirectory);
|
||||
virtual ~ActivateRepositoryCacheJob();
|
||||
|
||||
protected:
|
||||
virtual status_t Execute();
|
||||
|
||||
private:
|
||||
BEntry fFetchedRepoCacheEntry;
|
||||
BString fRepositoryName;
|
||||
BDirectory fTargetDirectory;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__PRIVATE__ACTIVATE_REPOSITORY_CACHE_JOB_H_
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__ACTIVATE_REPOSITORY_CONFIG_JOB_H_
|
||||
#define _HAIKU__PACKAGE__ACTIVATE_REPOSITORY_CONFIG_JOB_H_
|
||||
#ifndef _HAIKU__PACKAGE__PRIVATE__ACTIVATE_REPOSITORY_CONFIG_JOB_H_
|
||||
#define _HAIKU__PACKAGE__PRIVATE__ACTIVATE_REPOSITORY_CONFIG_JOB_H_
|
||||
|
||||
|
||||
#include <Directory.h>
|
||||
@ -17,6 +17,8 @@ namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
class ActivateRepositoryConfigJob : public Job {
|
||||
typedef Job inherited;
|
||||
@ -26,23 +28,31 @@ public:
|
||||
const Context& context,
|
||||
const BString& title,
|
||||
const BEntry& archivedRepoConfigEntry,
|
||||
const BString& repositoryBaseURL,
|
||||
const BDirectory& targetDirectory);
|
||||
virtual ~ActivateRepositoryConfigJob();
|
||||
|
||||
const BString& RepositoryName() const;
|
||||
|
||||
protected:
|
||||
virtual status_t Execute();
|
||||
virtual void Cleanup(status_t jobResult);
|
||||
|
||||
private:
|
||||
BEntry fArchivedRepoConfigEntry;
|
||||
BString fRepositoryBaseURL;
|
||||
BDirectory fTargetDirectory;
|
||||
BEntry fTargetEntry;
|
||||
|
||||
BString fRepositoryName;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__ACTIVATE_REPOSITORY_CONFIG_JOB_H_
|
||||
#endif // _HAIKU__PACKAGE__PRIVATE__ACTIVATE_REPOSITORY_CONFIG_JOB_H_
|
||||
|
61
headers/private/package/ChecksumAccessors.h
Normal file
61
headers/private/package/ChecksumAccessors.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__PRIVATE__CHECKSUM_ACCESSORS_H_
|
||||
#define _HAIKU__PACKAGE__PRIVATE__CHECKSUM_ACCESSORS_H_
|
||||
|
||||
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
class ChecksumAccessor {
|
||||
public:
|
||||
virtual ~ChecksumAccessor();
|
||||
|
||||
virtual status_t GetChecksum(BString& checksum) const = 0;
|
||||
};
|
||||
|
||||
|
||||
class ChecksumFileChecksumAccessor : public ChecksumAccessor {
|
||||
public:
|
||||
ChecksumFileChecksumAccessor(
|
||||
const BEntry& checksumFileEntry);
|
||||
|
||||
virtual status_t GetChecksum(BString& checksum) const;
|
||||
|
||||
private:
|
||||
BEntry fChecksumFileEntry;
|
||||
};
|
||||
|
||||
|
||||
class GeneralFileChecksumAccessor : public ChecksumAccessor {
|
||||
public:
|
||||
GeneralFileChecksumAccessor(
|
||||
const BEntry& fileEntry,
|
||||
bool skipMissingFile = false);
|
||||
|
||||
virtual status_t GetChecksum(BString& checksum) const;
|
||||
|
||||
private:
|
||||
BEntry fFileEntry;
|
||||
bool fSkipMissingFile;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__PRIVATE__CHECKSUM_ACCESSORS_H_
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__FETCH_FILE_JOB_H_
|
||||
#define _HAIKU__PACKAGE__FETCH_FILE_JOB_H_
|
||||
#ifndef _HAIKU__PACKAGE__PRIVATE__FETCH_FILE_JOB_H_
|
||||
#define _HAIKU__PACKAGE__PRIVATE__FETCH_FILE_JOB_H_
|
||||
|
||||
|
||||
#include <Entry.h>
|
||||
@ -16,6 +16,8 @@ namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
class FetchFileJob : public Job {
|
||||
typedef Job inherited;
|
||||
@ -37,9 +39,11 @@ private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__FETCH_FILE_JOB_H_
|
||||
#endif // _HAIKU__PACKAGE__PRIVATE__FETCH_FILE_JOB_H_
|
||||
|
@ -16,6 +16,8 @@ namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
class JobQueue : public JobStateListener {
|
||||
public:
|
||||
@ -43,6 +45,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__TEMP_ENTRY_MANAGER_H_
|
||||
#define _HAIKU__PACKAGE__TEMP_ENTRY_MANAGER_H_
|
||||
#ifndef _HAIKU__PACKAGE__PRIVATE__TEMPFILE_MANAGER_H_
|
||||
#define _HAIKU__PACKAGE__PRIVATE__TEMPFILE_MANAGER_H_
|
||||
|
||||
|
||||
#include <Directory.h>
|
||||
@ -16,11 +16,13 @@ namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
class TempEntryManager {
|
||||
|
||||
class TempfileManager {
|
||||
public:
|
||||
TempEntryManager();
|
||||
~TempEntryManager();
|
||||
TempfileManager();
|
||||
~TempfileManager();
|
||||
|
||||
void SetBaseDirectory(const BDirectory& baseDir);
|
||||
|
||||
@ -35,9 +37,11 @@ private:
|
||||
};
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__TEMP_ENTRY_MANAGER_H_
|
||||
#endif // _HAIKU__PACKAGE__PRIVATE__TEMPFILE_MANAGER_H_
|
57
headers/private/package/ValidateChecksumJob.h
Normal file
57
headers/private/package/ValidateChecksumJob.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__PRIVATE__VALIDATE_CHECKSUM_JOB_H_
|
||||
#define _HAIKU__PACKAGE__PRIVATE__VALIDATE_CHECKSUM_JOB_H_
|
||||
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/ChecksumAccessors.h>
|
||||
#include <package/Job.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
class ValidateChecksumJob : public Job {
|
||||
typedef Job inherited;
|
||||
|
||||
public:
|
||||
ValidateChecksumJob(
|
||||
const Context& context,
|
||||
const BString& title,
|
||||
ChecksumAccessor* expectedChecksumAccessor,
|
||||
ChecksumAccessor* realChecksumAccessor,
|
||||
bool failIfChecksumsDontMatch = true);
|
||||
virtual ~ValidateChecksumJob();
|
||||
|
||||
bool ChecksumsMatch() const;
|
||||
|
||||
protected:
|
||||
virtual status_t Execute();
|
||||
|
||||
private:
|
||||
ChecksumAccessor* fExpectedChecksumAccessor;
|
||||
ChecksumAccessor* fRealChecksumAccessor;
|
||||
bool fFailIfChecksumsDontMatch;
|
||||
|
||||
bool fChecksumsMatch;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__PRIVATE__VALIDATE_CHECKSUM_JOB_H_
|
@ -1,10 +1,11 @@
|
||||
SubDir HAIKU_TOP src bin pkgman ;
|
||||
|
||||
UsePrivateHeaders shared support ;
|
||||
UsePrivateHeaders support ;
|
||||
|
||||
BinCommand pkgman :
|
||||
command_add_repo.cpp
|
||||
command_list_repos.cpp
|
||||
command_refresh.cpp
|
||||
MyDecisionProvider.cpp
|
||||
MyJobStateListener.cpp
|
||||
pkgman.cpp
|
||||
|
@ -29,6 +29,11 @@ MyJobStateListener::JobSucceeded(Job* job)
|
||||
void
|
||||
MyJobStateListener::JobFailed(Job* job)
|
||||
{
|
||||
BString error = job->ErrorString();
|
||||
if (error.Length() > 0) {
|
||||
error.ReplaceAll("\n", "\n*** ");
|
||||
fprintf(stderr, "%s", error.String());
|
||||
}
|
||||
DIE(job->Result(), "failed!");
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,8 @@
|
||||
|
||||
#include <package/AddRepositoryRequest.h>
|
||||
#include <package/Context.h>
|
||||
#include <package/JobQueue.h>
|
||||
#include <package/RefreshRepositoryRequest.h>
|
||||
#include <package/Roster.h>
|
||||
|
||||
#include "MyDecisionProvider.h"
|
||||
#include "MyJobStateListener.h"
|
||||
@ -87,17 +88,32 @@ command_add_repo(int argc, const char* const* argv)
|
||||
|
||||
status_t result;
|
||||
for (int i = 0; i < urlCount; ++i) {
|
||||
AddRepositoryRequest request(context, repoURLs[i], asUserRepository);
|
||||
JobQueue jobQueue;
|
||||
result = request.CreateJobsToRun(jobQueue);
|
||||
AddRepositoryRequest addRequest(context, repoURLs[i], asUserRepository);
|
||||
result = addRequest.CreateInitialJobs();
|
||||
if (result != B_OK)
|
||||
DIE(result, "unable to create necessary jobs");
|
||||
|
||||
while (Job* job = jobQueue.Pop()) {
|
||||
while (Job* job = addRequest.PopRunnableJob()) {
|
||||
result = job->Run();
|
||||
delete job;
|
||||
if (result == B_CANCELED)
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BString repoName = addRequest.RepositoryName();
|
||||
Roster roster;
|
||||
RepositoryConfig repoConfig;
|
||||
roster.GetRepositoryConfig(repoName, &repoConfig);
|
||||
RefreshRepositoryRequest refreshRequest(context, repoConfig);
|
||||
result = refreshRequest.CreateInitialJobs();
|
||||
if (result != B_OK)
|
||||
DIE(result, "unable to create necessary jobs");
|
||||
|
||||
while (Job* job = refreshRequest.PopRunnableJob()) {
|
||||
result = job->Run();
|
||||
delete job;
|
||||
if (result == B_CANCELED)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,48 +43,6 @@ print_command_usage_and_exit(bool error)
|
||||
}
|
||||
|
||||
|
||||
typedef BObjectList<RepositoryConfig> RepositoryConfigList;
|
||||
|
||||
|
||||
struct RepositoryConfigCollector : public RepositoryConfigVisitor {
|
||||
RepositoryConfigCollector(RepositoryConfigList& _repositoryConfigList);
|
||||
|
||||
status_t operator()(const BEntry& entry);
|
||||
|
||||
RepositoryConfigList& repositoryConfigList;
|
||||
};
|
||||
|
||||
|
||||
RepositoryConfigCollector::RepositoryConfigCollector(
|
||||
RepositoryConfigList& _repositoryConfigList)
|
||||
:
|
||||
repositoryConfigList(_repositoryConfigList)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryConfigCollector::operator()(const BEntry& entry)
|
||||
{
|
||||
RepositoryConfig* repoConfig = new (std::nothrow) RepositoryConfig(entry);
|
||||
if (repoConfig == NULL)
|
||||
DIE(B_NO_MEMORY, "can't create repository-config object");
|
||||
|
||||
status_t result = repoConfig->InitCheck();
|
||||
if (result != B_OK) {
|
||||
BPath path;
|
||||
entry.GetPath(&path);
|
||||
WARN(result, "skipping repository-config '%s'", path.Path());
|
||||
delete repoConfig;
|
||||
|
||||
return B_OK;
|
||||
// let collector continue
|
||||
}
|
||||
|
||||
return repositoryConfigList.AddItem(repoConfig) ? B_OK : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
command_list_repos(int argc, const char* const* argv)
|
||||
{
|
||||
@ -121,24 +79,25 @@ command_list_repos(int argc, const char* const* argv)
|
||||
if (argc != optind)
|
||||
print_command_usage_and_exit(true);
|
||||
|
||||
BObjectList<BString> repositoryNames(20, true);
|
||||
Roster roster;
|
||||
RepositoryConfigList repositoryConfigs;
|
||||
RepositoryConfigCollector repositoryConfigCollector(repositoryConfigs);
|
||||
status_t result
|
||||
= roster.VisitCommonRepositoryConfigs(repositoryConfigCollector);
|
||||
if (result != B_OK && result != B_ENTRY_NOT_FOUND)
|
||||
DIE(result, "can't collect common repository configs");
|
||||
status_t result = roster.GetRepositoryNames(repositoryNames);
|
||||
if (result != B_OK)
|
||||
DIE(result, "can't collect repository names");
|
||||
|
||||
result = roster.VisitUserRepositoryConfigs(repositoryConfigCollector);
|
||||
if (result != B_OK && result != B_ENTRY_NOT_FOUND)
|
||||
DIE(result, "can't collect user's repository configs");
|
||||
|
||||
int32 count = repositoryConfigs.CountItems();
|
||||
for (int32 i = 0; i < count; ++i) {
|
||||
RepositoryConfig* repoConfig = repositoryConfigs.ItemAt(i);
|
||||
for (int i = 0; i < repositoryNames.CountItems(); ++i) {
|
||||
const BString& repoName = *(repositoryNames.ItemAt(i));
|
||||
RepositoryConfig repoConfig;
|
||||
result = roster.GetRepositoryConfig(repoName, &repoConfig);
|
||||
if (result != B_OK) {
|
||||
BPath path;
|
||||
repoConfig.Entry().GetPath(&path);
|
||||
WARN(result, "skipping repository-config '%s'", path.Path());
|
||||
continue;
|
||||
}
|
||||
printf(" %s %s\n",
|
||||
repoConfig->IsUserSpecific() ? "[User]" : " ",
|
||||
repoConfig->Name().String());
|
||||
repoConfig.IsUserSpecific() ? "[User]" : " ",
|
||||
repoConfig.Name().String());
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
119
src/bin/pkgman/command_refresh.cpp
Normal file
119
src/bin/pkgman/command_refresh.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefere.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Errors.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <package/Context.h>
|
||||
#include <package/RefreshRepositoryRequest.h>
|
||||
#include <package/Roster.h>
|
||||
|
||||
#include "MyDecisionProvider.h"
|
||||
#include "MyJobStateListener.h"
|
||||
#include "pkgman.h"
|
||||
|
||||
|
||||
using namespace Haiku::Package;
|
||||
|
||||
|
||||
// TODO: internationalization!
|
||||
|
||||
|
||||
static const char* kCommandUsage =
|
||||
"Usage: %s refresh [<repo-name> ...]\n"
|
||||
"Refreshes all or just the given repositories.\n"
|
||||
"\n"
|
||||
;
|
||||
|
||||
|
||||
static void
|
||||
print_command_usage_and_exit(bool error)
|
||||
{
|
||||
fprintf(error ? stderr : stdout, kCommandUsage, kProgramName);
|
||||
exit(error ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
command_refresh(int argc, const char* const* argv)
|
||||
{
|
||||
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, "hu", sLongOptions, NULL);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_command_usage_and_exit(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
print_command_usage_and_exit(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The remaining arguments are repo names.
|
||||
const char* const* repoArgs = argv + optind;
|
||||
int nameCount = argc - optind;
|
||||
|
||||
MyDecisionProvider decisionProvider;
|
||||
Context context(decisionProvider);
|
||||
MyJobStateListener listener;
|
||||
context.SetJobStateListener(&listener);
|
||||
|
||||
BObjectList<BString> repositoryNames(20, true);
|
||||
|
||||
Roster roster;
|
||||
if (nameCount == 0) {
|
||||
status_t result = roster.GetRepositoryNames(repositoryNames);
|
||||
if (result != B_OK)
|
||||
DIE(result, "can't collect repository names");
|
||||
} else {
|
||||
for (int i = 0; i < nameCount; ++i) {
|
||||
BString* repoName = new (std::nothrow) BString(repoArgs[i]);
|
||||
if (repoName == NULL)
|
||||
DIE(B_NO_MEMORY, "can't allocate repository name");
|
||||
repositoryNames.AddItem(repoName);
|
||||
}
|
||||
}
|
||||
|
||||
status_t result;
|
||||
for (int i = 0; i < repositoryNames.CountItems(); ++i) {
|
||||
const BString& repoName = *(repositoryNames.ItemAt(i));
|
||||
RepositoryConfig repoConfig;
|
||||
result = roster.GetRepositoryConfig(repoName, &repoConfig);
|
||||
if (result != B_OK) {
|
||||
BPath path;
|
||||
repoConfig.Entry().GetPath(&path);
|
||||
WARN(result, "skipping repository-config '%s'", path.Path());
|
||||
continue;
|
||||
}
|
||||
RefreshRepositoryRequest refreshRequest(context, repoConfig);
|
||||
result = refreshRequest.CreateInitialJobs();
|
||||
if (result != B_OK)
|
||||
DIE(result, "unable to create necessary jobs");
|
||||
|
||||
while (Job* job = refreshRequest.PopRunnableJob()) {
|
||||
result = job->Run();
|
||||
delete job;
|
||||
if (result != B_OK)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -24,11 +24,14 @@ static const char* kUsage =
|
||||
" add-repo <repo-base-url>\n"
|
||||
" Adds the repository with the given <repo-base-URL>.\n"
|
||||
"\n"
|
||||
" drop-repo <repo-name>\n"
|
||||
" Drops the repository with the given <repo-name>.\n"
|
||||
"\n"
|
||||
" list-repos\n"
|
||||
" Lists all repositories.\n"
|
||||
"\n"
|
||||
" drop-repo <repo-name>\n"
|
||||
" Drops the repository with the given <repo-name>.\n"
|
||||
" refresh [<repo-name> ...]\n"
|
||||
" Refreshes all or just the given repositories.\n"
|
||||
"\n"
|
||||
"Common Options:\n"
|
||||
" -h, --help - Print this usage info.\n"
|
||||
@ -50,15 +53,18 @@ main(int argc, const char* const* argv)
|
||||
print_usage_and_exit(true);
|
||||
|
||||
const char* command = argv[1];
|
||||
if (strcmp(command, "add-repo") == 0)
|
||||
if (strcmp(command, "add-repo") == 0 || strcmp(command, "ar") == 0)
|
||||
return command_add_repo(argc - 1, argv + 1);
|
||||
|
||||
// if (strcmp(command, "drop-repo") == 0)
|
||||
// return command_drop_repo(argc - 1, argv + 1);
|
||||
|
||||
if (strcmp(command, "list-repos") == 0)
|
||||
if (strcmp(command, "list-repos") == 0 || strcmp(command, "lr") == 0)
|
||||
return command_list_repos(argc - 1, argv + 1);
|
||||
|
||||
if (strcmp(command, "refresh") == 0)
|
||||
return command_refresh(argc - 1, argv + 1);
|
||||
|
||||
// if (strcmp(command, "search") == 0)
|
||||
// return command_search(argc - 1, argv + 1);
|
||||
|
||||
|
@ -38,6 +38,7 @@ void print_usage_and_exit(bool error);
|
||||
int command_add_repo(int argc, const char* const* argv);
|
||||
int command_drop_repo(int argc, const char* const* argv);
|
||||
int command_list_repos(int argc, const char* const* argv);
|
||||
int command_refresh(int argc, const char* const* argv);
|
||||
|
||||
|
||||
#endif // PKGMAN_H
|
||||
|
59
src/kits/package/ActivateRepositoryCacheJob.cpp
Normal file
59
src/kits/package/ActivateRepositoryCacheJob.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/ActivateRepositoryCacheJob.h>
|
||||
|
||||
#include <File.h>
|
||||
|
||||
#include <package/Context.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
ActivateRepositoryCacheJob::ActivateRepositoryCacheJob(const Context& context,
|
||||
const BString& title, const BEntry& fetchedRepoCacheEntry,
|
||||
const BString& repositoryName, const BDirectory& targetDirectory)
|
||||
:
|
||||
inherited(context, title),
|
||||
fFetchedRepoCacheEntry(fetchedRepoCacheEntry),
|
||||
fRepositoryName(repositoryName),
|
||||
fTargetDirectory(targetDirectory)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ActivateRepositoryCacheJob::~ActivateRepositoryCacheJob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActivateRepositoryCacheJob::Execute()
|
||||
{
|
||||
status_t result = fFetchedRepoCacheEntry.MoveTo(&fTargetDirectory,
|
||||
fRepositoryName.String(), true);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
// TODO: propagate some repository attributes to file attributes
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
@ -9,8 +9,6 @@
|
||||
|
||||
#include <package/ActivateRepositoryConfigJob.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <File.h>
|
||||
|
||||
#include <package/Context.h>
|
||||
@ -21,13 +19,16 @@ namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
ActivateRepositoryConfigJob::ActivateRepositoryConfigJob(const Context& context,
|
||||
const BString& title, const BEntry& archivedRepoConfigEntry,
|
||||
const BDirectory& targetDirectory)
|
||||
const BString& repositoryBaseURL, const BDirectory& targetDirectory)
|
||||
:
|
||||
inherited(context, title),
|
||||
fArchivedRepoConfigEntry(archivedRepoConfigEntry),
|
||||
fRepositoryBaseURL(repositoryBaseURL),
|
||||
fTargetDirectory(targetDirectory)
|
||||
{
|
||||
}
|
||||
@ -69,9 +70,14 @@ ActivateRepositoryConfigJob::Execute()
|
||||
}
|
||||
}
|
||||
|
||||
// inject the URL that was actually used and write the config file
|
||||
repoConfig->SetURL(fRepositoryBaseURL);
|
||||
if ((result = repoConfig->StoreAsConfigFile(fTargetEntry)) != B_OK)
|
||||
return result;
|
||||
|
||||
// store name of activated repository as result
|
||||
fRepositoryName = repoConfig->Name();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -85,6 +91,15 @@ ActivateRepositoryConfigJob::Cleanup(status_t jobResult)
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
ActivateRepositoryConfigJob::RepositoryName() const
|
||||
{
|
||||
return fRepositoryName;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
@ -23,12 +23,16 @@ namespace Haiku {
|
||||
namespace Package {
|
||||
|
||||
|
||||
using namespace Private;
|
||||
|
||||
|
||||
AddRepositoryRequest::AddRepositoryRequest(const Context& context,
|
||||
const BString& repositoryURL, bool asUserRepository)
|
||||
const BString& repositoryBaseURL, bool asUserRepository)
|
||||
:
|
||||
inherited(context),
|
||||
fRepositoryURL(repositoryURL),
|
||||
fAsUserRepository(asUserRepository)
|
||||
fRepositoryBaseURL(repositoryBaseURL),
|
||||
fAsUserRepository(asUserRepository),
|
||||
fActivateJob(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -39,16 +43,16 @@ AddRepositoryRequest::~AddRepositoryRequest()
|
||||
|
||||
|
||||
status_t
|
||||
AddRepositoryRequest::CreateJobsToRun(JobQueue& jobQueue)
|
||||
AddRepositoryRequest::CreateInitialJobs()
|
||||
{
|
||||
BEntry tempEntry
|
||||
= GetContext().GetTempEntryManager().Create("repoconfig-");
|
||||
FetchFileJob* fetchJob = new (std::nothrow) FetchFileJob(GetContext(),
|
||||
BString("Fetching repository-config from ") << fRepositoryURL,
|
||||
fRepositoryURL, tempEntry);
|
||||
BEntry tempEntry = fContext.GetTempfileManager().Create("repoheader-");
|
||||
BString repoHeaderURL = BString(fRepositoryBaseURL) << "/" << "repo.header";
|
||||
FetchFileJob* fetchJob = new (std::nothrow) FetchFileJob(fContext,
|
||||
BString("Fetching repository header from ") << fRepositoryBaseURL,
|
||||
repoHeaderURL, tempEntry);
|
||||
if (fetchJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
status_t result = QueueJob(fetchJob, jobQueue);
|
||||
status_t result = QueueJob(fetchJob);
|
||||
if (result != B_OK) {
|
||||
delete fetchJob;
|
||||
return result;
|
||||
@ -63,21 +67,37 @@ AddRepositoryRequest::CreateJobsToRun(JobQueue& jobQueue)
|
||||
return result;
|
||||
BDirectory targetDirectory(targetRepoConfigPath.Path());
|
||||
ActivateRepositoryConfigJob* activateJob
|
||||
= new (std::nothrow) ActivateRepositoryConfigJob(GetContext(),
|
||||
BString("Activating repository-config from ") << fRepositoryURL,
|
||||
tempEntry, targetDirectory);
|
||||
= new (std::nothrow) ActivateRepositoryConfigJob(fContext,
|
||||
BString("Activating repository config from ") << fRepositoryBaseURL,
|
||||
tempEntry, fRepositoryBaseURL, targetDirectory);
|
||||
if (activateJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
activateJob->AddDependency(fetchJob);
|
||||
if ((result = QueueJob(activateJob, jobQueue)) != B_OK) {
|
||||
if ((result = QueueJob(activateJob)) != B_OK) {
|
||||
delete activateJob;
|
||||
return result;
|
||||
}
|
||||
fActivateJob = activateJob;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AddRepositoryRequest::JobSucceeded(Job* job)
|
||||
{
|
||||
if (job == fActivateJob)
|
||||
fRepositoryName = fActivateJob->RepositoryName();
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
AddRepositoryRequest::RepositoryName() const
|
||||
{
|
||||
return fRepositoryName;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
33
src/kits/package/Attributes.cpp
Normal file
33
src/kits/package/Attributes.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/Attributes.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
// attributes used in package and as file attribute, too
|
||||
const char* kNameAttribute = "PKG:name";
|
||||
const char* kPlatformAttribute = "PKG:platform";
|
||||
const char* kVendorAttribute = "PKG:vendor";
|
||||
const char* kVersionAttribute = "PKG:version";
|
||||
|
||||
// attributes kept local to packages
|
||||
const char* kCopyrightAttribute = "PKG:copyright";
|
||||
const char* kLicenseAttribute = "PKG:license";
|
||||
const char* kProvidesAttribute = "PKG:provides";
|
||||
const char* kRequiresAttribute = "PKG:requires";
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
136
src/kits/package/ChecksumAccessors.cpp
Normal file
136
src/kits/package/ChecksumAccessors.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <File.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
#include <SHA256.h>
|
||||
|
||||
#include <package/ChecksumAccessors.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
#define NIBBLE_AS_HEX(nibble) \
|
||||
(nibble >= 10 ? 'a' + nibble - 10 : '0' + nibble)
|
||||
|
||||
|
||||
ChecksumAccessor::~ChecksumAccessor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ChecksumFileChecksumAccessor::ChecksumFileChecksumAccessor(
|
||||
const BEntry& checksumFileEntry)
|
||||
:
|
||||
fChecksumFileEntry(checksumFileEntry)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ChecksumFileChecksumAccessor::GetChecksum(BString& checksum) const
|
||||
{
|
||||
BFile checksumFile(&fChecksumFileEntry, B_READ_ONLY);
|
||||
status_t result = checksumFile.InitCheck();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
const int kSHA256ChecksumHexDumpSize = 64;
|
||||
char* buffer = checksum.LockBuffer(kSHA256ChecksumHexDumpSize);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
ssize_t bytesRead = checksumFile.Read(buffer, kSHA256ChecksumHexDumpSize);
|
||||
buffer[kSHA256ChecksumHexDumpSize] = '\0';
|
||||
checksum.UnlockBuffer(kSHA256ChecksumHexDumpSize);
|
||||
if (bytesRead < 0)
|
||||
return bytesRead;
|
||||
if (bytesRead != kSHA256ChecksumHexDumpSize)
|
||||
return B_IO_ERROR;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
GeneralFileChecksumAccessor::GeneralFileChecksumAccessor(
|
||||
const BEntry& fileEntry, bool skipMissingFile)
|
||||
:
|
||||
fFileEntry(fileEntry),
|
||||
fSkipMissingFile(skipMissingFile)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GeneralFileChecksumAccessor::GetChecksum(BString& checksum) const
|
||||
{
|
||||
SHA256 sha;
|
||||
|
||||
checksum.Truncate(0);
|
||||
|
||||
{
|
||||
BFile file(&fFileEntry, B_READ_ONLY);
|
||||
status_t result = file.InitCheck();
|
||||
if (result != B_OK) {
|
||||
if (result == B_ENTRY_NOT_FOUND && fSkipMissingFile)
|
||||
return B_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
off_t fileSize;
|
||||
if ((result = file.GetSize(&fileSize)) != B_OK)
|
||||
return result;
|
||||
|
||||
const int kBlockSize = 64 * 1024;
|
||||
void* buffer = malloc(kBlockSize);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
MemoryDeleter memoryDeleter(buffer);
|
||||
|
||||
off_t handledSize = 0;
|
||||
while (handledSize < fileSize) {
|
||||
ssize_t bytesRead = file.Read(buffer, kBlockSize);
|
||||
if (bytesRead < 0)
|
||||
return bytesRead;
|
||||
|
||||
sha.Update(buffer, bytesRead);
|
||||
|
||||
handledSize += bytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
const int kSHA256ChecksumSize = sha.DigestLength();
|
||||
char* buffer = checksum.LockBuffer(2 * kSHA256ChecksumSize);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
const uint8* digest = sha.Digest();
|
||||
for (int i = 0; i < kSHA256ChecksumSize; ++i) {
|
||||
uint8 highNibble = (digest[i] & 0xF0) >> 4;
|
||||
buffer[i * 2] = NIBBLE_AS_HEX(highNibble);
|
||||
uint8 lowNibble = digest[i] & 0x0F;
|
||||
buffer[1 + i * 2] = NIBBLE_AS_HEX(lowNibble);
|
||||
}
|
||||
buffer[2 * kSHA256ChecksumSize] = '\0';
|
||||
checksum.UnlockBuffer(2 * kSHA256ChecksumSize);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
@ -38,7 +38,7 @@ Context::Context(DecisionProvider& decisionProvider)
|
||||
BString contextName = BString("pkgkit-context-") << find_thread(NULL);
|
||||
BDirectory baseDirectory;
|
||||
tempDirectory.CreateDirectory(contextName.String(), &baseDirectory);
|
||||
fTempEntryManager.SetBaseDirectory(baseDirectory);
|
||||
fTempfileManager.SetBaseDirectory(baseDirectory);
|
||||
}
|
||||
|
||||
|
||||
@ -47,10 +47,10 @@ Context::~Context()
|
||||
}
|
||||
|
||||
|
||||
TempEntryManager&
|
||||
Context::GetTempEntryManager() const
|
||||
TempfileManager&
|
||||
Context::GetTempfileManager() const
|
||||
{
|
||||
return fTempEntryManager;
|
||||
return fTempfileManager;
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,6 +19,8 @@ namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
FetchFileJob::FetchFileJob(const Context& context, const BString& title,
|
||||
const BString& fileURL, const BEntry& targetEntry)
|
||||
@ -65,6 +67,8 @@ FetchFileJob::Cleanup(status_t jobResult)
|
||||
}
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
@ -1,19 +1,26 @@
|
||||
SubDir HAIKU_TOP src kits package ;
|
||||
|
||||
UsePrivateHeaders package ;
|
||||
UsePrivateHeaders package shared ;
|
||||
|
||||
SharedLibrary libpackage.so
|
||||
:
|
||||
ActivateRepositoryCacheJob.cpp
|
||||
ActivateRepositoryConfigJob.cpp
|
||||
AddRepositoryRequest.cpp
|
||||
Attributes.cpp
|
||||
ChecksumAccessors.cpp
|
||||
Context.cpp
|
||||
FetchFileJob.cpp
|
||||
Job.cpp
|
||||
JobQueue.cpp
|
||||
RefreshRepositoryRequest.cpp
|
||||
RepositoryCache.cpp
|
||||
RepositoryConfig.cpp
|
||||
# RepositoryHeader.cpp
|
||||
Request.cpp
|
||||
Roster.cpp
|
||||
TempEntryManager.cpp
|
||||
TempfileManager.cpp
|
||||
ValidateChecksumJob.cpp
|
||||
:
|
||||
be $(TARGET_LIBSTDC++)
|
||||
libshared.a be $(TARGET_LIBSTDC++)
|
||||
;
|
||||
|
@ -94,6 +94,20 @@ Job::Result() const
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
Job::ErrorString() const
|
||||
{
|
||||
return fErrorString;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Job::SetErrorString(const BString& error)
|
||||
{
|
||||
fErrorString = error;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::Run()
|
||||
{
|
||||
|
@ -20,6 +20,8 @@ namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
struct JobQueue::JobPriorityLess {
|
||||
bool operator()(const Job* left, const Job* right) const;
|
||||
@ -150,6 +152,8 @@ JobQueue::_UpdateDependantJobsOf(Job* job)
|
||||
}
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
171
src/kits/package/RefreshRepositoryRequest.cpp
Normal file
171
src/kits/package/RefreshRepositoryRequest.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/RefreshRepositoryRequest.h>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <package/ActivateRepositoryCacheJob.h>
|
||||
#include <package/ChecksumAccessors.h>
|
||||
#include <package/ValidateChecksumJob.h>
|
||||
#include <package/FetchFileJob.h>
|
||||
#include <package/JobQueue.h>
|
||||
#include <package/RepositoryCache.h>
|
||||
#include <package/RepositoryConfig.h>
|
||||
#include <package/Roster.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
using namespace Private;
|
||||
|
||||
|
||||
RefreshRepositoryRequest::RefreshRepositoryRequest(const Context& context,
|
||||
const RepositoryConfig& repoConfig)
|
||||
:
|
||||
inherited(context),
|
||||
fRepoConfig(repoConfig)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RefreshRepositoryRequest::~RefreshRepositoryRequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RefreshRepositoryRequest::CreateInitialJobs()
|
||||
{
|
||||
Roster roster;
|
||||
status_t result = fRepoConfig.InitCheck();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
// fetch the current checksum and compare with our cache's checksum,
|
||||
// if they differ, fetch the updated cache
|
||||
fFetchedChecksumFile
|
||||
= fContext.GetTempfileManager().Create("repochecksum-");
|
||||
BString repoChecksumURL
|
||||
= BString(fRepoConfig.URL()) << "/" << "repo.sha256";
|
||||
FetchFileJob* fetchChecksumJob = new (std::nothrow) FetchFileJob(
|
||||
fContext,
|
||||
BString("Fetching repository checksum from ") << fRepoConfig.URL(),
|
||||
repoChecksumURL, fFetchedChecksumFile);
|
||||
if (fetchChecksumJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
if ((result = QueueJob(fetchChecksumJob)) != B_OK) {
|
||||
delete fetchChecksumJob;
|
||||
return result;
|
||||
}
|
||||
|
||||
RepositoryCache repoCache;
|
||||
roster.GetRepositoryCache(fRepoConfig.Name(), &repoCache);
|
||||
|
||||
ValidateChecksumJob* validateChecksumJob
|
||||
= new (std::nothrow) ValidateChecksumJob(fContext,
|
||||
BString("Validating checksum for ") << fRepoConfig.Name(),
|
||||
new (std::nothrow) ChecksumFileChecksumAccessor(
|
||||
fFetchedChecksumFile),
|
||||
new (std::nothrow) GeneralFileChecksumAccessor(repoCache.Entry(),
|
||||
true),
|
||||
false);
|
||||
if (validateChecksumJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
validateChecksumJob->AddDependency(fetchChecksumJob);
|
||||
if ((result = QueueJob(validateChecksumJob)) != B_OK) {
|
||||
delete validateChecksumJob;
|
||||
return result;
|
||||
}
|
||||
fValidateChecksumJob = validateChecksumJob;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RefreshRepositoryRequest::JobSucceeded(Job* job)
|
||||
{
|
||||
if (job == fValidateChecksumJob
|
||||
&& !fValidateChecksumJob->ChecksumsMatch()) {
|
||||
// the remote repo cache has a different checksum, we fetch it
|
||||
fValidateChecksumJob = NULL;
|
||||
// don't re-trigger fetching if anything goes wrong, fail instead
|
||||
_FetchRepositoryCache();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RefreshRepositoryRequest::_FetchRepositoryCache()
|
||||
{
|
||||
// download repository cache and put it in either the common/user cache
|
||||
// path, depending on where the corresponding repo-config lives
|
||||
|
||||
// job fetching the cache
|
||||
BEntry tempRepoCache = fContext.GetTempfileManager().Create("repocache-");
|
||||
BString repoCacheURL = BString(fRepoConfig.URL()) << "/" << "repo";
|
||||
FetchFileJob* fetchCacheJob = new (std::nothrow) FetchFileJob(fContext,
|
||||
BString("Fetching repository-cache from ") << fRepoConfig.URL(),
|
||||
repoCacheURL, tempRepoCache);
|
||||
if (fetchCacheJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
status_t result = QueueJob(fetchCacheJob);
|
||||
if (result != B_OK) {
|
||||
delete fetchCacheJob;
|
||||
return result;
|
||||
}
|
||||
|
||||
// job validating the cache's checksum
|
||||
ValidateChecksumJob* validateChecksumJob
|
||||
= new (std::nothrow) ValidateChecksumJob(fContext,
|
||||
BString("Validating checksum for ") << fRepoConfig.Name(),
|
||||
new (std::nothrow) ChecksumFileChecksumAccessor(
|
||||
fFetchedChecksumFile),
|
||||
new (std::nothrow) GeneralFileChecksumAccessor(tempRepoCache));
|
||||
if (validateChecksumJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
validateChecksumJob->AddDependency(fetchCacheJob);
|
||||
if ((result = QueueJob(validateChecksumJob)) != B_OK) {
|
||||
delete validateChecksumJob;
|
||||
return result;
|
||||
}
|
||||
|
||||
// job activating the cache
|
||||
BPath targetRepoCachePath;
|
||||
Roster roster;
|
||||
result = fRepoConfig.IsUserSpecific()
|
||||
? roster.GetUserRepositoryCachePath(&targetRepoCachePath, true)
|
||||
: roster.GetCommonRepositoryCachePath(&targetRepoCachePath, true);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
BDirectory targetDirectory(targetRepoCachePath.Path());
|
||||
ActivateRepositoryCacheJob* activateJob
|
||||
= new (std::nothrow) ActivateRepositoryCacheJob(fContext,
|
||||
BString("Activating repository cache for ") << fRepoConfig.Name(),
|
||||
tempRepoCache, fRepoConfig.Name(), targetDirectory);
|
||||
if (activateJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
activateJob->AddDependency(validateChecksumJob);
|
||||
if ((result = QueueJob(activateJob)) != B_OK) {
|
||||
delete activateJob;
|
||||
return result;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
106
src/kits/package/RepositoryCache.cpp
Normal file
106
src/kits/package/RepositoryCache.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/RepositoryCache.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
RepositoryCache::RepositoryCache()
|
||||
:
|
||||
fInitStatus(B_NO_INIT),
|
||||
fIsUserSpecific(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RepositoryCache::RepositoryCache(const BEntry& entry)
|
||||
{
|
||||
SetTo(entry);
|
||||
}
|
||||
|
||||
|
||||
RepositoryCache::~RepositoryCache()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryCache::InitCheck() const
|
||||
{
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
|
||||
const BEntry&
|
||||
RepositoryCache::Entry() const
|
||||
{
|
||||
return fEntry;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RepositoryCache::IsUserSpecific() const
|
||||
{
|
||||
return fIsUserSpecific;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryCache::SetIsUserSpecific(bool isUserSpecific)
|
||||
{
|
||||
fIsUserSpecific = isUserSpecific;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryCache::SetTo(const BEntry& entry)
|
||||
{
|
||||
fEntry = entry;
|
||||
fInitStatus = B_NO_INIT;
|
||||
|
||||
BFile file(&entry, B_READ_ONLY);
|
||||
status_t result = file.InitCheck();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
BMessage headerMsg;
|
||||
if ((result = headerMsg.Unflatten(&file)) != B_OK)
|
||||
return result;
|
||||
|
||||
// TODO: unarchive header and read packages
|
||||
|
||||
BPath userSettingsPath;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &userSettingsPath) == B_OK) {
|
||||
BDirectory userSettingsDir(userSettingsPath.Path());
|
||||
fIsUserSpecific = userSettingsDir.Contains(&entry);
|
||||
} else
|
||||
fIsUserSpecific = false;
|
||||
|
||||
fInitStatus = B_OK;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include <Directory.h>
|
||||
#include <driver_settings.h>
|
||||
#include <Entry.h>
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
@ -26,6 +25,7 @@ namespace Haiku {
|
||||
namespace Package {
|
||||
|
||||
|
||||
const uint8 RepositoryConfig::kDefaultPriority = 50;
|
||||
const char* RepositoryConfig::kNameField = "name";
|
||||
const char* RepositoryConfig::kURLField = "url";
|
||||
const char* RepositoryConfig::kPriorityField = "priority";
|
||||
@ -42,7 +42,7 @@ RepositoryConfig::RepositoryConfig()
|
||||
|
||||
RepositoryConfig::RepositoryConfig(const BEntry& entry)
|
||||
{
|
||||
fInitStatus = _InitFrom(entry);
|
||||
SetTo(entry);
|
||||
}
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ RepositoryConfig::RepositoryConfig(BMessage* data)
|
||||
:
|
||||
inherited(data)
|
||||
{
|
||||
fInitStatus = _InitFrom(data);
|
||||
SetTo(data);
|
||||
}
|
||||
|
||||
|
||||
@ -109,7 +109,6 @@ RepositoryConfig::StoreAsConfigFile(const BEntry& entry) const
|
||||
|
||||
BString configString;
|
||||
configString
|
||||
<< "name=" << fName << "\n"
|
||||
<< "url=" << fURL << "\n"
|
||||
<< "priority=" << fPriority << "\n";
|
||||
|
||||
@ -128,6 +127,91 @@ RepositoryConfig::InitCheck() const
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryConfig::SetTo(const BEntry& entry)
|
||||
{
|
||||
fEntry = entry;
|
||||
fInitStatus = B_NO_INIT;
|
||||
|
||||
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)
|
||||
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* url = get_driver_parameter(settingsHandle, "url", NULL, NULL);
|
||||
const char* priorityString
|
||||
= get_driver_parameter(settingsHandle, "priority", NULL, NULL);
|
||||
|
||||
unload_driver_settings(settingsHandle);
|
||||
|
||||
if (url == NULL || *url == '\0')
|
||||
return B_BAD_DATA;
|
||||
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
if ((result = entry.GetName(name)) != B_OK)
|
||||
return result;
|
||||
|
||||
fName = name;
|
||||
fURL = url;
|
||||
fPriority = priorityString == NULL
|
||||
? kDefaultPriority : atoi(priorityString);
|
||||
|
||||
BPath userSettingsPath;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &userSettingsPath) == B_OK) {
|
||||
BDirectory userSettingsDir(userSettingsPath.Path());
|
||||
fIsUserSpecific = userSettingsDir.Contains(&entry);
|
||||
} else
|
||||
fIsUserSpecific = false;
|
||||
|
||||
fInitStatus = B_OK;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryConfig::SetTo(const BMessage* data)
|
||||
{
|
||||
fInitStatus = B_NO_INIT;
|
||||
|
||||
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, &fURL)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->FindUInt8(kPriorityField, &fPriority)) != B_OK)
|
||||
return result;
|
||||
|
||||
fIsUserSpecific = false;
|
||||
|
||||
fInitStatus = B_OK;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
RepositoryConfig::Name() const
|
||||
{
|
||||
@ -156,6 +240,13 @@ RepositoryConfig::IsUserSpecific() const
|
||||
}
|
||||
|
||||
|
||||
const BEntry&
|
||||
RepositoryConfig::Entry() const
|
||||
{
|
||||
return fEntry;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryConfig::SetName(const BString& name)
|
||||
{
|
||||
@ -184,78 +275,6 @@ RepositoryConfig::SetIsUserSpecific(bool isUserSpecific)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryConfig::_InitFrom(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)
|
||||
return (result >= 0) ? B_ERROR : result;
|
||||
|
||||
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* priorityString
|
||||
= get_driver_parameter(settingsHandle, "priority", NULL, NULL);
|
||||
|
||||
unload_driver_settings(settingsHandle);
|
||||
|
||||
if (name == NULL || *name == '\0' || url == NULL || *url == '\0')
|
||||
return B_BAD_DATA;
|
||||
|
||||
fName = name;
|
||||
fURL = url;
|
||||
fPriority = priorityString == NULL
|
||||
? kDefaultPriority : atoi(priorityString);
|
||||
|
||||
BPath userSettingsPath;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &userSettingsPath) == B_OK) {
|
||||
BDirectory userSettingsDir(userSettingsPath.Path());
|
||||
fIsUserSpecific = userSettingsDir.Contains(&entry);
|
||||
} else
|
||||
fIsUserSpecific = false;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryConfig::_InitFrom(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, &fURL)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->FindUInt8(kPriorityField, &fPriority)) != B_OK)
|
||||
return result;
|
||||
|
||||
fIsUserSpecific = false;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include <package/Context.h>
|
||||
#include <package/Job.h>
|
||||
#include <package/JobQueue.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
@ -21,7 +20,8 @@ namespace Package {
|
||||
|
||||
Request::Request(const Context& context)
|
||||
:
|
||||
fContext(context)
|
||||
fContext(context),
|
||||
fJobQueue()
|
||||
{
|
||||
}
|
||||
|
||||
@ -31,21 +31,23 @@ Request::~Request()
|
||||
}
|
||||
|
||||
|
||||
const Context&
|
||||
Request::GetContext() const
|
||||
Job*
|
||||
Request::PopRunnableJob()
|
||||
{
|
||||
return fContext;
|
||||
return fJobQueue.Pop();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Request::QueueJob(Job* job, JobQueue& jobQueue) const
|
||||
Request::QueueJob(Job* job)
|
||||
{
|
||||
job->AddStateListener(this);
|
||||
|
||||
JobStateListener* listener = fContext.GetJobStateListener();
|
||||
if (listener != NULL)
|
||||
job->AddStateListener(listener);
|
||||
|
||||
return jobQueue.AddJob(job);
|
||||
return fJobQueue.AddJob(job);
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,8 +14,12 @@
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <ObjectList.h>
|
||||
#include <Path.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/RepositoryCache.h>
|
||||
#include <package/RepositoryConfig.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
@ -36,48 +40,28 @@ Roster::~Roster()
|
||||
status_t
|
||||
Roster::GetCommonRepositoryConfigPath(BPath* path, bool create) const
|
||||
{
|
||||
if (path == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t result = find_directory(B_COMMON_SETTINGS_DIRECTORY, path);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
if ((result = path->Append("package-repositories")) != B_OK)
|
||||
return result;
|
||||
|
||||
if (create) {
|
||||
BEntry entry(path->Path(), true);
|
||||
if (!entry.Exists()) {
|
||||
if (mkdir(path->Path(), 0755) != 0)
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
return _GetRepositoryPath(path, create, B_COMMON_SETTINGS_DIRECTORY);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Roster::GetUserRepositoryConfigPath(BPath* path, bool create) const
|
||||
{
|
||||
if (path == NULL)
|
||||
return B_BAD_VALUE;
|
||||
return _GetRepositoryPath(path, create, B_USER_SETTINGS_DIRECTORY);
|
||||
}
|
||||
|
||||
status_t result = find_directory(B_USER_SETTINGS_DIRECTORY, path);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
if ((result = path->Append("package-repositories")) != B_OK)
|
||||
return result;
|
||||
|
||||
if (create) {
|
||||
BEntry entry(path->Path(), true);
|
||||
if (!entry.Exists()) {
|
||||
if (mkdir(path->Path(), 0755) != 0)
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
status_t
|
||||
Roster::GetCommonRepositoryCachePath(BPath* path, bool create) const
|
||||
{
|
||||
return _GetRepositoryPath(path, create, B_COMMON_CACHE_DIRECTORY);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
status_t
|
||||
Roster::GetUserRepositoryCachePath(BPath* path, bool create) const
|
||||
{
|
||||
return _GetRepositoryPath(path, create, B_USER_CACHE_DIRECTORY);
|
||||
}
|
||||
|
||||
|
||||
@ -87,10 +71,10 @@ Roster::VisitCommonRepositoryConfigs(RepositoryConfigVisitor& visitor)
|
||||
BPath commonRepositoryConfigPath;
|
||||
status_t result
|
||||
= GetCommonRepositoryConfigPath(&commonRepositoryConfigPath);
|
||||
if (result == B_OK)
|
||||
result = _VisitRepositoryConfigs(commonRepositoryConfigPath, visitor);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
return result;
|
||||
return _VisitRepositoryConfigs(commonRepositoryConfigPath, visitor);
|
||||
}
|
||||
|
||||
|
||||
@ -99,10 +83,122 @@ Roster::VisitUserRepositoryConfigs(RepositoryConfigVisitor& visitor)
|
||||
{
|
||||
BPath userRepositoryConfigPath;
|
||||
status_t result = GetUserRepositoryConfigPath(&userRepositoryConfigPath);
|
||||
if (result == B_OK)
|
||||
result = _VisitRepositoryConfigs(userRepositoryConfigPath, visitor);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
return result;
|
||||
return _VisitRepositoryConfigs(userRepositoryConfigPath, visitor);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Roster::GetRepositoryNames(BObjectList<BString>& names)
|
||||
{
|
||||
struct RepositoryNameCollector : public RepositoryConfigVisitor {
|
||||
RepositoryNameCollector(BObjectList<BString>& _names)
|
||||
: names(_names)
|
||||
{
|
||||
}
|
||||
status_t operator()(const BEntry& entry)
|
||||
{
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
status_t result = entry.GetName(name);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
int32 count = names.CountItems();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (names.ItemAt(i)->Compare(name) == 0)
|
||||
return B_OK;
|
||||
}
|
||||
names.AddItem(new (std::nothrow) BString(name));
|
||||
return B_OK;
|
||||
}
|
||||
BObjectList<BString>& names;
|
||||
};
|
||||
RepositoryNameCollector repositoryNameCollector(names);
|
||||
status_t result = VisitUserRepositoryConfigs(repositoryNameCollector);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
return VisitCommonRepositoryConfigs(repositoryNameCollector);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Roster::GetRepositoryCache(const BString& name,
|
||||
RepositoryCache* repositoryCache)
|
||||
{
|
||||
if (repositoryCache == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// user path has higher precedence than common path
|
||||
BPath path;
|
||||
status_t result = GetUserRepositoryCachePath(&path);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
path.Append(name.String());
|
||||
|
||||
BEntry repoCacheEntry(path.Path());
|
||||
if (repoCacheEntry.Exists())
|
||||
return repositoryCache->SetTo(repoCacheEntry);
|
||||
|
||||
if ((result = GetCommonRepositoryCachePath(&path)) != B_OK)
|
||||
return result;
|
||||
path.Append(name.String());
|
||||
|
||||
repoCacheEntry.SetTo(path.Path());
|
||||
return repositoryCache->SetTo(repoCacheEntry);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Roster::GetRepositoryConfig(const BString& name,
|
||||
RepositoryConfig* repositoryConfig)
|
||||
{
|
||||
if (repositoryConfig == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// user path has higher precedence than common path
|
||||
BPath path;
|
||||
status_t result = GetUserRepositoryConfigPath(&path);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
path.Append(name.String());
|
||||
|
||||
BEntry repoConfigEntry(path.Path());
|
||||
if (repoConfigEntry.Exists())
|
||||
return repositoryConfig->SetTo(repoConfigEntry);
|
||||
|
||||
if ((result = GetCommonRepositoryConfigPath(&path)) != B_OK)
|
||||
return result;
|
||||
path.Append(name.String());
|
||||
|
||||
repoConfigEntry.SetTo(path.Path());
|
||||
return repositoryConfig->SetTo(repoConfigEntry);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Roster::_GetRepositoryPath(BPath* path, bool create,
|
||||
directory_which whichDir) const
|
||||
{
|
||||
if (path == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t result = find_directory(whichDir, path);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
if ((result = path->Append("package-repositories")) != B_OK)
|
||||
return result;
|
||||
|
||||
if (create) {
|
||||
BEntry entry(path->Path(), true);
|
||||
if (!entry.Exists()) {
|
||||
if (mkdir(path->Path(), 0755) != 0)
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -112,6 +208,8 @@ Roster::_VisitRepositoryConfigs(const BPath& path,
|
||||
{
|
||||
BDirectory directory(path.Path());
|
||||
status_t result = directory.InitCheck();
|
||||
if (result == B_ENTRY_NOT_FOUND)
|
||||
return B_OK;
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
|
@ -7,25 +7,27 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <package/TempEntryManager.h>
|
||||
#include <package/TempfileManager.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
const BString TempEntryManager::kDefaultName = "tmp-pkgkit-file-";
|
||||
namespace Private {
|
||||
|
||||
|
||||
TempEntryManager::TempEntryManager()
|
||||
const BString TempfileManager::kDefaultName = "tmp-pkgkit-file-";
|
||||
|
||||
|
||||
TempfileManager::TempfileManager()
|
||||
:
|
||||
fNextNumber(1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TempEntryManager::~TempEntryManager()
|
||||
TempfileManager::~TempfileManager()
|
||||
{
|
||||
if (fBaseDirectory.InitCheck() != B_OK)
|
||||
return;
|
||||
@ -41,14 +43,14 @@ TempEntryManager::~TempEntryManager()
|
||||
|
||||
|
||||
void
|
||||
TempEntryManager::SetBaseDirectory(const BDirectory& baseDirectory)
|
||||
TempfileManager::SetBaseDirectory(const BDirectory& baseDirectory)
|
||||
{
|
||||
fBaseDirectory = baseDirectory;
|
||||
}
|
||||
|
||||
|
||||
BEntry
|
||||
TempEntryManager::Create(const BString& baseName)
|
||||
TempfileManager::Create(const BString& baseName)
|
||||
{
|
||||
BString name = BString(baseName) << atomic_add(&fNextNumber, 1);
|
||||
|
||||
@ -56,6 +58,8 @@ TempEntryManager::Create(const BString& baseName)
|
||||
}
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
86
src/kits/package/ValidateChecksumJob.cpp
Normal file
86
src/kits/package/ValidateChecksumJob.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/ValidateChecksumJob.h>
|
||||
|
||||
#include <File.h>
|
||||
|
||||
#include <package/Context.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
namespace Private {
|
||||
|
||||
|
||||
ValidateChecksumJob::ValidateChecksumJob(const Context& context,
|
||||
const BString& title, ChecksumAccessor* expectedChecksumAccessor,
|
||||
ChecksumAccessor* realChecksumAccessor, bool failIfChecksumsDontMatch)
|
||||
:
|
||||
inherited(context, title),
|
||||
fExpectedChecksumAccessor(expectedChecksumAccessor),
|
||||
fRealChecksumAccessor(realChecksumAccessor),
|
||||
fFailIfChecksumsDontMatch(failIfChecksumsDontMatch),
|
||||
fChecksumsMatch(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ValidateChecksumJob::~ValidateChecksumJob()
|
||||
{
|
||||
delete fRealChecksumAccessor;
|
||||
delete fExpectedChecksumAccessor;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ValidateChecksumJob::Execute()
|
||||
{
|
||||
if (fExpectedChecksumAccessor == NULL || fRealChecksumAccessor == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BString expectedChecksum;
|
||||
BString realChecksum;
|
||||
|
||||
status_t result = fExpectedChecksumAccessor->GetChecksum(expectedChecksum);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
result = fRealChecksumAccessor->GetChecksum(realChecksum);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
fChecksumsMatch = expectedChecksum.ICompare(realChecksum) == 0;
|
||||
|
||||
if (fFailIfChecksumsDontMatch && !fChecksumsMatch) {
|
||||
BString error = BString("Checksum error:\n")
|
||||
<< "expected '" << expectedChecksum << "'\n"
|
||||
<< "got '" << realChecksum << "'";
|
||||
SetErrorString(error);
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ValidateChecksumJob::ChecksumsMatch() const
|
||||
{
|
||||
return fChecksumsMatch;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
Loading…
Reference in New Issue
Block a user