#include "backup.hpp"
#include "scandir.hpp"
#include "globals.hpp"
#include "time.hpp"
#include "dir.hpp"
#include "script.hpp"
#include <stdlib.h>
using namespace std;
#undef logger
string log_filename;
ofstream logger_f;
ostream *logger_p = 0;
#define logger (logger_p ? (*logger_p) : cerr)
string tar_suffix = ".tgz";
string zip_suffix = ".gz";
string gzip_path = "/bin/gzip";
// In gdb, do "break error_catcher" for debugging.
void error_catcher() {}
Backup::Backup()
{
sc = new Scanner(this);
}
void Backup::setBackupRoot(const std::string& root)
{
backup_root = root;
}
Backup::~Backup()
{
delete sc;
}
void Backup::addMyfiles(const string& path)
{
trees.push_back(path);
}
void Backup::backup_tree(const string& tree_root)
{
if (tree_root[0] != '/') {
cerr << "INTERNAL ERROR: Path " << tree_root << " is not absolute\n";
exit(-1);
}
// IFFY: Instance variables used by other objects
myfiles_root = tree_root;
backup_subdir = scrub_pathname(tree_root);
backup_path = backup_root + '/' + current_time_name + '/' + backup_subdir;
string cmd;
cmd = "mkdir -p \"" + backup_path + "\"";
if (system(cmd.c_str())<0) {
perror("mkdir");
logger << "SYSTEM ERROR: Making backup path " << backup_path << endl;
error_catcher();
exit(-1);
}
log_filename = backup_path + "/backup_log.txt";
logger_f.open(log_filename.c_str());
if (!logger_f.good()) {
perror("opening log file");
cerr << "SYSTEM ERROR: Failed to open log file " <<
log_filename << endl;
exit(-1);
}
logger_p = &logger_f;
Dir *e = sc->load_hier(backup_root + "/latest/" + backup_subdir + '/' + "db.dat");
Dir *d = sc->scan_hier(myfiles_root);
if (!sc->diff_hier(e, d)) {
logger << "Nothing to do\n";
// XXX MOVE THIS INTO A BAILOUT
if (logger_p) {
logger_f.close();
string cmd = gzip_path + ' ' + log_filename;
system(cmd.c_str());
}
return;
}
sc->run_queues();
d->consolidate_small_files();
//d->print();
d->finish_backup(1);
string new_hier = backup_path + "/db.dat";
sc->save_hier(new_hier.c_str(), d);
restore_script(d, backup_path);
delete d;
delete e;
/*
string rs_latest = backup_root + "/restore_latest.sh";
FILE *out;
out = fopen(rs_latest.c_str(), "w");
fprintf(out, "#!/bin/bash\n");
fprintf(out, "if [ \"$#\" -ne \"1\" ]; then\n");
fprintf(out, " echo \"Usage: restore <restore_path>\"\n");
fprintf(out, " exit\n");
fprintf(out, "fi\n");
fprintf(out, "export BKBASE=\"$(dirname \"$0\")\"\n");
fprintf(out, "MYBASE=\"$1\"\n");
fprintf(out, "\"$BKBASE/%s/restore_recursive.sh\" \"$MYBASE\"\n",
current_time_name.c_str());
fclose(out);
chmod(rs_latest.c_str(), 0777);*/
// XXX MOVE THIS INTO A BAILOUT
if (logger_p) {
logger_f.close();
string cmd = gzip_path + ' ' + log_filename;
system(cmd.c_str());
}
logger << "Finished!\n";
}
void Backup::backup_trees()
{
string upper_backup_path = backup_root + '/' + current_time_name;
string cmd;
cmd = "mkdir -p \"" + upper_backup_path + "\"";
if (system(cmd.c_str())<0) {
perror("mkdir");
logger << "SYSTEM ERROR: Making backup path " << backup_path << endl;
error_catcher();
exit(-1);
}
vector<string>::iterator i;
for (i=trees.begin(); i!=trees.end(); ++i) {
backup_tree(*i);
}
// Point to latest set of backups
string new_dir = current_time_name;
string latest_dir = backup_root + "/latest";
unlink(latest_dir.c_str());
symlink(new_dir.c_str(), latest_dir.c_str());
top_script(upper_backup_path, trees, backup_root);
}