X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Ffilesys.cpp;h=256c8f16a6dea94a29c9bd3e437fa5686c1bd4fa;hb=d3f0ce62240b7598eded13153eacb410bf2420a1;hp=287090e8a94ec068a4ba92e755330481f69887fb;hpb=a0f0517c5bec0a2b667813abb9ff8b08cd318952;p=minetest.git diff --git a/src/filesys.cpp b/src/filesys.cpp index 287090e8a..256c8f16a 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -1,18 +1,18 @@ /* -Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola 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 +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 General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License along +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. */ @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "strfnd.h" #include #include +#include "log.h" namespace fs { @@ -28,7 +29,7 @@ namespace fs #ifdef _WIN32 // WINDOWS #define _WIN32_WINNT 0x0501 -#include +#include #include #include #include @@ -51,7 +52,7 @@ std::vector GetDirListing(std::string pathstring) if( DirSpec == NULL ) { - printf( "Insufficient memory available\n" ); + errorstream<<"GetDirListing: Insufficient memory available"< GetDirListing(std::string pathstring) // Check that the input is not larger than allowed. if (pathstring.size() > (BUFSIZE - 2)) { - _tprintf(TEXT("Input directory is too large.\n")); + errorstream<<"GetDirListing: Input directory is too large."< GetDirListing(std::string pathstring) if (hFind == INVALID_HANDLE_VALUE) { - _tprintf (TEXT("Invalid file handle. Error is %u.\n"), - GetLastError()); - retval = (-1); + retval = (-1); + goto Cleanup; } else { @@ -103,10 +103,10 @@ std::vector GetDirListing(std::string pathstring) FindClose(hFind); if (dwError != ERROR_NO_MORE_FILES) { - _tprintf (TEXT("FindNextFile error. Error is %u.\n"), - dwError); - retval = (-1); - goto Cleanup; + errorstream<<"GetDirListing: FindNextFile error. Error is " + < GetDirListing(std::string pathstring) if(retval != 0) listing.clear(); //for(unsigned int i=0; i content = GetDirListing(path); + for(int i=0; i @@ -171,6 +214,7 @@ bool RecursiveDelete(std::string path) #include #include #include +#include std::vector GetDirListing(std::string pathstring) { @@ -179,7 +223,7 @@ std::vector GetDirListing(std::string pathstring) DIR *dp; struct dirent *dirp; if((dp = opendir(pathstring.c_str())) == NULL) { - //std::cout<<"Error("< GetDirListing(std::string pathstring) 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; - if(node.name != "." && node.name != "..") - listing.push_back(node); + 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); @@ -223,13 +293,21 @@ bool PathExists(std::string path) 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() */ - std::cerr<<"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