Exemple #1
0
inline bool delete_subdirectories_recursive
(const std::string &refcstrRootDirectory, const char *dont_delete_this)
{
    DIR *d = opendir(refcstrRootDirectory.c_str());
    if(!d) {
        return false;
    }

    struct dir_close
    {
        DIR *d_;
        dir_close(DIR *d) : d_(d) {}
        ~dir_close() {
            ::closedir(d_);
        }
    } dc(d);
    (void)dc;

    struct ::dirent *de;
    struct ::stat st;
    std::string fn;

    while((de=::readdir(d))) {
        if( de->d_name[0] == '.' && ( de->d_name[1] == '\0'
                                      || (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ) {
            continue;
        }
        if(dont_delete_this && std::strcmp(dont_delete_this, de->d_name) == 0) {
            continue;
        }
        fn = refcstrRootDirectory;
        fn += '/';
        fn += de->d_name;

        if(std::remove(fn.c_str())) {
            if(::stat(fn.c_str(), & st)) {
                return false;
            }
            if(S_ISDIR(st.st_mode)) {
                if(!delete_subdirectories_recursive(fn, 0) ) {
                    return false;
                }
            } else {
                return false;
            }
        }
    }
    return std::remove(refcstrRootDirectory.c_str()) ? false : true;
}
//This function erases all the subdirectories of a directory except the one pointed by "dont_delete_this"
inline bool delete_subdirectories(const std::string &refcstrRootDirectory, const char *dont_delete_this)
{
   return delete_subdirectories_recursive(refcstrRootDirectory, dont_delete_this );
}
inline bool delete_subdirectories_recursive
   (const std::string &refcstrRootDirectory, const char *dont_delete_this, unsigned int count)
{
   bool               bSubdirectory = false;       // Flag, indicating whether
                                                   // subdirectories have been found
   void *             hFile;                       // Handle to directory
   std::string        strFilePath;                 // Filepath
   std::string        strPattern;                  // Pattern
   winapi::win32_find_data_t  FileInformation;     // File information

   //Find all files and directories
   strPattern = refcstrRootDirectory + "\\*.*";
   hFile = winapi::find_first_file(strPattern.c_str(), &FileInformation);
   if(hFile != winapi::invalid_handle_value){
      do{
         //If it's not "." or ".." or the pointed root_level dont_delete_this erase it
         if(FileInformation.cFileName[0] != '.' &&
            !(dont_delete_this && count == 0 && std::strcmp(dont_delete_this, FileInformation.cFileName) == 0)){
            strFilePath.erase();
            strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;

            //If it's a directory, go recursive
            if(FileInformation.dwFileAttributes & winapi::file_attribute_directory){
               // Delete subdirectory
               if(!delete_subdirectories_recursive(strFilePath, dont_delete_this, count+1))
                  return false;
            }
            //If it's a file, just delete it
            else{
               // Set file attributes
               //if(::SetFileAttributes(strFilePath.c_str(), winapi::file_attribute_normal) == 0)
               //return winapi::get_last_error();
               // Delete file
               winapi::delete_file(strFilePath.c_str());
            }
         }
      //Go to the next file
      } while(winapi::find_next_file(hFile, &FileInformation) == 1);

      // Close handle
      winapi::find_close(hFile);

      //See if the loop has ended with an error or just because we've traversed all the files
      if(winapi::get_last_error() != winapi::error_no_more_files){
         return false;
      }
      else
      {
         //Erase empty subdirectories or original refcstrRootDirectory
         if(!bSubdirectory && count)
         {
            // Set directory attributes
            //if(::SetFileAttributes(refcstrRootDirectory.c_str(), FILE_ATTRIBUTE_NORMAL) == 0)
               //return ::GetLastError();
            // Delete directory
            if(winapi::remove_directory(refcstrRootDirectory.c_str()) == 0)
               return false;
         }
      }
   }
   return true;
}