Add BRemoveEngine
Similar to BCopyEngine, but it (surprise!) removes an entry.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <[email protected]>
|
||||
*/
|
||||
#ifndef _REMOVE_ENGINE_H
|
||||
#define _REMOVE_ENGINE_H
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <EntryOperationEngineBase.h>
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
|
||||
class BRemoveEngine : public BEntryOperationEngineBase {
|
||||
public:
|
||||
class BController;
|
||||
|
||||
public:
|
||||
BRemoveEngine();
|
||||
~BRemoveEngine();
|
||||
|
||||
BController* Controller() const;
|
||||
void SetController(BController* controller);
|
||||
|
||||
status_t RemoveEntry(const Entry& entry);
|
||||
|
||||
private:
|
||||
status_t _RemoveEntry(const char* path);
|
||||
|
||||
void _NotifyErrorVarArgs(status_t error,
|
||||
const char* format, va_list args);
|
||||
status_t _HandleEntryError(const char* path,
|
||||
status_t error, const char* format, ...);
|
||||
|
||||
private:
|
||||
BController* fController;
|
||||
};
|
||||
|
||||
|
||||
class BRemoveEngine::BController {
|
||||
public:
|
||||
BController();
|
||||
virtual ~BController();
|
||||
|
||||
virtual bool EntryStarted(const char* path);
|
||||
virtual bool EntryFinished(const char* path, status_t error);
|
||||
|
||||
virtual void ErrorOccurred(const char* message,
|
||||
status_t error);
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
|
||||
using ::BPrivate::BRemoveEngine;
|
||||
|
||||
|
||||
#endif // _REMOVE_ENGINE_H
|
||||
@@ -42,6 +42,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
PathMonitor.cpp
|
||||
Query.cpp
|
||||
QueryPredicate.cpp
|
||||
RemoveEngine.cpp
|
||||
ResourceFile.cpp
|
||||
ResourceItem.cpp
|
||||
Resources.cpp
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2013, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <RemoveEngine.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
|
||||
// #pragma mark - BRemoveEngine
|
||||
|
||||
|
||||
BRemoveEngine::BRemoveEngine()
|
||||
:
|
||||
fController(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BRemoveEngine::~BRemoveEngine()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BRemoveEngine::BController*
|
||||
BRemoveEngine::Controller() const
|
||||
{
|
||||
return fController;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRemoveEngine::SetController(BController* controller)
|
||||
{
|
||||
fController = controller;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRemoveEngine::RemoveEntry(const Entry& entry)
|
||||
{
|
||||
BPath pathBuffer;
|
||||
const char* path;
|
||||
status_t error = entry.GetPath(pathBuffer, path);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return _RemoveEntry(path);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRemoveEngine::_RemoveEntry(const char* path)
|
||||
{
|
||||
// apply entry filter
|
||||
if (fController != NULL && !fController->EntryStarted(path))
|
||||
return B_OK;
|
||||
|
||||
// stat entry
|
||||
struct stat st;
|
||||
if (lstat(path, &st) < 0) {
|
||||
return _HandleEntryError(path, errno, "Couldn't access \"%s\": %s\n",
|
||||
path, strerror(errno));
|
||||
}
|
||||
|
||||
// recurse, if entry is a directory
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
// open directory
|
||||
BDirectory directory;
|
||||
status_t error = directory.SetTo(path);
|
||||
if (error != B_OK) {
|
||||
return _HandleEntryError(path, error,
|
||||
"Failed to open directory \"%s\": %s\n", path, strerror(error));
|
||||
}
|
||||
|
||||
char buffer[sizeof(dirent) + B_FILE_NAME_LENGTH];
|
||||
dirent *entry = (dirent*)buffer;
|
||||
while (directory.GetNextDirents(entry, sizeof(buffer), 1) == 1) {
|
||||
if (strcmp(entry->d_name, ".") == 0
|
||||
|| strcmp(entry->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// construct child entry path
|
||||
BPath childPath;
|
||||
error = childPath.SetTo(path, entry->d_name);
|
||||
if (error != B_OK) {
|
||||
return _HandleEntryError(path, error,
|
||||
"Failed to construct entry path from dir \"%s\" and name "
|
||||
"\"%s\": %s\n", path, entry->d_name, strerror(error));
|
||||
}
|
||||
|
||||
// remove the entry
|
||||
error = _RemoveEntry(childPath.Path());
|
||||
if (error != B_OK) {
|
||||
if (fController != NULL
|
||||
&& fController->EntryFinished(path, error)) {
|
||||
return B_OK;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove entry
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (rmdir(path) < 0) {
|
||||
return _HandleEntryError(path, errno,
|
||||
"Failed to remove \"%s\": %s\n", path, strerror(errno));
|
||||
}
|
||||
} else {
|
||||
if (unlink(path) < 0) {
|
||||
return _HandleEntryError(path, errno,
|
||||
"Failed to unlink \"%s\": %s\n", path, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (fController != NULL)
|
||||
fController->EntryFinished(path, B_OK);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRemoveEngine::_NotifyErrorVarArgs(status_t error, const char* format,
|
||||
va_list args)
|
||||
{
|
||||
if (fController != NULL) {
|
||||
BString message;
|
||||
message.SetToFormatVarArgs(format, args);
|
||||
fController->ErrorOccurred(message, error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BRemoveEngine::_HandleEntryError(const char* path, status_t error,
|
||||
const char* format, ...)
|
||||
{
|
||||
if (fController == NULL)
|
||||
return error;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
_NotifyErrorVarArgs(error, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (fController->EntryFinished(path, error))
|
||||
return B_OK;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - BController
|
||||
|
||||
|
||||
BRemoveEngine::BController::BController()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BRemoveEngine::BController::~BController()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BRemoveEngine::BController::EntryStarted(const char* path)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BRemoveEngine::BController::EntryFinished(const char* path, status_t error)
|
||||
{
|
||||
return error == B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRemoveEngine::BController::ErrorOccurred(const char* message, status_t error)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace BPrivate
|
||||
Reference in New Issue
Block a user