Guest User

Untitled

a guest
Feb 20th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.14 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <vector>
  5. #include <boost/filesystem/operations.hpp>
  6. #include <boost/filesystem/fstream.hpp>
  7. #include <hashlibpp.h>
  8. #include <ext/hash_map>
  9. #include <list>
  10. #include <sys/stat.h>
  11. struct eqstr
  12. {
  13.   bool operator()(const char* s1, const char* s2) const
  14.   {
  15.     return strcmp(s1, s2) == 0;
  16.   }
  17. };
  18.  
  19.  
  20. namespace fs = boost::filesystem;
  21. namespace stdext = __gnu_cxx;
  22. const std::string DS = "/";
  23. typedef stdext::hash_map<const char*, std::string, stdext::hash<const char*>, eqstr> hashMapType;
  24.  
  25. class Backup {
  26.     public:
  27.     Backup(std::string sDir, std::string tDir, std::string mDir) {
  28.         if (!file_exists(sDir)) {
  29.             std::cout << "sourcedir does not exists" << std::endl;
  30.         }
  31.         sourceDir = sDir;
  32.         targetDir = tDir;
  33.         md5Dir    = mDir;
  34.     }
  35.     bool backup() {
  36.         fs::path pathToIter(fs::initial_path<fs::path>());
  37.         pathToIter = fs::system_complete(fs::path(sourceDir));
  38.         if (!fs::exists(pathToIter) || !fs::is_directory(pathToIter)) {
  39. //          std::cout << "Backup directory '" << pathToIter.file_string() << "'not found" << std::endl;
  40.             return false;
  41.         }
  42.         fs::directory_iterator endIter;
  43.         for (fs::directory_iterator dirIter(pathToIter); dirIter != endIter; ++dirIter) {
  44.             try {
  45.             if (fs::is_directory(*dirIter)) {
  46.                 backupDir(dirIter->filename());
  47.                 if (!saveLastMd5File(dirIter->filename())) {
  48.                 std::cout << "Savind last md5 FAILED! More than 500k files in last md5? check! Directory: '" << dirIter->filename() <<  "'" << std::endl;
  49.                 std::string fullFileName = targetDir;
  50.                 fullFileName.append(DS).append(dirIter->filename()).append(".last.md5");
  51. //              remove(fullFileName.c_str());
  52.                 }
  53.                 saveFilesToSave(dirIter->filename());
  54.             }
  55.             } catch(const std::exception & e) {
  56.                         std::cout << e.what() << std::endl;
  57.                     }
  58.         }
  59.         return true;
  60.     }
  61.  
  62.     private:
  63.     std::string sourceDir;
  64.     std::string targetDir;
  65.     std::string md5Dir;
  66.     std::list<std::string> filesToSave;
  67.     hashMapType currentMd5Filelist;
  68.  
  69.     void saveFilesToSave(std::string dirName) {
  70.         std::string filesToSaveFileName = targetDir;
  71.         filesToSaveFileName.append(DS).append("files_to_save.").append(dirName);
  72.         if (file_exists(filesToSaveFileName)) {
  73.             std::remove(filesToSaveFileName.c_str());
  74.         }
  75.         if (filesToSave.size() > 0) {
  76.             std::fstream out;
  77.             out.open(filesToSaveFileName.c_str(), std::ios::out);
  78.             for (std::list<std::string>::iterator iter = filesToSave.begin(); iter != filesToSave.end(); iter++) {
  79.             out << *iter << std::endl;
  80.             }
  81.             out.close();
  82.             std::cout << "Saved files to backup to '" << filesToSaveFileName << "'" << std::endl;
  83.         }
  84.         filesToSave.clear();
  85.     }
  86.    
  87.     bool saveLastMd5File(std::string dirName) {
  88.         std::fstream out;
  89.         std::string fullFileName = targetDir;
  90.         fullFileName.append(DS).append(dirName).append(".last.md5");
  91.         std::cout << "Saving last md5 to " << fullFileName << std::endl;
  92.         out.open(fullFileName.c_str(), std::ios::out);
  93.         hashMapType::iterator iter = currentMd5Filelist.begin();
  94.         unsigned long int count = 0;
  95.         while (iter != currentMd5Filelist.end()) {
  96.         if (count > 500000) {
  97.             return false;
  98.         }
  99.         count++;
  100.         out << iter->second << "  " << iter->first << std::endl;
  101.         iter++;
  102.         }
  103.         out.close();
  104.         return true;
  105.     }
  106.    
  107.     bool generateFilesToSave(std::string directory) {
  108.         std::string currentDir = sourceDir;
  109.         hashwrapper *md5 = new md5wrapper();
  110.         fs::path pathToIter(fs::initial_path<fs::path>());
  111.         pathToIter = fs::system_complete(fs::path(currentDir.append(DS).append(directory)));
  112.         if (!fs::exists(pathToIter) || !fs::is_directory(pathToIter)) {
  113. //          std::cout << "Given directory name is not really a directory... " << pathToIter.file_string() << std::endl;
  114.             return false;
  115.         }
  116. //      std::cout << "parsing directory: " << pathToIter.file_string() << std::endl;
  117.         fs::directory_iterator endIter;
  118.         std::string currentFile;
  119.         std::string currentMd5;
  120.         std::string currentFileWithRelativePath;
  121.         for (fs::directory_iterator dirIter(pathToIter); dirIter != endIter; ++dirIter) {
  122.             currentFile = currentDir;
  123.             currentFile.append(DS).append(dirIter->filename());
  124.             currentFileWithRelativePath = directory;
  125.             currentFileWithRelativePath.append(DS).append(dirIter->filename());
  126.             try {
  127.                 if (fs::is_directory(*dirIter) && !fs::is_symlink(*dirIter)) {
  128.                     generateFilesToSave(currentFileWithRelativePath);
  129.                 } else if (fs::is_regular(*dirIter)) {
  130.                     // backup file if file not found or md5 differs
  131.                     hashMapType::iterator finder = currentMd5Filelist.find(currentFileWithRelativePath.c_str());
  132.                                         try {
  133.                                             currentMd5 = md5->getHashFromFile(currentFile);
  134.                                         } catch(hlException &e) {
  135.                                             std::count << "cought hlException and therefore ignoring file: " << currentfile << std::endl;
  136.                                             continue;
  137.                                         }
  138.                     if (finder == currentMd5Filelist.end() || currentMd5 != finder->second) {
  139.                         filesToSave.push_back(currentFileWithRelativePath);
  140.                         std::pair<const char*, std::string> pair;
  141.                         pair.first = currentFileWithRelativePath.c_str();
  142.                         pair.second = currentMd5;
  143.                         if (finder != currentMd5Filelist.end()) {
  144. //                      std::cout << "File found in hash_map - replacing md5 sum: " << currentFileWithRelativePath << std::endl;
  145.                         currentMd5Filelist.erase(currentFileWithRelativePath.c_str());
  146.                         } else {
  147. //                      std::cout << "file not found in hash_map: " << currentFileWithRelativePath << std::endl;
  148.                         }
  149.                         currentMd5Filelist.insert(pair);
  150.                     }
  151.                 }
  152.             } catch (const std::exception & e) {
  153.                 std::cout << e.what() << std::endl;
  154.             }
  155.         }
  156.         return true;
  157.     }
  158.    
  159.     void backupDir(std::string dir) {
  160.         std::string md5File = targetDir;
  161.         md5File.append(DS).append(dir).append(".last.md5");
  162.         currentMd5Filelist.clear();
  163.         if (file_exists(md5File)) {
  164.             std::cout << dir << ": getting md5 from last backup run" << std::endl;
  165.             readMd5File(md5File);
  166.             remove(md5File.c_str());
  167.         } else {
  168.             md5File = md5Dir;
  169.             md5File.append(DS).append(dir).append(".md5");
  170.             if (file_exists(md5File)) {
  171.             std::cout << dir << ": getting md5" << std::endl;
  172.             readMd5File(md5File);
  173.             } else {
  174.             std::cout << dir << ": cannot find md5 file - backing up everything" << std::endl;
  175.             }
  176.         }
  177.         std::cout << "parsing directory: " << dir << std::endl;
  178.         generateFilesToSave(dir);
  179.     }
  180.  
  181.    
  182.     void readMd5File(std::string filename) {
  183.         std::ifstream ifs(filename.c_str());
  184.         std::string line;      
  185.         while (std::getline(ifs, line)) {
  186.             std::pair<const char*, std::string> pair;
  187.             char* key = new char[line.substr(34, line.size()).size()+1];
  188.             strcpy(key, line.substr(34, line.size()).c_str());
  189.             pair.first = key;
  190.             pair.second = line.substr(0, 32);
  191.             currentMd5Filelist.insert(pair);
  192.         }
  193.         return;
  194.     }
  195.    
  196.     bool file_exists(std::string filename) {
  197.         struct stat fileInfo;
  198.         return stat(filename.c_str(), &fileInfo) == 0;
  199.     }
  200.  
  201. };
Add Comment
Please, Sign In to add comment