/* Minetest-c55 Copyright (C) 2010 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 #include #include "log.h" namespace fs { #ifdef _WIN32 // WINDOWS #define _WIN32_WINNT 0x0501 #include #include #include #include #include #include #define BUFSIZE MAX_PATH std::vector GetDirListing(std::string pathstring) { std::vector listing; WIN32_FIND_DATA FindFileData; HANDLE hFind = INVALID_HANDLE_VALUE; DWORD dwError; LPTSTR DirSpec; INT retval; DirSpec = (LPTSTR) malloc (BUFSIZE); if( DirSpec == NULL ) { errorstream<<"GetDirListing: Insufficient memory available"< (BUFSIZE - 2)) { errorstream<<"GetDirListing: Input directory is too large."< content = GetDirListing(path); for(int i=0; i #include #include #include #include #include std::vector GetDirListing(std::string pathstring) { std::vector listing; DIR *dp; struct dirent *dirp; if((dp = opendir(pathstring.c_str())) == NULL) { //infostream<<"Error("<d_name[0]!='.'){ DirListNode node; node.name = dirp->d_name; if(node.name == "." || node.name == "..") continue; int isdir = -1; // -1 means unknown /* POSIX doesn't define d_type member of struct dirent and certain filesystems on glibc/Linux will only return DT_UNKNOWN for the d_type member. Also we don't know whether symlinks are directories or not. */ #ifdef _DIRENT_HAVE_D_TYPE if(dirp->d_type != DT_UNKNOWN && dirp->d_type != DT_LNK) isdir = (dirp->d_type == DT_DIR); #endif /* _DIRENT_HAVE_D_TYPE */ /* Was d_type DT_UNKNOWN, DT_LNK or nonexistent? If so, try stat(). */ if(isdir == -1) { struct stat statbuf; if (stat((pathstring + "/" + node.name).c_str(), &statbuf)) continue; isdir = ((statbuf.st_mode & S_IFDIR) == S_IFDIR); } node.dir = isdir; listing.push_back(node); } } closedir(dp); return listing; } bool CreateDir(std::string path) { int r = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); if(r == 0) { return true; } else { // If already exists, return true if(errno == EEXIST) return true; return false; } } bool PathExists(std::string path) { struct stat st; return (stat(path.c_str(),&st) == 0); } bool IsDir(std::string path) { struct stat statbuf; if(stat(path.c_str(), &statbuf)) return false; // Actually error; but certainly not a directory return ((statbuf.st_mode & S_IFDIR) == S_IFDIR); } bool RecursiveDelete(std::string path) { /* Execute the 'rm' command directly, by fork() and execve() */ infostream<<"Removing \""< &dst) { std::vector content = GetDirListing(path); for(unsigned int i=0; i &paths) { bool success = true; // Go backwards to succesfully delete the output of GetRecursiveSubPaths for(int i=paths.size()-1; i>=0; i--){ const std::string &path = paths[i]; bool did = DeleteSingleFileOrEmptyDirectory(path); if(!did){ errorstream<<"Failed to delete "< list = GetDirListing(path); for(unsigned int i=0; i tocreate; std::string basepath = path; while(!PathExists(basepath)) { tocreate.push_back(basepath); pos = basepath.rfind(DIR_DELIM_C); if(pos == std::string::npos) break; basepath = basepath.substr(0,pos); } for(int i=tocreate.size()-1;i>=0;i--) if(!CreateDir(tocreate[i])) return false; return true; } } // namespace fs