#include <sys/types.h>
#include <cstdio>
#include <unistd.h>
+#include <fts.h>
#include <dirent.h>
#include <errno.h>
#include <pcrecpp.h>
continue;
}
Try {
+ Assert(m_path);
INodePtr node = Node::resolve(*m_path + entry->d_name);
node->setPermissions(getPermissions()); // inherit access rights
if (NodeFilterMatcher::match(node, filter)) {
ThrowMsg(Commons::SecurityException, "Not enough permissions.");
}
+ Assert(m_path);
+ Assert(path);
IPathPtr childPath = *m_path + *path;
if (exists(childPath)) {
ThrowMsg(Commons::PlatformException, "Node already exists.");
{
LocationPaths roots = IManager::getInstance().getLocationPaths();
for (LocationPaths::iterator it = roots.begin(); it != roots.end(); ++it) {
+ Assert(*it);
+ Assert(m_path);
if (*(*it) == *m_path) {
return INodePtr();
}
void Node::removeAsDirectory(const IPathPtr& path,
bool recursive)
{
+ Assert(path);
if (recursive) {
- DIR* dir = opendir(path->getFullPath().c_str());
- if (!dir) {
- LogError("File: " << path->getFullPath().c_str());
- ThrowMsg(Commons::PlatformException,
- "Node does not exist or access denied.");
+ FTS *fts;
+ FTSENT *ftsent;
+ int error = 0;
+ std::string pth=path->getFullPath();
+ char * const paths[] = {const_cast<char * const>(pth.c_str()), NULL};
+
+ if ((fts = fts_open(paths, FTS_PHYSICAL|FTS_NOCHDIR, NULL)) == NULL) {
+ //ERROR
+ error = errno;
+ LogError(__PRETTY_FUNCTION__ << ": fts_open on "
+ << pth
+ << " failed with error: "
+ << strerror(error));
+ ThrowMsg(Commons::PlatformException, "Failed to traverse Node");
}
- errno = 0;
- struct dirent *entry = NULL;
- while ((entry = readdir(dir))) {
- if (!strncmp(entry->d_name, ".",
- 1) || !strncmp(entry->d_name, "..", 2)) {
- continue;
- }
- IPathPtr subPath = *path + entry->d_name;
- struct stat info;
- memset(&info, 0, sizeof(struct stat));
- if (lstat(subPath->getFullPath().c_str(), &info) == 0) {
- Try {
- if (S_ISDIR(info.st_mode)) {
- removeAsDirectory(subPath, true);
- } else if (S_ISREG(info.st_mode)) {
- removeAsFile(subPath);
+
+ while ((ftsent = fts_read(fts)) != NULL) {
+ switch (ftsent->fts_info) {
+ case FTS_D:
+ //directory in preorder - do nothing
+ break;
+ case FTS_DP:
+ //directory in postorder - remove
+ errno = 0;
+ if (rmdir(ftsent->fts_accpath) != 0) {
+ if (errno == EEXIST) {
+ ThrowMsg(Commons::PlatformException,
+ "Node has child nodes.");
+ }
+ ThrowMsg(Commons::PlatformException,
+ "Error while removing platform node.");
}
- }
- Catch(Commons::PlatformException) {
- }
- // TODO: Not sure if above exception should be swallowed.
+ break;
+ case FTS_DC:
+ case FTS_F:
+ case FTS_NSOK:
+ case FTS_SL:
+ case FTS_SLNONE:
+ case FTS_DEFAULT:
+ {
+ //regular files and other objects that can safely be removed
+ IPathPtr file_path = IPath::create(ftsent->fts_path);
+ removeAsFile(file_path);
+ break;
+ }
+ case FTS_NS:
+ case FTS_DOT:
+ case FTS_DNR:
+ case FTS_ERR:
+ default:
+ LogWarning(__PRETTY_FUNCTION__
+ << ": traversal failed with error: "
+ << strerror(ftsent->fts_errno));
+ break;
}
}
- closedir(dir);
- }
- errno = 0;
- if (rmdir(path->getFullPath().c_str()) != 0) {
- if (errno == EEXIST) {
- ThrowMsg(Commons::PlatformException, "Node has child nodes.");
+ if (fts_close(fts) == -1) {
+ error = errno;
+ LogWarning(__PRETTY_FUNCTION__ << ": fts_close failed with error: "
+ << strerror(error));
+ }
+ } else {
+ if (rmdir(path->getFullPath().c_str()) != 0) {
+ if (errno == EEXIST) {
+ ThrowMsg(Commons::PlatformException, "Node has child nodes.");
+ }
+ ThrowMsg(Commons::PlatformException,
+ "Error while removing platform node.");
}
- ThrowMsg(Commons::PlatformException,
- "Error while removing platform node.");
}
}