+/*
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
#include "filesys.h"
+#include "strfnd.h"
#include <iostream>
+#include <string.h>
namespace fs
{
-#ifdef _WIN32
+#ifdef _WIN32 // WINDOWS
#define _WIN32_WINNT 0x0501
-#include <Windows.h>
+#include <windows.h>
#include <stdio.h>
#include <malloc.h>
#include <tchar.h>
}
else
{
+ // NOTE:
+ // Be very sure to not include '..' in the results, it will
+ // result in an epic failure when deleting stuff.
+
DirListNode node;
node.name = FindFileData.cFileName;
node.dir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- listing.push_back(node);
+ if(node.name != "." && node.name != "..")
+ listing.push_back(node);
// List all the other files in the directory.
while (FindNextFile(hFind, &FindFileData) != 0)
DirListNode node;
node.name = FindFileData.cFileName;
node.dir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
- listing.push_back(node);
+ if(node.name != "." && node.name != "..")
+ listing.push_back(node);
}
dwError = GetLastError();
return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES);
}
-#else
+bool RecursiveDelete(std::string path)
+{
+ std::cerr<<"Removing \""<<path<<"\""<<std::endl;
+
+ //return false;
+
+ // This silly function needs a double-null terminated string...
+ // Well, we'll just make sure it has at least two, then.
+ path += "\0\0";
+
+ SHFILEOPSTRUCT sfo;
+ sfo.hwnd = NULL;
+ sfo.wFunc = FO_DELETE;
+ sfo.pFrom = path.c_str();
+ sfo.pTo = NULL;
+ sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
+
+ int r = SHFileOperation(&sfo);
+
+ if(r != 0)
+ std::cerr<<"SHFileOperation returned "<<r<<std::endl;
+
+ //return (r == 0);
+ return true;
+}
-#ifdef linux
+#else // POSIX
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
+#include <sys/wait.h>
std::vector<DirListNode> GetDirListing(std::string pathstring)
{
}
while ((dirp = readdir(dp)) != NULL) {
+ // NOTE:
+ // Be very sure to not include '..' in the results, it will
+ // result in an epic failure when deleting stuff.
if(dirp->d_name[0]!='.'){
DirListNode node;
node.name = dirp->d_name;
if(dirp->d_type == DT_DIR) node.dir = true;
else node.dir = false;
- listing.push_back(node);
+ if(node.name != "." && node.name != "..")
+ listing.push_back(node);
}
}
closedir(dp);
return (stat(path.c_str(),&st) == 0);
}
-#else
-
-#include "boost/filesystem/operations.hpp"
-namespace bfsys = boost::filesystem;
-
-std::vector<DirListNode> GetDirListing(std::string pathstring)
+bool RecursiveDelete(std::string path)
{
- std::vector<DirListNode> listing;
-
- bfsys::path path(pathstring);
+ /*
+ Execute the 'rm' command directly, by fork() and execve()
+ */
+
+ std::cerr<<"Removing \""<<path<<"\""<<std::endl;
- if( !exists( path ) ) return listing;
+ //return false;
+
+ pid_t child_pid = fork();
- bfsys::directory_iterator end_itr; // default construction yields past-the-end
- for( bfsys::directory_iterator itr( path ); itr != end_itr; ++itr ){
- DirListNode node;
- node.name = itr->leaf();
- node.dir = is_directory(*itr);
- listing.push_back(node);
+ if(child_pid == 0)
+ {
+ // Child
+ char argv_data[3][10000];
+ strcpy(argv_data[0], "/bin/rm");
+ strcpy(argv_data[1], "-rf");
+ strncpy(argv_data[2], path.c_str(), 10000);
+ char *argv[4];
+ argv[0] = argv_data[0];
+ argv[1] = argv_data[1];
+ argv[2] = argv_data[2];
+ argv[3] = NULL;
+
+ std::cerr<<"Executing '"<<argv[0]<<"' '"<<argv[1]<<"' '"
+ <<argv[2]<<"'"<<std::endl;
+
+ execv(argv[0], argv);
+
+ // Execv shouldn't return. Failed.
+ _exit(1);
+ }
+ else
+ {
+ // Parent
+ int child_status;
+ pid_t tpid;
+ do{
+ tpid = wait(&child_status);
+ //if(tpid != child_pid) process_terminated(tpid);
+ }while(tpid != child_pid);
+ return (child_status == 0);
}
-
- return listing;
}
-bool CreateDir(std::string path)
+#endif
+
+bool RecursiveDeleteContent(std::string path)
{
- std::cout<<"CreateDir not implemented in boost"<<std::endl;
- return false;
+ std::cerr<<"Removing content of \""<<path<<"\""<<std::endl;
+ std::vector<DirListNode> list = GetDirListing(path);
+ for(unsigned int i=0; i<list.size(); i++)
+ {
+ if(trim(list[i].name) == "." || trim(list[i].name) == "..")
+ continue;
+ std::string childpath = path + DIR_DELIM + list[i].name;
+ bool r = RecursiveDelete(childpath);
+ if(r == false)
+ {
+ std::cerr<<"Removing \""<<childpath<<"\" failed"<<std::endl;
+ return false;
+ }
+ }
+ return true;
}
-#endif
-
-#endif
+bool CreateAllDirs(std::string path)
+{
+ size_t pos;
+ std::vector<std::string> tocreate;
+ std::string basepath = path;
+ while(!PathExists(basepath))
+ {
+ tocreate.push_back(basepath);
+ pos = basepath.rfind(DIR_DELIM_C);
+ if(pos == std::string::npos)
+ return false;
+ basepath = basepath.substr(0,pos);
+ }
+ for(int i=tocreate.size()-1;i>=0;i--)
+ CreateDir(tocreate[i]);
+ return true;
}
+} // namespace fs
+