From: Arvin Schnell Date: Mon, 14 Feb 2011 17:34:25 +0000 (+0100) Subject: - started with actual rollback implementation X-Git-Tag: v0.1.3~486 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=6fdcedfac16189145c98b59663ee47bd4a54760f;p=thirdparty%2Fsnapper.git - started with actual rollback implementation --- diff --git a/snapper/AppUtil.cc b/snapper/AppUtil.cc index 40242081..21a84b73 100644 --- a/snapper/AppUtil.cc +++ b/snapper/AppUtil.cc @@ -93,6 +93,13 @@ setStatMode(const string& Path_Cv, mode_t val ) } + bool + getLStat(const string& path, struct stat& fs) + { + return lstat(path.c_str(), &fs) == 0; + } + + bool checkNormalFile(const string& Path_Cv) { diff --git a/snapper/AppUtil.h b/snapper/AppUtil.h index dcf5a508..6b0661ff 100644 --- a/snapper/AppUtil.h +++ b/snapper/AppUtil.h @@ -46,6 +46,8 @@ bool checkDir(const string& Path_Cv); bool getStatMode(const string& Path_Cv, mode_t& val ); bool setStatMode(const string& Path_Cv, mode_t val ); + bool getLStat(const string& path, struct stat& fs); + list glob(const string& path, int flags); bool readlink(const string& path, string& buf); diff --git a/snapper/File.cc b/snapper/File.cc index 0d4bf4ef..e055d43d 100644 --- a/snapper/File.cc +++ b/snapper/File.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include "snapper/File.h" #include "snapper/Snapper.h" @@ -40,6 +41,29 @@ namespace snapper { + std::ostream& operator<<(std::ostream& s, const RollbackStatistic& rs) + { + s << "numCreate:" << rs.numCreate + << " numModify:" << rs.numModify + << " numDelete:" << rs.numDelete; + + return s; + } + + + RollbackStatistic::RollbackStatistic() + : numCreate(0), numModify(0), numDelete(0) + { + } + + + bool + RollbackStatistic::empty() const + { + return numCreate == 0 && numModify == 0 && numDelete == 0; + } + + std::ostream& operator<<(std::ostream& s, const File& file) { s << "name:\"" << file.name << "\""; @@ -279,20 +303,76 @@ namespace snapper if (getPreToPostStatus() == CREATED) { cout << "delete " << name << endl; + + struct stat fs; + getLStat(getAbsolutePath(LOC_POST), fs); + + if (S_ISREG(fs.st_mode) || S_ISLNK(fs.st_mode)) + { + unlink(getAbsolutePath(LOC_SYSTEM).c_str()); + } + else if (S_ISDIR(fs.st_mode)) + { + rmdir(getAbsolutePath(LOC_SYSTEM).c_str()); + } } else if (getPreToPostStatus() == DELETED) { cout << "create " << name << endl; + + struct stat fs; + getLStat(getAbsolutePath(LOC_PRE), fs); + + if (S_ISREG(fs.st_mode) || S_ISLNK(fs.st_mode)) + { + SystemCmd cmd(CPBIN " --no-dereference --preserve=mode,ownership,links " + + getAbsolutePath(LOC_PRE) + " " + getAbsolutePath(LOC_SYSTEM)); + } + else if (S_ISDIR(fs.st_mode)) + { + mkdir(getAbsolutePath(LOC_SYSTEM).c_str(), 0777); + } } else { cout << "modify " << name << endl; + + struct stat fs; + getLStat(getAbsolutePath(LOC_PRE), fs); + + if (S_ISREG(fs.st_mode) || S_ISLNK(fs.st_mode)) + { + SystemCmd cmd(CPBIN " --no-dereference --preserve=mode,ownership,links " + + getAbsolutePath(LOC_PRE) + " " + getAbsolutePath(LOC_SYSTEM)); + } } return true; } + RollbackStatistic + Files::getRollbackStatistic() const + { + RollbackStatistic rs; + + for (vector::const_iterator it = entries.begin(); it != entries.end(); ++it) + { + if (it->getRollback()) + { + if (it->getPreToPostStatus() == CREATED) + rs.numDelete++; + else if (it->getPreToPostStatus() == DELETED) + rs.numCreate++; + else + rs.numModify++; + } + } + + return rs; + } + + bool Files::doRollback() { diff --git a/snapper/File.h b/snapper/File.h index b65ac65c..fe0859c2 100644 --- a/snapper/File.h +++ b/snapper/File.h @@ -54,6 +54,20 @@ namespace snapper }; + struct RollbackStatistic + { + RollbackStatistic(); + + bool empty() const; + + unsigned int numCreate; + unsigned int numModify; + unsigned int numDelete; + + friend std::ostream& operator<<(std::ostream& s, const RollbackStatistic& rs); + }; + + class File { public: @@ -129,6 +143,8 @@ namespace snapper bool load(); bool save(); + RollbackStatistic getRollbackStatistic() const; + bool doRollback(); const Snapper* snapper; diff --git a/snapper/Snapper.cc b/snapper/Snapper.cc index d3fbe53b..3ab585bb 100644 --- a/snapper/Snapper.cc +++ b/snapper/Snapper.cc @@ -142,6 +142,13 @@ namespace snapper } + RollbackStatistic + Snapper::getRollbackStatistic() const + { + return files.getRollbackStatistic(); + } + + bool Snapper::doRollback() { diff --git a/snapper/Snapper.h b/snapper/Snapper.h index 5518f540..57c13533 100644 --- a/snapper/Snapper.h +++ b/snapper/Snapper.h @@ -72,6 +72,8 @@ namespace snapper Files& getFiles() { return files; } const Files& getFiles() const { return files; } + RollbackStatistic getRollbackStatistic() const; + bool doRollback(); void setCompareCallback(CompareCallback* p) { compare_callback = p; } diff --git a/snapper/SnapperDefines.h b/snapper/SnapperDefines.h index fe4cdadf..fd6ded3c 100644 --- a/snapper/SnapperDefines.h +++ b/snapper/SnapperDefines.h @@ -33,5 +33,7 @@ #define COMPAREDIRSBIN "/usr/lib/snapper/bin/compare-dirs" +#define CPBIN "/bin/cp" + #endif diff --git a/tools/snapper.cc b/tools/snapper.cc index 5a524e90..67017c75 100644 --- a/tools/snapper.cc +++ b/tools/snapper.cc @@ -368,6 +368,17 @@ command_rollback() it->setRollback(true); } + RollbackStatistic rs = sh->getRollbackStatistic(); + + if (rs.empty()) + { + cout << "nothing to do" << endl; + return; + } + + cout << "create:" << rs.numCreate << " modify:" << rs.numModify << " delete:" << rs.numDelete + << endl; + sh->doRollback(); }