Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- #include <boost/filesystem/operations.hpp>
- #include <boost/filesystem/fstream.hpp>
- #include <hashlibpp.h>
- #include <ext/hash_map>
- #include <list>
- #include <sys/stat.h>
- struct eqstr
- {
- bool operator()(const char* s1, const char* s2) const
- {
- return strcmp(s1, s2) == 0;
- }
- };
- namespace fs = boost::filesystem;
- namespace stdext = __gnu_cxx;
- const std::string DS = "/";
- typedef stdext::hash_map<const char*, std::string, stdext::hash<const char*>, eqstr> hashMapType;
- class Backup {
- public:
- Backup(std::string sDir, std::string tDir, std::string mDir) {
- if (!file_exists(sDir)) {
- std::cout << "sourcedir does not exists" << std::endl;
- }
- sourceDir = sDir;
- targetDir = tDir;
- md5Dir = mDir;
- }
- bool backup() {
- fs::path pathToIter(fs::initial_path<fs::path>());
- pathToIter = fs::system_complete(fs::path(sourceDir));
- if (!fs::exists(pathToIter) || !fs::is_directory(pathToIter)) {
- // std::cout << "Backup directory '" << pathToIter.file_string() << "'not found" << std::endl;
- return false;
- }
- fs::directory_iterator endIter;
- for (fs::directory_iterator dirIter(pathToIter); dirIter != endIter; ++dirIter) {
- try {
- if (fs::is_directory(*dirIter)) {
- backupDir(dirIter->filename());
- if (!saveLastMd5File(dirIter->filename())) {
- std::cout << "Savind last md5 FAILED! More than 500k files in last md5? check! Directory: '" << dirIter->filename() << "'" << std::endl;
- std::string fullFileName = targetDir;
- fullFileName.append(DS).append(dirIter->filename()).append(".last.md5");
- // remove(fullFileName.c_str());
- }
- saveFilesToSave(dirIter->filename());
- }
- } catch(const std::exception & e) {
- std::cout << e.what() << std::endl;
- }
- }
- return true;
- }
- private:
- std::string sourceDir;
- std::string targetDir;
- std::string md5Dir;
- std::list<std::string> filesToSave;
- hashMapType currentMd5Filelist;
- void saveFilesToSave(std::string dirName) {
- std::string filesToSaveFileName = targetDir;
- filesToSaveFileName.append(DS).append("files_to_save.").append(dirName);
- if (file_exists(filesToSaveFileName)) {
- std::remove(filesToSaveFileName.c_str());
- }
- if (filesToSave.size() > 0) {
- std::fstream out;
- out.open(filesToSaveFileName.c_str(), std::ios::out);
- for (std::list<std::string>::iterator iter = filesToSave.begin(); iter != filesToSave.end(); iter++) {
- out << *iter << std::endl;
- }
- out.close();
- std::cout << "Saved files to backup to '" << filesToSaveFileName << "'" << std::endl;
- }
- filesToSave.clear();
- }
- bool saveLastMd5File(std::string dirName) {
- std::fstream out;
- std::string fullFileName = targetDir;
- fullFileName.append(DS).append(dirName).append(".last.md5");
- std::cout << "Saving last md5 to " << fullFileName << std::endl;
- out.open(fullFileName.c_str(), std::ios::out);
- hashMapType::iterator iter = currentMd5Filelist.begin();
- unsigned long int count = 0;
- while (iter != currentMd5Filelist.end()) {
- if (count > 500000) {
- return false;
- }
- count++;
- out << iter->second << " " << iter->first << std::endl;
- iter++;
- }
- out.close();
- return true;
- }
- bool generateFilesToSave(std::string directory) {
- std::string currentDir = sourceDir;
- hashwrapper *md5 = new md5wrapper();
- fs::path pathToIter(fs::initial_path<fs::path>());
- pathToIter = fs::system_complete(fs::path(currentDir.append(DS).append(directory)));
- if (!fs::exists(pathToIter) || !fs::is_directory(pathToIter)) {
- // std::cout << "Given directory name is not really a directory... " << pathToIter.file_string() << std::endl;
- return false;
- }
- // std::cout << "parsing directory: " << pathToIter.file_string() << std::endl;
- fs::directory_iterator endIter;
- std::string currentFile;
- std::string currentMd5;
- std::string currentFileWithRelativePath;
- for (fs::directory_iterator dirIter(pathToIter); dirIter != endIter; ++dirIter) {
- currentFile = currentDir;
- currentFile.append(DS).append(dirIter->filename());
- currentFileWithRelativePath = directory;
- currentFileWithRelativePath.append(DS).append(dirIter->filename());
- try {
- if (fs::is_directory(*dirIter) && !fs::is_symlink(*dirIter)) {
- generateFilesToSave(currentFileWithRelativePath);
- } else if (fs::is_regular(*dirIter)) {
- // backup file if file not found or md5 differs
- hashMapType::iterator finder = currentMd5Filelist.find(currentFileWithRelativePath.c_str());
- try {
- currentMd5 = md5->getHashFromFile(currentFile);
- } catch(hlException &e) {
- std::count << "cought hlException and therefore ignoring file: " << currentfile << std::endl;
- continue;
- }
- if (finder == currentMd5Filelist.end() || currentMd5 != finder->second) {
- filesToSave.push_back(currentFileWithRelativePath);
- std::pair<const char*, std::string> pair;
- pair.first = currentFileWithRelativePath.c_str();
- pair.second = currentMd5;
- if (finder != currentMd5Filelist.end()) {
- // std::cout << "File found in hash_map - replacing md5 sum: " << currentFileWithRelativePath << std::endl;
- currentMd5Filelist.erase(currentFileWithRelativePath.c_str());
- } else {
- // std::cout << "file not found in hash_map: " << currentFileWithRelativePath << std::endl;
- }
- currentMd5Filelist.insert(pair);
- }
- }
- } catch (const std::exception & e) {
- std::cout << e.what() << std::endl;
- }
- }
- return true;
- }
- void backupDir(std::string dir) {
- std::string md5File = targetDir;
- md5File.append(DS).append(dir).append(".last.md5");
- currentMd5Filelist.clear();
- if (file_exists(md5File)) {
- std::cout << dir << ": getting md5 from last backup run" << std::endl;
- readMd5File(md5File);
- remove(md5File.c_str());
- } else {
- md5File = md5Dir;
- md5File.append(DS).append(dir).append(".md5");
- if (file_exists(md5File)) {
- std::cout << dir << ": getting md5" << std::endl;
- readMd5File(md5File);
- } else {
- std::cout << dir << ": cannot find md5 file - backing up everything" << std::endl;
- }
- }
- std::cout << "parsing directory: " << dir << std::endl;
- generateFilesToSave(dir);
- }
- void readMd5File(std::string filename) {
- std::ifstream ifs(filename.c_str());
- std::string line;
- while (std::getline(ifs, line)) {
- std::pair<const char*, std::string> pair;
- char* key = new char[line.substr(34, line.size()).size()+1];
- strcpy(key, line.substr(34, line.size()).c_str());
- pair.first = key;
- pair.second = line.substr(0, 32);
- currentMd5Filelist.insert(pair);
- }
- return;
- }
- bool file_exists(std::string filename) {
- struct stat fileInfo;
- return stat(filename.c_str(), &fileInfo) == 0;
- }
- };
Add Comment
Please, Sign In to add comment