#include "script.hpp"
#include <map>
#include <pwd.h>
#include <grp.h>
#include "globals.hpp"
#include <stdlib.h>
#include "dir.hpp"
#include "time.hpp"
using namespace std;
void restore_script(Dir *hier, const string& scrpath, int level)
{
vector<Dir *>::iterator j;
vector<DirEnt>::iterator i;
string bkname, fname, path, sfname, x, y;
FILE *out;
sfname = scrpath+"/restore_this.sh";
out = fopen(sfname.c_str(), "w");
if (!out) {
perror("fopen");
logger << "SYSTEM ERROR: Unable to open " << sfname << " for writing\n";
error_catcher();
return;
}
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, "if [ -z \"$BKBASE\" ]; then\n");
fprintf(out, " export BKBASE=\"$(dirname \"$0\")");
for (int i=0; i<level; i++) fprintf(out, "/..");
fprintf(out, "\"\n");
fprintf(out, "fi\n");
fprintf(out, "MYBASE=\"$1\"\n");
fprintf(out, "mkdir -p \"$MYBASE\"\n");
map<string, vector<string> > tarlist;
for (i=hier->files.begin(); i!=hier->files.end(); ++i) {
if (i->invalid) continue;
if (i->bkchunks.size() < 1) {
logger << "INTERNAL ERROR: Script, file " << i->my_full_name() << " has no chunks\n";
i->invalid = 1;
error_catcher();
continue;
}
if (i->bkchunks.size() > 1) {
bkname = i->my_rel_backup_name(0);
fname = i->fname;
fprintf(out, "gunzip < \"$BKBASE/%s\" > \"$MYBASE/%s\"\n", bkname.c_str(), fname.c_str());
for (int k=1; k<i->bkchunks.size(); k++) {
bkname = i->my_rel_backup_name(k);
fprintf(out, "gunzip < \"$BKBASE/%s\" >> \"$MYBASE/%s\"\n", bkname.c_str(), fname.c_str());
}
fprintf(out, "chown ");
struct passwd *pwd = getpwuid(i->st.st_uid);
if (pwd) {
fprintf(out, "%s:", pwd->pw_name);
} else {
fprintf(out, "%d:", i->st.st_uid);
}
struct group *grp = getgrgid(i->st.st_gid);
if (grp) {
fprintf(out, "%s", grp->gr_name);
} else {
fprintf(out, "%d", i->st.st_gid);
}
fprintf(out, " \"$MYBASE/%s\"\n", fname.c_str());
fprintf(out, "chmod %o \"$MYBASE/%s\"\n", i->st.st_mode & 07777, fname.c_str());
fprintf(out, "touch -m -t %s \"$MYBASE/%s\"\n", time_to_touch(&i->st.st_mtime).c_str(), fname.c_str());
fprintf(out, "touch -a -t %s \"$MYBASE/%s\"\n", time_to_touch(&i->st.st_atime).c_str(), fname.c_str());
} else {
bkname = i->my_rel_backup_name(0);
//path = i->parent->my_rel_full_name();
fname = i->fname;
x = "tar axpSUf \"$BKBASE/" + bkname + "\" -C \"$MYBASE/\" --same-owner ";
y = fname;
tarlist[x].push_back(y);
}
// fprintf(out, "tar axpSUf \"$BKBASE/%s\" -C \"$MYBASE/%s\" --same-owner \"%s\"\n",
// bkname.c_str(), path.c_str(), fname.c_str());
}
for (j=hier->dirs.begin(); j!=hier->dirs.end(); ++j) {
if ((*j)->self.invalid) continue;
if ((*j)->self.bkchunks.size() != 1) {
logger << "INTERNAL ERROR: Script, directory " << i->my_full_name() << " wrong number of chunks\n";
error_catcher();
exit(-1);
}
bkname = (*j)->my_rel_backup_name();
//path = (*j)->self.parent->my_rel_full_name();
fname = (*j)->self.fname;
x = "tar axpSUf \"$BKBASE/" + bkname + "\" -C \"$MYBASE/\" --same-owner ";
y = fname;
tarlist[x].push_back(y);
// fprintf(out, "tar axpSUf \"$BKBASE/%s\" -C \"$MYBASE/%s\" --same-owner \"%s\"\n",
// bkname.c_str(), path.c_str(), fname.c_str());
}
map<string, vector<string> >::iterator k;
vector<string>::iterator l;
for (k=tarlist.begin(); k!=tarlist.end(); ++k) {
fprintf(out, "%s", k->first.c_str());
for (l=k->second.begin(); l!=k->second.end(); l++) {
fprintf(out, "\"%s\" ", l->c_str());
}
fprintf(out, "\n");
}
fclose(out);
chmod(sfname.c_str(), 0777);
sfname = scrpath+"/restore_recursive.sh";
out = fopen(sfname.c_str(), "w");
if (!out) {
perror("fopen");
logger << "SYSTEM ERROR: Unable to open " << sfname << " for writing\n";
error_catcher();
return;
}
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, "if [ -z \"$BKBASE\" ]; then\n");
fprintf(out, " export BKBASE=\"$(dirname \"$0\")");
for (int i=0; i<level; i++) fprintf(out, "/..");
fprintf(out, "\"\n");
fprintf(out, "fi\n");
fprintf(out, "MYBASE=\"$1\"\n");
fprintf(out, "mkdir -p \"$MYBASE\"\n");
fprintf(out, "\"$BKBASE/%s/restore_this.sh\" \"$MYBASE\"\n",
hier->my_rel_backup_path().c_str());
for (j=hier->dirs.begin(); j!=hier->dirs.end(); ++j) {
if ((*j)->self.invalid) continue;
fname = (*j)->my_rel_backup_path();
fprintf(out, "\"$BKBASE/%s/restore_recursive.sh\" ", fname.c_str());
fname = (*j)->self.fname;
fprintf(out, "\"$MYBASE/%s\"\n", fname.c_str());
}
fclose(out);
chmod(sfname.c_str(), 0777);
for (j=hier->dirs.begin(); j!=hier->dirs.end(); ++j) {
if ((*j)->self.invalid) continue;
if ((*j)->self.bkchunks.size() != 1) {
logger << "INTERNAL ERROR: Script, directory " << i->my_full_name() << " wrong number of chunks\n";
error_catcher();
exit(-1);
}
if ((*j)->self.bkchunks[0].bkdate < current_time) continue;
bkname = (*j)->my_rel_backup_name();
path = (*j)->self.parent->my_rel_full_name();
fname = (*j)->self.fname;
restore_script(*j, scrpath+"/_"+fname, level+1);
}
}
void top_script(const string& upper_backup_path, const vector<string>& trees,
const string& backup_root)
{
vector<string>::const_iterator i;
FILE *out;
string sfname;
sfname = upper_backup_path+"/restore_recursive.sh";
out = fopen(sfname.c_str(), "w");
if (!out) {
perror("fopen");
logger << "SYSTEM ERROR: Unable to open " << sfname << " for writing\n";
error_catcher();
return;
}
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, "if [ -z \"$BKBASE\" ]; then\n");
fprintf(out, " export BKBASE=\"$(dirname \"$0\")");
for (int i=0; i<1; i++) fprintf(out, "/..");
fprintf(out, "\"\n");
fprintf(out, "fi\n");
fprintf(out, "MYBASE=\"$1\"\n");
fprintf(out, "mkdir -p \"$MYBASE\"\n");
for (i=trees.begin(); i!=trees.end(); ++i) {
/* if (*i == "/") {
fprintf(out, "\"$BKBASE/root/restore_recursive.sh\" \"$MYBASE\"", backup_subdir.c_str());
} else {
backup_subdir = last_dir_name(*i);
fprintf(out, "\"$BKBASE/_%s/restore_recursive.sh\" ", backup_subdir.c_str());
fprintf(out, "\"$MYBASE/%s\"\n", backup_subdir.c_str());
}*/
string backup_subdir = scrub_pathname(*i);
string real_subdir = last_dir_name(*i);
fprintf(out, "\"$BKBASE/%s/%s/restore_recursive.sh\" ",
current_time_name.c_str(),
backup_subdir.c_str());
fprintf(out, "\"$MYBASE/%s\"\n", real_subdir.c_str());
}
chmod(sfname.c_str(), 0777);
fclose(out);
string rs_latest = backup_root + "/restore_latest.sh";
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);
}