repository_infos: Enable automatic updates on the main Haiku repostiory.
[haiku.git] / src / kits / storage / RemoveEngine.cpp
blob63626be04542e1cb2469210634f871b3a90ec0dc
1 /*
2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include <RemoveEngine.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <unistd.h>
13 #include <Directory.h>
14 #include <Entry.h>
15 #include <Path.h>
18 namespace BPrivate {
21 // #pragma mark - BRemoveEngine
24 BRemoveEngine::BRemoveEngine()
26 fController(NULL)
31 BRemoveEngine::~BRemoveEngine()
36 BRemoveEngine::BController*
37 BRemoveEngine::Controller() const
39 return fController;
43 void
44 BRemoveEngine::SetController(BController* controller)
46 fController = controller;
50 status_t
51 BRemoveEngine::RemoveEntry(const Entry& entry)
53 BPath pathBuffer;
54 const char* path;
55 status_t error = entry.GetPath(pathBuffer, path);
56 if (error != B_OK)
57 return error;
59 return _RemoveEntry(path);
63 status_t
64 BRemoveEngine::_RemoveEntry(const char* path)
66 // apply entry filter
67 if (fController != NULL && !fController->EntryStarted(path))
68 return B_OK;
70 // stat entry
71 struct stat st;
72 if (lstat(path, &st) < 0) {
73 return _HandleEntryError(path, errno, "Couldn't access \"%s\": %s\n",
74 path, strerror(errno));
77 // recurse, if entry is a directory
78 if (S_ISDIR(st.st_mode)) {
79 // open directory
80 BDirectory directory;
81 status_t error = directory.SetTo(path);
82 if (error != B_OK) {
83 return _HandleEntryError(path, error,
84 "Failed to open directory \"%s\": %s\n", path, strerror(error));
87 char buffer[sizeof(dirent) + B_FILE_NAME_LENGTH];
88 dirent *entry = (dirent*)buffer;
89 while (directory.GetNextDirents(entry, sizeof(buffer), 1) == 1) {
90 if (strcmp(entry->d_name, ".") == 0
91 || strcmp(entry->d_name, "..") == 0) {
92 continue;
95 // construct child entry path
96 BPath childPath;
97 error = childPath.SetTo(path, entry->d_name);
98 if (error != B_OK) {
99 return _HandleEntryError(path, error,
100 "Failed to construct entry path from dir \"%s\" and name "
101 "\"%s\": %s\n", path, entry->d_name, strerror(error));
104 // remove the entry
105 error = _RemoveEntry(childPath.Path());
106 if (error != B_OK) {
107 if (fController != NULL
108 && fController->EntryFinished(path, error)) {
109 return B_OK;
111 return error;
116 // remove entry
117 if (S_ISDIR(st.st_mode)) {
118 if (rmdir(path) < 0) {
119 return _HandleEntryError(path, errno,
120 "Failed to remove \"%s\": %s\n", path, strerror(errno));
122 } else {
123 if (unlink(path) < 0) {
124 return _HandleEntryError(path, errno,
125 "Failed to unlink \"%s\": %s\n", path, strerror(errno));
129 if (fController != NULL)
130 fController->EntryFinished(path, B_OK);
132 return B_OK;
136 void
137 BRemoveEngine::_NotifyErrorVarArgs(status_t error, const char* format,
138 va_list args)
140 if (fController != NULL) {
141 BString message;
142 message.SetToFormatVarArgs(format, args);
143 fController->ErrorOccurred(message, error);
148 status_t
149 BRemoveEngine::_HandleEntryError(const char* path, status_t error,
150 const char* format, ...)
152 if (fController == NULL)
153 return error;
155 va_list args;
156 va_start(args, format);
157 _NotifyErrorVarArgs(error, format, args);
158 va_end(args);
160 if (fController->EntryFinished(path, error))
161 return B_OK;
162 return error;
166 // #pragma mark - BController
169 BRemoveEngine::BController::BController()
174 BRemoveEngine::BController::~BController()
179 bool
180 BRemoveEngine::BController::EntryStarted(const char* path)
182 return true;
186 bool
187 BRemoveEngine::BController::EntryFinished(const char* path, status_t error)
189 return error == B_OK;
193 void
194 BRemoveEngine::BController::ErrorOccurred(const char* message, status_t error)
199 } // namespace BPrivate