Created
August 26, 2011 22:56
-
-
Save retep998/1174642 to your computer and use it in GitHub Desktop.
Backup system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <boost/filesystem.hpp> | |
#include <boost/lexical_cast.hpp> | |
using namespace boost::filesystem; | |
using boost::lexical_cast; | |
//std | |
#include <iostream> | |
#include <string> | |
#include <fstream> | |
#include <map> | |
using namespace std; | |
#define FAIL exit(273); | |
int main(int argc, char* argv[]) { | |
if (argc<3) { | |
FAIL | |
} | |
string command = argv[1]; | |
path p = argv[2]; | |
auto strip = [&](path pp) -> path { | |
path result; | |
for (auto it1 = pp.begin(), it2 = p.begin(); it1 != pp.end(); it1++) { | |
if (it2 != p.end()) { | |
it2++; | |
} else { | |
result /= *it1; | |
} | |
} | |
return result; | |
}; | |
if (command == "backup") { | |
cout << "Backing up your shit" << endl; | |
time_t curtime = time(0); | |
string timestr = lexical_cast <string> (curtime); | |
path info = p; | |
info /= "info.dat"; | |
file_status stat = status(info); | |
file_type t = stat.type(); | |
map <string, pair <time_t, time_t>> last; | |
if (t == regular_file) { | |
ifstream file(info.string()); | |
while (!file.eof()) { | |
time_t back; | |
time_t mod; | |
file >> back >> mod; | |
char s[1024]; | |
file.getline(s, 1024); | |
last[string(s).substr(1)].first = back; | |
last[string(s).substr(1)].second = mod; | |
} | |
file.close(); | |
} else if (t = file_not_found) { | |
//Ignore | |
} else { | |
FAIL | |
} | |
create_directory(p/"backup"); | |
create_directory(p/"backup"/timestr); | |
function <void(path)> recurse = [&](path pp) { | |
for (directory_iterator it(pp); it != directory_iterator(); it++) { | |
if (is_directory(it->path())) { | |
if (it->path().filename() == "backup") { | |
//Ignore | |
} else { | |
path fun = strip(it->path()); | |
create_directory(p/"backup"/timestr/fun); | |
recurse(it->path()); | |
} | |
} else if (is_regular_file(it->path())) { | |
if (it->path().filename() == "info.dat") { | |
//Ignore | |
} else { | |
time_t mod = last_write_time(it->path()); | |
path fun = strip(it->path()); | |
if (mod != last[fun.string()].second) { | |
cout << "Adding: " << fun << endl; | |
last[fun.string()].first = curtime; | |
last[fun.string()].second = mod; | |
copy_file(p/fun, p/"backup"/timestr/fun); | |
} | |
} | |
} else { | |
//Ignore | |
} | |
} | |
}; | |
for (auto it = last.begin(); it != last.end();) { | |
if (!is_regular_file(p/it->first)) { | |
cout << "Removing: " << it->first << endl; | |
last.erase(it++); | |
} else { | |
it++; | |
} | |
} | |
recurse(p); | |
ofstream file(info.string()); | |
for (auto it = last.begin(); it != last.end(); it++) { | |
if (it != last.begin()) { | |
file << endl; | |
} | |
file << it->second.first << " " << it->second.second << " " << it->first; | |
} | |
file.close(); | |
copy_file(p/"info.dat", p/"backup"/timestr/"info.dat"); | |
} else if (command == "restore") { | |
if (argc<4) { | |
FAIL | |
} | |
cout << "Restoring your shit" << endl; | |
string version = argv[3]; | |
map <string, pair <time_t, time_t>> last; | |
ifstream file((p/"backup"/version/"info.dat").string()); | |
while (!file.eof()) { | |
time_t back; | |
time_t mod; | |
file >> back >> mod; | |
char s[1024]; | |
file.getline(s, 1024); | |
last[string(s).substr(1)].first = back; | |
last[string(s).substr(1)].second = mod; | |
} | |
file.close(); | |
function <void(path)> recurse = [&](path pp) { | |
for (directory_iterator it(pp); it != directory_iterator(); it++) { | |
if (is_directory(it->path())) { | |
if (it->path().filename() == "backup") { | |
//Ignore | |
} else { | |
recurse(it->path()); | |
} | |
} else if (is_regular_file(it->path())) { | |
if (it->path().filename() == "info.dat") { | |
} else { | |
time_t mod = last_write_time(it->path()); | |
path fun = strip(it->path()); | |
if (last.find(fun.string()) == last.end()) { | |
cout << "Erasing: " << fun << endl; | |
if (exists(it->path())) { | |
remove(it->path()); | |
} | |
} else if (mod != last[fun.string()].second) { | |
cout << "Restoring: " << fun << endl; | |
copy_file(p/"backup"/lexical_cast<string>(last[fun.string()].first)/fun, p/fun, copy_option::overwrite_if_exists); | |
last.erase(fun.string()); | |
} | |
} | |
} else { | |
//Ignore | |
} | |
} | |
}; | |
recurse(p); | |
for (auto it = last.begin(); it != last.end(); it++) { | |
function <void(path)> verify = [&](path pp) { | |
if (exists(pp)) { | |
return; | |
} else { | |
verify(pp.parent_path()); | |
create_directory(pp); | |
} | |
}; | |
verify(p/"backup"/lexical_cast<string>(it->second.first)/it->first); | |
copy_file(p/"backup"/lexical_cast<string>(it->second.first)/it->first, p/it->first, copy_option::overwrite_if_exists); | |
cout << "Restoring: " << it->first << endl; | |
} | |
copy_file(p/"backup"/version/"info.dat", p/"info.dat", copy_option::overwrite_if_exists); | |
} else { | |
FAIL | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment