* WIP-commit of the first parts of the package kit and the pkgman
(console-)tool git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40261 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
90a81ace91
commit
500bb6305c
@ -529,7 +529,8 @@ HAIKU_BUILD_DESCRIPTION ?= "Unknown Build" ;
|
||||
{
|
||||
local i ;
|
||||
for i in be bnetapi debug game GL locale mail media midi midi2 network
|
||||
opengl root screensaver textencoding tracker translation z {
|
||||
opengl package root screensaver textencoding tracker translation
|
||||
z {
|
||||
HAIKU_LIBRARY_NAME_MAP_$(i) = lib$(i).so ;
|
||||
}
|
||||
HAIKU_LIBRARY_NAME_MAP_libstdc++ = $(HAIKU_LIBSTDC++) ;
|
||||
|
42
headers/os/package/AddRepositoryRequest.h
Normal file
42
headers/os/package/AddRepositoryRequest.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__ADD_REPOSITORY_REQUEST_H_
|
||||
#define _HAIKU__PACKAGE__ADD_REPOSITORY_REQUEST_H_
|
||||
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include <package/Context.h>
|
||||
#include <package/Request.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
class AddRepositoryRequest : public Request {
|
||||
typedef Request inherited;
|
||||
|
||||
public:
|
||||
AddRepositoryRequest(const Context& context,
|
||||
const BString& repositoryURL,
|
||||
bool asUserRepository);
|
||||
virtual ~AddRepositoryRequest();
|
||||
|
||||
virtual status_t CreateJobsToRun(JobQueue& jobQueue);
|
||||
|
||||
private:
|
||||
BString fRepositoryURL;
|
||||
bool fAsUserRepository;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__ADD_REPOSITORY_REQUEST_H_
|
42
headers/os/package/Context.h
Normal file
42
headers/os/package/Context.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__CONTEXT_H_
|
||||
#define _HAIKU__PACKAGE__CONTEXT_H_
|
||||
|
||||
|
||||
#include <package/TempEntryManager.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
class JobStateListener;
|
||||
|
||||
|
||||
class Context {
|
||||
public:
|
||||
Context();
|
||||
~Context();
|
||||
|
||||
TempEntryManager& GetTempEntryManager() const;
|
||||
|
||||
JobStateListener* DefaultJobStateListener() const;
|
||||
void SetDefaultJobStateListener(
|
||||
JobStateListener* listener);
|
||||
|
||||
private:
|
||||
mutable TempEntryManager fTempEntryManager;
|
||||
JobStateListener* fDefaultJobStateListener;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__CONTEXT_H_
|
88
headers/os/package/Job.h
Normal file
88
headers/os/package/Job.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__JOB_H_
|
||||
#define _HAIKU__PACKAGE__JOB_H_
|
||||
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
class Job;
|
||||
|
||||
struct JobStateListener {
|
||||
virtual ~JobStateListener();
|
||||
|
||||
// these default implementations do nothing
|
||||
virtual void JobStarted(Job* job);
|
||||
virtual void JobSucceeded(Job* job);
|
||||
virtual void JobFailed(Job* job);
|
||||
virtual void JobAborted(Job* job);
|
||||
};
|
||||
|
||||
|
||||
enum JobState {
|
||||
JOB_STATE_WAITING_TO_RUN,
|
||||
JOB_STATE_RUNNING,
|
||||
JOB_STATE_SUCCEEDED,
|
||||
JOB_STATE_FAILED,
|
||||
JOB_STATE_ABORTED,
|
||||
};
|
||||
|
||||
|
||||
class Job {
|
||||
public:
|
||||
Job(const BString& title);
|
||||
virtual ~Job();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
virtual status_t Run();
|
||||
|
||||
const BString& Title() const;
|
||||
JobState State() const;
|
||||
status_t Result() const;
|
||||
|
||||
status_t AddStateListener(JobStateListener* listener);
|
||||
status_t RemoveStateListener(
|
||||
JobStateListener* listener);
|
||||
|
||||
status_t AddDependency(Job* job);
|
||||
status_t RemoveDependency(Job* job);
|
||||
int32 CountDependencies() const;
|
||||
|
||||
Job* DependantJobAt(int32 index) const;
|
||||
protected:
|
||||
virtual status_t Execute() = 0;
|
||||
virtual void Cleanup(status_t jobResult);
|
||||
|
||||
void NotifyStateListeners();
|
||||
|
||||
private:
|
||||
status_t fInitStatus;
|
||||
BString fTitle;
|
||||
JobState fState;
|
||||
status_t fResult;
|
||||
|
||||
typedef BObjectList<Job> JobList;
|
||||
JobList fDependencies;
|
||||
JobList fDependantJobs;
|
||||
|
||||
typedef BObjectList<JobStateListener> StateListenerList;
|
||||
StateListenerList fStateListeners;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__JOB_H_
|
51
headers/os/package/JobQueue.h
Normal file
51
headers/os/package/JobQueue.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__JOB_QUEUE_H_
|
||||
#define _HAIKU__PACKAGE__JOB_QUEUE_H_
|
||||
|
||||
|
||||
#include <Locker.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <package/Job.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
class JobQueue : public JobStateListener {
|
||||
public:
|
||||
JobQueue();
|
||||
~JobQueue();
|
||||
|
||||
status_t AddJob(Job* job);
|
||||
status_t RemoveJob(Job* job);
|
||||
|
||||
Job* Pop();
|
||||
|
||||
// JobStateListener
|
||||
virtual void JobSucceeded(Job* job);
|
||||
virtual void JobFailed(Job* job);
|
||||
|
||||
private:
|
||||
struct JobPriorityLess;
|
||||
class JobPriorityQueue;
|
||||
|
||||
private:
|
||||
void _UpdateDependantJobsOf(Job* job);
|
||||
|
||||
BLocker fLock;
|
||||
JobPriorityQueue* fQueuedJobs;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__JOB_QUEUE_H_
|
24
headers/os/package/RepositoryCache.h
Normal file
24
headers/os/package/RepositoryCache.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _REPOSITORY_H_
|
||||
#define _REPOSITORY_H_
|
||||
|
||||
|
||||
#include <Archivable.h>
|
||||
|
||||
|
||||
class BMessage;
|
||||
|
||||
|
||||
class BRepository {
|
||||
public:
|
||||
BRepository(const char* url);
|
||||
|
||||
public:
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
};
|
||||
|
||||
|
||||
#endif // _REPOSITORY_H_
|
75
headers/os/package/RepositoryConfig.h
Normal file
75
headers/os/package/RepositoryConfig.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__REPOSITORY_CONFIG_H_
|
||||
#define _HAIKU__PACKAGE__REPOSITORY_CONFIG_H_
|
||||
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BEntry;
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
class RepositoryConfig : public BArchivable {
|
||||
typedef BArchivable inherited;
|
||||
|
||||
public:
|
||||
RepositoryConfig();
|
||||
RepositoryConfig(const BString& name,
|
||||
const BString& url,
|
||||
uint8 priority = kDefaultPriority);
|
||||
RepositoryConfig(const BEntry& entry);
|
||||
RepositoryConfig(BMessage* data);
|
||||
virtual ~RepositoryConfig();
|
||||
|
||||
virtual status_t Archive(BMessage* data, bool deep = true) const;
|
||||
|
||||
status_t StoreAsConfigFile(const BEntry& entry) const;
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
const BString& Name() const;
|
||||
const BString& URL() const;
|
||||
uint8 Priority() const;
|
||||
bool IsUserSpecific() const;
|
||||
|
||||
void SetName(const BString& name);
|
||||
void SetURL(const BString& url);
|
||||
void SetPriority(uint8 priority);
|
||||
void SetIsUserSpecific(bool isUserSpecific);
|
||||
|
||||
public:
|
||||
static RepositoryConfig* Instantiate(BMessage* data);
|
||||
|
||||
static const uint8 kDefaultPriority = 50;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__REPOSITORY_CONFIG_H_
|
43
headers/os/package/Request.h
Normal file
43
headers/os/package/Request.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__REQUEST_H_
|
||||
#define _HAIKU__PACKAGE__REQUEST_H_
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
class Context;
|
||||
class Job;
|
||||
class JobQueue;
|
||||
|
||||
|
||||
class Request {
|
||||
public:
|
||||
Request(const Context& context);
|
||||
virtual ~Request();
|
||||
|
||||
virtual status_t CreateJobsToRun(JobQueue& jobQueue) = 0;
|
||||
|
||||
const Context& GetContext() const;
|
||||
|
||||
protected:
|
||||
status_t QueueJob(Job* job, JobQueue& jobQueue) const;
|
||||
private:
|
||||
const Context& fContext;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__REQUEST_H_
|
55
headers/os/package/Roster.h
Normal file
55
headers/os/package/Roster.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__ROSTER_H_
|
||||
#define _HAIKU__PACKAGE__ROSTER_H_
|
||||
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
struct RepositoryConfigVisitor {
|
||||
virtual ~RepositoryConfigVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
virtual status_t operator()(const BEntry& entry) = 0;
|
||||
};
|
||||
|
||||
|
||||
class Roster {
|
||||
public:
|
||||
Roster();
|
||||
~Roster();
|
||||
|
||||
status_t GetCommonRepositoryConfigPath(BPath* path,
|
||||
bool create = false) const;
|
||||
status_t GetUserRepositoryConfigPath(BPath* path,
|
||||
bool create = false) const;
|
||||
|
||||
status_t VisitCommonRepositoryConfigs(
|
||||
RepositoryConfigVisitor& visitor);
|
||||
status_t VisitUserRepositoryConfigs(
|
||||
RepositoryConfigVisitor& visitor);
|
||||
|
||||
private:
|
||||
status_t _VisitRepositoryConfigs(const BPath& path,
|
||||
RepositoryConfigVisitor& visitor);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__ROSTER_H_
|
43
headers/os/package/TempEntryManager.h
Normal file
43
headers/os/package/TempEntryManager.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__TEMP_ENTRY_MANAGER_H_
|
||||
#define _HAIKU__PACKAGE__TEMP_ENTRY_MANAGER_H_
|
||||
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
class TempEntryManager {
|
||||
public:
|
||||
TempEntryManager();
|
||||
~TempEntryManager();
|
||||
|
||||
void SetBaseDirectory(const BDirectory& baseDir);
|
||||
|
||||
BEntry Create(const BString& baseName = kDefaultName);
|
||||
|
||||
private:
|
||||
static const BString kDefaultName;
|
||||
|
||||
private:
|
||||
BDirectory fBaseDirectory;
|
||||
vint32 fNextNumber;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__TEMP_ENTRY_MANAGER_H_
|
47
headers/private/package/ActivateRepositoryConfigJob.h
Normal file
47
headers/private/package/ActivateRepositoryConfigJob.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__ACTIVATE_REPOSITORY_CONFIG_JOB_H_
|
||||
#define _HAIKU__PACKAGE__ACTIVATE_REPOSITORY_CONFIG_JOB_H_
|
||||
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/Job.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
class ActivateRepositoryConfigJob : public Job {
|
||||
typedef Job inherited;
|
||||
|
||||
public:
|
||||
ActivateRepositoryConfigJob(
|
||||
const BString& title,
|
||||
const BEntry& archivedRepoConfigEntry,
|
||||
const BDirectory& targetDirectory);
|
||||
virtual ~ActivateRepositoryConfigJob();
|
||||
|
||||
protected:
|
||||
virtual status_t Execute();
|
||||
virtual void Cleanup(status_t jobResult);
|
||||
|
||||
private:
|
||||
BEntry fArchivedRepoConfigEntry;
|
||||
BDirectory fTargetDirectory;
|
||||
BEntry fTargetEntry;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__ACTIVATE_REPOSITORY_CONFIG_JOB_H_
|
44
headers/private/package/FetchFileJob.h
Normal file
44
headers/private/package/FetchFileJob.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _HAIKU__PACKAGE__FETCH_FILE_JOB_H_
|
||||
#define _HAIKU__PACKAGE__FETCH_FILE_JOB_H_
|
||||
|
||||
|
||||
#include <Entry.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/Job.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
class FetchFileJob : public Job {
|
||||
typedef Job inherited;
|
||||
|
||||
public:
|
||||
FetchFileJob(const BString& title,
|
||||
const BString& fileURL,
|
||||
const BEntry& targetEntry);
|
||||
virtual ~FetchFileJob();
|
||||
|
||||
protected:
|
||||
virtual status_t Execute();
|
||||
virtual void Cleanup(status_t jobResult);
|
||||
|
||||
private:
|
||||
BString fFileURL;
|
||||
BEntry fTargetEntry;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
||||
|
||||
|
||||
#endif // _HAIKU__PACKAGE__FETCH_FILE_JOB_H_
|
@ -258,6 +258,7 @@ SubInclude HAIKU_TOP src bin package ;
|
||||
SubInclude HAIKU_TOP src bin patch ;
|
||||
SubInclude HAIKU_TOP src bin pc ;
|
||||
SubInclude HAIKU_TOP src bin pcmcia-cs ;
|
||||
SubInclude HAIKU_TOP src bin pkgman ;
|
||||
SubInclude HAIKU_TOP src bin playsound ;
|
||||
SubInclude HAIKU_TOP src bin rc ;
|
||||
SubInclude HAIKU_TOP src bin rmd160 ;
|
||||
|
12
src/bin/pkgman/Jamfile
Normal file
12
src/bin/pkgman/Jamfile
Normal file
@ -0,0 +1,12 @@
|
||||
SubDir HAIKU_TOP src bin pkgman ;
|
||||
|
||||
UsePrivateHeaders shared support ;
|
||||
|
||||
BinCommand pkgman :
|
||||
command_add_repo.cpp
|
||||
command_list_repos.cpp
|
||||
pkgman.cpp
|
||||
:
|
||||
package be
|
||||
$(TARGET_LIBSUPC++)
|
||||
;
|
120
src/bin/pkgman/command_add_repo.cpp
Normal file
120
src/bin/pkgman/command_add_repo.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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/AddRepositoryRequest.h>
|
||||
#include <package/Context.h>
|
||||
#include <package/JobQueue.h>
|
||||
|
||||
#include "pkgman.h"
|
||||
|
||||
|
||||
// TODO: internationalization!
|
||||
|
||||
|
||||
using namespace Haiku::Package;
|
||||
|
||||
|
||||
static const char* kCommandUsage =
|
||||
"Usage: %s add-repo <repo-URL> [<repo-URL> ...]\n"
|
||||
"Adds one or more repositories by downloading them from the given URL(s).\n"
|
||||
"\n"
|
||||
;
|
||||
|
||||
|
||||
static void
|
||||
print_command_usage_and_exit(bool error)
|
||||
{
|
||||
fprintf(error ? stderr : stdout, kCommandUsage, kProgramName);
|
||||
exit(error ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
struct Listener : public JobStateListener {
|
||||
virtual void JobStarted(Job* job)
|
||||
{
|
||||
printf("%s ...\n", job->Title().String());
|
||||
}
|
||||
virtual void JobSucceeded(Job* job)
|
||||
{
|
||||
}
|
||||
virtual void JobFailed(Job* job)
|
||||
{
|
||||
DIE(job->Result(), "failed!");
|
||||
}
|
||||
virtual void JobAborted(Job* job)
|
||||
{
|
||||
DIE(job->Result(), "aborted");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
command_add_repo(int argc, const char* const* argv)
|
||||
{
|
||||
bool asUserRepository = false;
|
||||
|
||||
while (true) {
|
||||
static struct option sLongOptions[] = {
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "user", no_argument, 0, 'u' },
|
||||
{ 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;
|
||||
|
||||
case 'u':
|
||||
asUserRepository = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
print_command_usage_and_exit(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The remaining arguments are repo URLs, i. e. at least one more argument.
|
||||
if (argc < optind + 1)
|
||||
print_command_usage_and_exit(true);
|
||||
|
||||
const char* const* repoURLs = argv + optind;
|
||||
int urlCount = argc - optind;
|
||||
|
||||
Context context;
|
||||
status_t result;
|
||||
Listener listener;
|
||||
context.SetDefaultJobStateListener(&listener);
|
||||
for (int i = 0; i < urlCount; ++i) {
|
||||
AddRepositoryRequest request(context, repoURLs[i], asUserRepository);
|
||||
JobQueue jobQueue;
|
||||
result = request.CreateJobsToRun(jobQueue);
|
||||
if (result != B_OK)
|
||||
DIE(result, "unable to create necessary jobs");
|
||||
|
||||
while (Job* job = jobQueue.Pop()) {
|
||||
result = job->Run();
|
||||
delete job;
|
||||
if (result == B_INTERRUPTED)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
145
src/bin/pkgman/command_list_repos.cpp
Normal file
145
src/bin/pkgman/command_list_repos.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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 <new>
|
||||
|
||||
#include <Entry.h>
|
||||
#include <Errors.h>
|
||||
#include <ObjectList.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <package/RepositoryConfig.h>
|
||||
#include <package/Roster.h>
|
||||
|
||||
#include "pkgman.h"
|
||||
|
||||
|
||||
// TODO: internationalization!
|
||||
|
||||
|
||||
using namespace Haiku::Package;
|
||||
|
||||
|
||||
static const char* kCommandUsage =
|
||||
"Usage:\n"
|
||||
" %s list-repos [options]\n"
|
||||
"Lists all configured package repositories.\n"
|
||||
"\n"
|
||||
;
|
||||
|
||||
|
||||
static void
|
||||
print_command_usage_and_exit(bool error)
|
||||
{
|
||||
fprintf(error ? stderr : stdout, kCommandUsage, kProgramName);
|
||||
exit(error ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
bool verbose = false;
|
||||
|
||||
while (true) {
|
||||
static struct option sLongOptions[] = {
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "verbose", no_argument, 0, 'v' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
opterr = 0; // don't print errors
|
||||
int c = getopt_long(argc, (char**)argv, "hv", sLongOptions, NULL);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_command_usage_and_exit(false);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
print_command_usage_and_exit(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// No remaining arguments.
|
||||
if (argc != optind)
|
||||
print_command_usage_and_exit(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");
|
||||
|
||||
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);
|
||||
printf(" %s %s\n",
|
||||
repoConfig->IsUserSpecific() ? "[User]" : " ",
|
||||
repoConfig->Name().String());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
72
src/bin/pkgman/pkgman.cpp
Normal file
72
src/bin/pkgman/pkgman.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "pkgman.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
extern const char* __progname;
|
||||
const char* kProgramName = __progname;
|
||||
|
||||
|
||||
static const char* kUsage =
|
||||
"Usage: %s <command> <command args>\n"
|
||||
"Creates, inspects, or extracts a Haiku package.\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" add-repo <repo-base-url>\n"
|
||||
" Adds the repository with the given <repo-base-URL>.\n"
|
||||
"\n"
|
||||
" list-repos\n"
|
||||
" Lists all repositories.\n"
|
||||
"\n"
|
||||
" drop-repo <repo-name>\n"
|
||||
" Drops the repository with the given <repo-name>.\n"
|
||||
"\n"
|
||||
"Common Options:\n"
|
||||
" -h, --help - Print this usage info.\n"
|
||||
;
|
||||
|
||||
|
||||
void
|
||||
print_usage_and_exit(bool error)
|
||||
{
|
||||
fprintf(error ? stderr : stdout, kUsage, kProgramName);
|
||||
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, "add-repo") == 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)
|
||||
return command_list_repos(argc - 1, argv + 1);
|
||||
|
||||
// if (strcmp(command, "search") == 0)
|
||||
// return command_search(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;
|
||||
}
|
44
src/bin/pkgman/pkgman.h
Normal file
44
src/bin/pkgman/pkgman.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef PKGMAN_H
|
||||
#define PKGMAN_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
extern const char* kProgramName;
|
||||
|
||||
|
||||
#define DIE(result, msg...) \
|
||||
do { \
|
||||
fprintf(stderr, "*** " msg); \
|
||||
fprintf(stderr, " : %s\n", strerror(result)); \
|
||||
exit(5); \
|
||||
} while(0)
|
||||
|
||||
#define ERROR(result, msg...) \
|
||||
do { \
|
||||
fprintf(stderr, "*** " msg); \
|
||||
fprintf(stderr, " : %s\n", strerror(result)); \
|
||||
} while(0)
|
||||
|
||||
#define WARN(result, msg...) \
|
||||
do { \
|
||||
fprintf(stderr, "* " msg); \
|
||||
fprintf(stderr, " : %s\n", strerror(result)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
#endif // PKGMAN_H
|
@ -83,6 +83,7 @@ SubInclude HAIKU_TOP src kits midi2 ;
|
||||
SubInclude HAIKU_TOP src kits network ;
|
||||
SubInclude HAIKU_TOP src kits notification ;
|
||||
SubInclude HAIKU_TOP src kits opengl ;
|
||||
SubInclude HAIKU_TOP src kits package ;
|
||||
SubInclude HAIKU_TOP src kits print ;
|
||||
SubInclude HAIKU_TOP src kits screensaver ;
|
||||
SubInclude HAIKU_TOP src kits shared ;
|
||||
|
92
src/kits/package/ActivateRepositoryConfigJob.cpp
Normal file
92
src/kits/package/ActivateRepositoryConfigJob.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include <stdio.h>
|
||||
#include <Path.h>
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/ActivateRepositoryConfigJob.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <File.h>
|
||||
|
||||
#include <package/RepositoryConfig.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
ActivateRepositoryConfigJob::ActivateRepositoryConfigJob(const BString& title,
|
||||
const BEntry& archivedRepoConfigEntry, const BDirectory& targetDirectory)
|
||||
:
|
||||
inherited(title),
|
||||
fArchivedRepoConfigEntry(archivedRepoConfigEntry),
|
||||
fTargetDirectory(targetDirectory)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ActivateRepositoryConfigJob::~ActivateRepositoryConfigJob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ActivateRepositoryConfigJob::Execute()
|
||||
{
|
||||
BFile archiveFile(&fArchivedRepoConfigEntry, B_READ_ONLY);
|
||||
BPath p;
|
||||
fArchivedRepoConfigEntry.GetPath(&p);
|
||||
printf("Execute(): arce=%s\n", p.Path());
|
||||
status_t result = archiveFile.InitCheck();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
printf("Execute(): 2\n");
|
||||
BMessage archive;
|
||||
if ((result = archive.Unflatten(&archiveFile)) != B_OK)
|
||||
return result;
|
||||
|
||||
printf("Execute(): 3\n");
|
||||
RepositoryConfig* repoConfig = RepositoryConfig::Instantiate(&archive);
|
||||
if (repoConfig == NULL)
|
||||
return B_BAD_DATA;
|
||||
printf("Execute(): 4\n");
|
||||
if ((result = repoConfig->InitCheck()) != B_OK)
|
||||
return result;
|
||||
|
||||
printf("Execute(): 5\n");
|
||||
fTargetEntry.SetTo(&fTargetDirectory, repoConfig->Name().String());
|
||||
if (fTargetEntry.Exists()) {
|
||||
// TODO: ask user whether to clobber or not
|
||||
printf("Execute(): 5b\n");
|
||||
return B_INTERRUPTED;
|
||||
}
|
||||
|
||||
printf("Execute(): 6\n");
|
||||
if ((result = repoConfig->StoreAsConfigFile(fTargetEntry)) != B_OK)
|
||||
return result;
|
||||
|
||||
printf("Execute(): 7\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ActivateRepositoryConfigJob::Cleanup(status_t jobResult)
|
||||
{
|
||||
if (jobResult != B_OK && State() != JOB_STATE_ABORTED)
|
||||
fTargetEntry.Remove();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
83
src/kits/package/AddRepositoryRequest.cpp
Normal file
83
src/kits/package/AddRepositoryRequest.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/AddRepositoryRequest.h>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <package/ActivateRepositoryConfigJob.h>
|
||||
#include <package/FetchFileJob.h>
|
||||
#include <package/JobQueue.h>
|
||||
#include <package/Roster.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
AddRepositoryRequest::AddRepositoryRequest(const Context& context,
|
||||
const BString& repositoryURL, bool asUserRepository)
|
||||
:
|
||||
inherited(context),
|
||||
fRepositoryURL(repositoryURL),
|
||||
fAsUserRepository(asUserRepository)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AddRepositoryRequest::~AddRepositoryRequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AddRepositoryRequest::CreateJobsToRun(JobQueue& jobQueue)
|
||||
{
|
||||
BEntry tempEntry
|
||||
= GetContext().GetTempEntryManager().Create("repoconfig-");
|
||||
FetchFileJob* fetchJob = new (std::nothrow) FetchFileJob(
|
||||
BString("Fetching repository-config from ") << fRepositoryURL,
|
||||
fRepositoryURL, tempEntry);
|
||||
if (fetchJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
status_t result = QueueJob(fetchJob, jobQueue);
|
||||
if (result != B_OK) {
|
||||
delete fetchJob;
|
||||
return result;
|
||||
}
|
||||
|
||||
Roster roster;
|
||||
BPath targetRepoConfigPath;
|
||||
result = fAsUserRepository
|
||||
? roster.GetUserRepositoryConfigPath(&targetRepoConfigPath, true)
|
||||
: roster.GetCommonRepositoryConfigPath(&targetRepoConfigPath, true);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
BDirectory targetDirectory(targetRepoConfigPath.Path());
|
||||
ActivateRepositoryConfigJob* activateJob
|
||||
= new (std::nothrow) ActivateRepositoryConfigJob(
|
||||
BString("Activating repository-config from ") << fRepositoryURL,
|
||||
tempEntry, targetDirectory);
|
||||
if (activateJob == NULL)
|
||||
return B_NO_MEMORY;
|
||||
activateJob->AddDependency(fetchJob);
|
||||
if ((result = QueueJob(activateJob, jobQueue)) != B_OK) {
|
||||
delete activateJob;
|
||||
return result;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
67
src/kits/package/Context.cpp
Normal file
67
src/kits/package/Context.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/Context.h>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <OS.h>
|
||||
#include <Path.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
Context::Context()
|
||||
:
|
||||
fDefaultJobStateListener(NULL)
|
||||
{
|
||||
BPath tempPath;
|
||||
if (find_directory(B_COMMON_TEMP_DIRECTORY, &tempPath) != B_OK)
|
||||
tempPath.SetTo("/tmp");
|
||||
BDirectory tempDirectory(tempPath.Path());
|
||||
|
||||
BString contextName = BString("pkgkit-context-") << find_thread(NULL);
|
||||
BDirectory baseDirectory;
|
||||
tempDirectory.CreateDirectory(contextName.String(), &baseDirectory);
|
||||
fTempEntryManager.SetBaseDirectory(baseDirectory);
|
||||
}
|
||||
|
||||
|
||||
Context::~Context()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TempEntryManager&
|
||||
Context::GetTempEntryManager() const
|
||||
{
|
||||
return fTempEntryManager;
|
||||
}
|
||||
|
||||
|
||||
JobStateListener*
|
||||
Context::DefaultJobStateListener() const
|
||||
{
|
||||
return fDefaultJobStateListener;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Context::SetDefaultJobStateListener(JobStateListener* listener)
|
||||
{
|
||||
fDefaultJobStateListener = listener;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
70
src/kits/package/FetchFileJob.cpp
Normal file
70
src/kits/package/FetchFileJob.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/FetchFileJob.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <Path.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
FetchFileJob::FetchFileJob(const BString& title, const BString& fileURL,
|
||||
const BEntry& targetEntry)
|
||||
:
|
||||
inherited(title),
|
||||
fFileURL(fileURL),
|
||||
fTargetEntry(targetEntry)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FetchFileJob::~FetchFileJob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FetchFileJob::Execute()
|
||||
{
|
||||
BPath targetPath;
|
||||
status_t result = fTargetEntry.GetPath(&targetPath);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
// TODO: implement for real, maybe using the "service kit"-GSOC HTTP-stuff?
|
||||
BString cmd = BString("curl -# -o ") << targetPath.Path() << " "
|
||||
<< fFileURL.String();
|
||||
|
||||
int cmdResult = system(cmd.String());
|
||||
if (WIFSIGNALED(cmdResult)
|
||||
&& (WTERMSIG(cmdResult) == SIGINT || WTERMSIG(cmdResult) == SIGQUIT)) {
|
||||
return B_INTERRUPTED;
|
||||
}
|
||||
|
||||
return cmdResult == 0 ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FetchFileJob::Cleanup(status_t jobResult)
|
||||
{
|
||||
if (jobResult != B_OK)
|
||||
fTargetEntry.Remove();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
19
src/kits/package/Jamfile
Normal file
19
src/kits/package/Jamfile
Normal file
@ -0,0 +1,19 @@
|
||||
SubDir HAIKU_TOP src kits package ;
|
||||
|
||||
UsePrivateHeaders package ;
|
||||
|
||||
SharedLibrary libpackage.so
|
||||
:
|
||||
ActivateRepositoryConfigJob.cpp
|
||||
AddRepositoryRequest.cpp
|
||||
Context.cpp
|
||||
FetchFileJob.cpp
|
||||
Job.cpp
|
||||
JobQueue.cpp
|
||||
RepositoryConfig.cpp
|
||||
Request.cpp
|
||||
Roster.cpp
|
||||
TempEntryManager.cpp
|
||||
:
|
||||
be $(TARGET_LIBSTDC++)
|
||||
;
|
207
src/kits/package/Job.cpp
Normal file
207
src/kits/package/Job.cpp
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/Job.h>
|
||||
|
||||
#include <Errors.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
JobStateListener::~JobStateListener()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobStateListener::JobStarted(Job* job)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobStateListener::JobSucceeded(Job* job)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobStateListener::JobFailed(Job* job)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobStateListener::JobAborted(Job* job)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Job::Job(const BString& title)
|
||||
:
|
||||
fTitle(title),
|
||||
fState(JOB_STATE_WAITING_TO_RUN)
|
||||
{
|
||||
if (fTitle.Length() == 0)
|
||||
fInitStatus = B_BAD_VALUE;
|
||||
else
|
||||
fInitStatus = B_OK;
|
||||
}
|
||||
|
||||
|
||||
Job::~Job()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::InitCheck() const
|
||||
{
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
Job::Title() const
|
||||
{
|
||||
return fTitle;
|
||||
}
|
||||
|
||||
|
||||
JobState
|
||||
Job::State() const
|
||||
{
|
||||
return fState;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::Result() const
|
||||
{
|
||||
return fResult;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::Run()
|
||||
{
|
||||
if (fState != JOB_STATE_WAITING_TO_RUN)
|
||||
return B_NOT_ALLOWED;
|
||||
|
||||
fState = JOB_STATE_RUNNING;
|
||||
NotifyStateListeners();
|
||||
|
||||
fResult = Execute();
|
||||
Cleanup(fResult);
|
||||
|
||||
fState = fResult == B_OK
|
||||
? JOB_STATE_SUCCEEDED
|
||||
: fResult == B_INTERRUPTED
|
||||
? JOB_STATE_ABORTED
|
||||
: JOB_STATE_FAILED;
|
||||
NotifyStateListeners();
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Job::Cleanup(status_t /*jobResult*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::AddStateListener(JobStateListener* listener)
|
||||
{
|
||||
return fStateListeners.AddItem(listener) ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::RemoveStateListener(JobStateListener* listener)
|
||||
{
|
||||
return fStateListeners.RemoveItem(listener) ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::AddDependency(Job* job)
|
||||
{
|
||||
if (fDependencies.HasItem(job))
|
||||
return B_ERROR;
|
||||
|
||||
if (fDependencies.AddItem(job) && job->fDependantJobs.AddItem(this))
|
||||
return B_OK;
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Job::RemoveDependency(Job* job)
|
||||
{
|
||||
if (!fDependencies.HasItem(job))
|
||||
return B_ERROR;
|
||||
|
||||
if (fDependencies.RemoveItem(job) && job->fDependantJobs.RemoveItem(this))
|
||||
return B_OK;
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
Job::CountDependencies() const
|
||||
{
|
||||
return fDependencies.CountItems();
|
||||
}
|
||||
|
||||
|
||||
Job*
|
||||
Job::DependantJobAt(int32 index) const
|
||||
{
|
||||
return fDependantJobs.ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Job::NotifyStateListeners()
|
||||
{
|
||||
int32 count = fStateListeners.CountItems();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
JobStateListener* listener = fStateListeners.ItemAt(i);
|
||||
if (listener == NULL)
|
||||
continue;
|
||||
switch (fState) {
|
||||
case JOB_STATE_RUNNING:
|
||||
listener->JobStarted(this);
|
||||
break;
|
||||
case JOB_STATE_SUCCEEDED:
|
||||
listener->JobSucceeded(this);
|
||||
break;
|
||||
case JOB_STATE_FAILED:
|
||||
listener->JobFailed(this);
|
||||
break;
|
||||
case JOB_STATE_ABORTED:
|
||||
listener->JobAborted(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
155
src/kits/package/JobQueue.cpp
Normal file
155
src/kits/package/JobQueue.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/JobQueue.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <Autolock.h>
|
||||
|
||||
#include <package/Job.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
struct JobQueue::JobPriorityLess {
|
||||
bool operator()(const Job* left, const Job* right) const;
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
JobQueue::JobPriorityLess::operator()(const Job* left, const Job* right) const
|
||||
{
|
||||
int32 difference = left->CountDependencies() - right->CountDependencies();
|
||||
if (difference < 0)
|
||||
return true;
|
||||
if (difference > 0)
|
||||
return false;
|
||||
|
||||
return left->Title() < right->Title();
|
||||
};
|
||||
|
||||
|
||||
class JobQueue::JobPriorityQueue
|
||||
: public std::set<Job*, JobPriorityLess> {
|
||||
|
||||
};
|
||||
|
||||
|
||||
JobQueue::JobQueue()
|
||||
:
|
||||
fLock("job queue"),
|
||||
fQueuedJobs(new (std::nothrow) JobPriorityQueue())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
JobQueue::~JobQueue()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
JobQueue::AddJob(Job* job)
|
||||
{
|
||||
if (fQueuedJobs == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
BAutolock lock(&fLock);
|
||||
if (lock.IsLocked()) {
|
||||
try {
|
||||
fQueuedJobs->insert(job);
|
||||
} catch (const std::bad_alloc& e) {
|
||||
return B_NO_MEMORY;
|
||||
} catch (...) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
job->AddStateListener(this);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
JobQueue::RemoveJob(Job* job)
|
||||
{
|
||||
if (fQueuedJobs == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
BAutolock lock(&fLock);
|
||||
if (lock.IsLocked()) {
|
||||
try {
|
||||
fQueuedJobs->erase(job);
|
||||
} catch (...) {
|
||||
return B_ERROR;
|
||||
}
|
||||
job->RemoveStateListener(this);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobQueue::JobSucceeded(Job* job)
|
||||
{
|
||||
_UpdateDependantJobsOf(job);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobQueue::JobFailed(Job* job)
|
||||
{
|
||||
_UpdateDependantJobsOf(job);
|
||||
}
|
||||
|
||||
|
||||
Job*
|
||||
JobQueue::Pop()
|
||||
{
|
||||
BAutolock lock(&fLock);
|
||||
if (lock.IsLocked()) {
|
||||
JobPriorityQueue::iterator head = fQueuedJobs->begin();
|
||||
if (head == fQueuedJobs->end())
|
||||
return NULL;
|
||||
fQueuedJobs->erase(head);
|
||||
return *head;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobQueue::_UpdateDependantJobsOf(Job* job)
|
||||
{
|
||||
BAutolock lock(&fLock);
|
||||
if (lock.IsLocked()) {
|
||||
while (Job* dependantJob = job->DependantJobAt(0)) {
|
||||
try {
|
||||
fQueuedJobs->erase(dependantJob);
|
||||
} catch (...) {
|
||||
}
|
||||
dependantJob->RemoveDependency(job);
|
||||
try {
|
||||
fQueuedJobs->insert(dependantJob);
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
261
src/kits/package/RepositoryConfig.cpp
Normal file
261
src/kits/package/RepositoryConfig.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/RepositoryConfig.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <driver_settings.h>
|
||||
#include <Entry.h>
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
const char* RepositoryConfig::kNameField = "name";
|
||||
const char* RepositoryConfig::kURLField = "url";
|
||||
const char* RepositoryConfig::kPriorityField = "priority";
|
||||
|
||||
|
||||
RepositoryConfig::RepositoryConfig()
|
||||
:
|
||||
fInitStatus(B_NO_INIT),
|
||||
fPriority(kDefaultPriority),
|
||||
fIsUserSpecific(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RepositoryConfig::RepositoryConfig(const BEntry& entry)
|
||||
{
|
||||
fInitStatus = _InitFrom(entry);
|
||||
}
|
||||
|
||||
|
||||
RepositoryConfig::RepositoryConfig(BMessage* data)
|
||||
:
|
||||
inherited(data)
|
||||
{
|
||||
fInitStatus = _InitFrom(data);
|
||||
}
|
||||
|
||||
|
||||
RepositoryConfig::RepositoryConfig(const BString& name, const BString& url,
|
||||
uint8 priority)
|
||||
:
|
||||
fInitStatus(B_OK),
|
||||
fName(name),
|
||||
fURL(url),
|
||||
fPriority(priority),
|
||||
fIsUserSpecific(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RepositoryConfig::~RepositoryConfig()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*static*/ RepositoryConfig*
|
||||
RepositoryConfig::Instantiate(BMessage* data)
|
||||
{
|
||||
if (validate_instantiation(data, "Haiku::Package::RepositoryConfig"))
|
||||
return new (std::nothrow) RepositoryConfig(data);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryConfig::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, fURL)) != B_OK)
|
||||
return result;
|
||||
if ((result = data->AddUInt8(kPriorityField, fPriority)) != B_OK)
|
||||
return result;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryConfig::StoreAsConfigFile(const BEntry& entry) const
|
||||
{
|
||||
BFile file(&entry, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
|
||||
status_t result = file.InitCheck();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
BString configString;
|
||||
configString
|
||||
<< "name=" << fName << "\n"
|
||||
<< "url=" << fURL << "\n"
|
||||
<< "priority=" << fPriority << "\n";
|
||||
|
||||
int32 size = configString.Length();
|
||||
if ((result = file.Write(configString.String(), size)) < size)
|
||||
return (result >= 0) ? B_ERROR : result;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryConfig::InitCheck() const
|
||||
{
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
RepositoryConfig::Name() const
|
||||
{
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
||||
const BString&
|
||||
RepositoryConfig::URL() const
|
||||
{
|
||||
return fURL;
|
||||
}
|
||||
|
||||
|
||||
uint8
|
||||
RepositoryConfig::Priority() const
|
||||
{
|
||||
return fPriority;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RepositoryConfig::IsUserSpecific() const
|
||||
{
|
||||
return fIsUserSpecific;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryConfig::SetName(const BString& name)
|
||||
{
|
||||
fName = name;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryConfig::SetURL(const BString& url)
|
||||
{
|
||||
fURL = url;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryConfig::SetPriority(uint8 priority)
|
||||
{
|
||||
fPriority = priority;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryConfig::SetIsUserSpecific(bool isUserSpecific)
|
||||
{
|
||||
fIsUserSpecific = 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
|
54
src/kits/package/Request.cpp
Normal file
54
src/kits/package/Request.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/Request.h>
|
||||
|
||||
#include <package/Context.h>
|
||||
#include <package/Job.h>
|
||||
#include <package/JobQueue.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
Request::Request(const Context& context)
|
||||
:
|
||||
fContext(context)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Request::~Request()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const Context&
|
||||
Request::GetContext() const
|
||||
{
|
||||
return fContext;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Request::QueueJob(Job* job, JobQueue& jobQueue) const
|
||||
{
|
||||
JobStateListener* defaultListener = fContext.DefaultJobStateListener();
|
||||
if (defaultListener != NULL)
|
||||
job->AddStateListener(defaultListener);
|
||||
|
||||
return jobQueue.AddJob(job);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
130
src/kits/package/Roster.cpp
Normal file
130
src/kits/package/Roster.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/Roster.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
#include <FindDirectory.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
Roster::Roster()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Roster::GetUserRepositoryConfigPath(BPath* path, bool create) const
|
||||
{
|
||||
if (path == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Roster::VisitCommonRepositoryConfigs(RepositoryConfigVisitor& visitor)
|
||||
{
|
||||
BPath commonRepositoryConfigPath;
|
||||
status_t result
|
||||
= GetCommonRepositoryConfigPath(&commonRepositoryConfigPath);
|
||||
if (result == B_OK)
|
||||
result = _VisitRepositoryConfigs(commonRepositoryConfigPath, visitor);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Roster::VisitUserRepositoryConfigs(RepositoryConfigVisitor& visitor)
|
||||
{
|
||||
BPath userRepositoryConfigPath;
|
||||
status_t result = GetUserRepositoryConfigPath(&userRepositoryConfigPath);
|
||||
if (result == B_OK)
|
||||
result = _VisitRepositoryConfigs(userRepositoryConfigPath, visitor);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Roster::_VisitRepositoryConfigs(const BPath& path,
|
||||
RepositoryConfigVisitor& visitor)
|
||||
{
|
||||
BDirectory directory(path.Path());
|
||||
status_t result = directory.InitCheck();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
BEntry entry;
|
||||
while (directory.GetNextEntry(&entry, true) == B_OK) {
|
||||
if ((result = visitor(entry)) != B_OK)
|
||||
return result;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
61
src/kits/package/TempEntryManager.cpp
Normal file
61
src/kits/package/TempEntryManager.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Oliver Tappe <zooey@hirschkaefer.de>
|
||||
*/
|
||||
|
||||
|
||||
#include <package/TempEntryManager.h>
|
||||
|
||||
|
||||
namespace Haiku {
|
||||
|
||||
namespace Package {
|
||||
|
||||
|
||||
const BString TempEntryManager::kDefaultName = "tmp-pkgkit-file-";
|
||||
|
||||
|
||||
TempEntryManager::TempEntryManager()
|
||||
:
|
||||
fNextNumber(1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TempEntryManager::~TempEntryManager()
|
||||
{
|
||||
if (fBaseDirectory.InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
fBaseDirectory.Rewind();
|
||||
BEntry entry;
|
||||
while (fBaseDirectory.GetNextEntry(&entry) == B_OK)
|
||||
entry.Remove();
|
||||
|
||||
fBaseDirectory.GetEntry(&entry);
|
||||
entry.Remove();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TempEntryManager::SetBaseDirectory(const BDirectory& baseDirectory)
|
||||
{
|
||||
fBaseDirectory = baseDirectory;
|
||||
}
|
||||
|
||||
|
||||
BEntry
|
||||
TempEntryManager::Create(const BString& baseName)
|
||||
{
|
||||
BString name = BString(baseName) << atomic_add(&fNextNumber, 1);
|
||||
|
||||
return BEntry(&fBaseDirectory, name.String());
|
||||
}
|
||||
|
||||
|
||||
} // namespace Package
|
||||
|
||||
} // namespace Haiku
|
@ -7,9 +7,10 @@ SubInclude HAIKU_TOP src tests kits locale ;
|
||||
SubInclude HAIKU_TOP src tests kits media ;
|
||||
SubInclude HAIKU_TOP src tests kits midi ;
|
||||
SubInclude HAIKU_TOP src tests kits net ;
|
||||
SubInclude HAIKU_TOP src tests kits opengl ;
|
||||
SubInclude HAIKU_TOP src tests kits package ;
|
||||
SubInclude HAIKU_TOP src tests kits shared ;
|
||||
SubInclude HAIKU_TOP src tests kits storage ;
|
||||
SubInclude HAIKU_TOP src tests kits support ;
|
||||
SubInclude HAIKU_TOP src tests kits translation ;
|
||||
SubInclude HAIKU_TOP src tests kits opengl ;
|
||||
|
||||
|
4
src/tests/kits/package/Jamfile
Normal file
4
src/tests/kits/package/Jamfile
Normal file
@ -0,0 +1,4 @@
|
||||
SubDir HAIKU_TOP src tests kits package ;
|
||||
|
||||
SimpleTest make_repo : make_repo.cpp : package be ;
|
||||
|
80
src/tests/kits/package/make_repo.cpp
Normal file
80
src/tests/kits/package/make_repo.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <File.h>
|
||||
#include <Message.h>
|
||||
#include <String.h>
|
||||
|
||||
#include <package/RepositoryConfig.h>
|
||||
|
||||
|
||||
using namespace Haiku::Package;
|
||||
|
||||
|
||||
int
|
||||
main(int argc, const char** argv)
|
||||
{
|
||||
if (argc < 5) {
|
||||
fprintf(stderr, "usage: %s <name> <url> <priority> <pkg-count>\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
RepositoryConfig repoConfig(argv[1], argv[2], atoi(argv[3]));
|
||||
status_t status = repoConfig.InitCheck();
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "couldn't initialize repository-config\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
BMessage repoConfigArchive;
|
||||
if ((status = repoConfig.Archive(&repoConfigArchive)) != B_OK) {
|
||||
fprintf(stderr, "couldn't archive repository-config\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
BFile output(argv[1], B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
|
||||
if ((status = repoConfigArchive.Flatten(&output)) != B_OK) {
|
||||
fprintf(stderr, "couldn't flatten repository-config archive\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pkgCount = atoi(argv[4]);
|
||||
for (int i = 0; i < pkgCount; ++i) {
|
||||
BMessage pkg('PKGp');
|
||||
|
||||
BString name = BString("pkg") << i + 1;
|
||||
pkg.AddString("name", name.String());
|
||||
|
||||
BString majorVersion
|
||||
= BString() << 1 + i % 5 << "." << i % 10;
|
||||
BString minorVersion
|
||||
= BString() << i % 100;
|
||||
pkg.AddString("version",
|
||||
(BString() << majorVersion << "." << minorVersion).String());
|
||||
|
||||
pkg.AddString("provides",
|
||||
(BString() << name << "-" << majorVersion).String());
|
||||
if (i % 2 == 1)
|
||||
pkg.AddString("provides", (BString("lib") << name).String());
|
||||
if (i % 3 != 1)
|
||||
pkg.AddString("provides", (BString("cmd:") << name).String());
|
||||
|
||||
if (i > 1) {
|
||||
int requiresCount = rand() % 10 % i;
|
||||
for (int r = 0; r < requiresCount; ++r) {
|
||||
int reqIndex = rand() % i;
|
||||
pkg.AddString("requires",
|
||||
(BString("pkg") << reqIndex).String());
|
||||
}
|
||||
}
|
||||
|
||||
status = pkg.Flatten(&output);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "couldn't flatten pkg message #%d\n", i + 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user