Code:
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <fstream>
#include <ctime>
using namespace std;
//Function EditPathIn
void EditPathIn ()
{
string new_path_in ; //variable
cout << "Type the filepath of where you want back up. Be sure to end it with a / !\n";
cin >> new_path_in ;
ofstream path ;
path.open (".backup_prefs/path_in") ;
path << new_path_in ;
path.close() ;
}
//Function EditPathOut
void EditPathOut ()
{
string new_path_out ; //variable
cout << "Type the filepath of where you want to store your backup. Be sure to end it with a / !\n";
cin >> new_path_out ;
ofstream path ;
path.open (".backup_prefs/path_out") ;
path << new_path_out ;
path.close() ;
}
//Function EditFormat
void EditFormat ()
{
string new_format_short ; //variable
string new_format_full ; //Expanded form
cout << "Enter the letter representing the format you want to use.\n\n";
cout << "t Gzipped tar (.tar.gz), for average compression.\n" ;
cout << "z Zip (.zip), for low compression.\n" ;
cout << "7 7zip (.7z), for high compression.\n" ;
cout << " High compression formats take longer.\n" ;
cin >> new_format_short ;
if ( new_format_short == "t" ) {
new_format_full = "tar" ;
}
if ( new_format_short == "z" ) {
new_format_full = "zip" ;
}
if ( new_format_short == "7" ) {
new_format_full = "7z" ;
}
ofstream format ;
format.open (".backup_prefs/format") ;
format << new_format_full ;
format.close() ;
//Record new format to log
ofstream appendlog ("./.backup_prefs/log", ios::app );
if (appendlog.is_open()) {
appendlog << " to " ;
appendlog << new_format_full ;
appendlog << " at " ;
appendlog.close();
}
}
//Main
int main( int argc, char** argv )
{
time_t now; //Time
struct tm *d; //Time
char li [13]; //Time
vector <string> args( argv, argv+argc ) ;
string arg_input; //For checking -xyz type options
int search_for_option = 0; //WTF are fluxes?
int multiple_formats = 0 ;
string emulated_args = "nothing" ;
char yesno ; //For y/n
string io_select ;
int include_hidden_files = 0 ;
int options_present = 0 ;
string archive_type = "tar" ;
string options_to_terminal ;
string settings_outpath ;
string settings_inpath ;
string line_outpath ;
string line_inpath ;
string line_format ;
string date ; //User entered date
string extension = ".tar.gz" ;
string path_in = "~/" ;
string astrisk ; //Adds an astrisk (all) if called.
string exclude_hidden_files = "-X .*" ; //Excludes all .* (hidden) files
string final_command ;
Start:; //A goto
//Get dd-mm-yyyy
time(&now);
d = localtime(&now);
strftime(li, 15, "%d-%m-%Y", d);
date = li ;
//Find preferences
ifstream log (".backup_prefs/log");
if (log.is_open()) {
cout << "Found preferences directory.\n\n" ;
}
else {
system ( "mkdir ~/.backup_prefs" ) ; //Make directory (assuming that no log = no directory)
ofstream mklog ;
mklog.open (".backup_prefs/log") ;
mklog << "Creating log: " ;
mklog << date ;
mklog << ".\n\n\n" ;
mklog.close() ;
}
//Load preferences
//Path in
ifstream in(".backup_prefs/path_in") ;
while(getline(in,line_inpath))
path_in += line_inpath ;
//Path out
ifstream hi(".backup_prefs/path_out") ;
while(getline(hi,line_outpath))
settings_outpath += line_outpath ;
//Format
ifstream format(".backup_prefs/format") ;
while(getline(format,line_format))
archive_type = line_format ;
if ( emulated_args != "nothing" ) { //If it is an emulated run
arg_input = emulated_args ;
}
if ( argv[1] && emulated_args == "nothing" ) {
arg_input = argv[1]; //Gives string arg_input the contents of argument 1, ONLY IF there is an argument 1.
//Without the if, segfault.
}
//If not normal run ( backup <something else> ), check the <something else>.
if (args.size() > 1) {
//If --help
if ( arg_input == "--help" ) {
cout << "\n"
"Usage: backup [option(s)/function]\n"
"Options are written as -xyz. You can append as many options as you want.\n"
"Functions are written as --name, and exit after running.\n\n"
"Options:\n"
" -i Backs up user-defined location instead of default.\n"
" -h Includes hidden files .\n"
" -o Sends to user-defined location instead of default.\n"
" -z Uses .zip instead of .tar.gz . Is less efficiant, but is supported everywhere.\n"
" -7 Uses .7z instead of .tar.gz . 7zip takes longer, but produces a smaller file.\n"
"\n"
"Functions:\n"
" --emulate Treat the next input as if it was argument 1. Use backup --emulate on launchers.\n"
" --format Change the default archive format.\n"
" --in Edit input location.\n"
" --help Opens this index.\n"
" --out Edit output location.\n"
"\n" ;
ofstream appendlog ("./.backup_prefs/log", ios::app );
if (appendlog.is_open()) {
appendlog << "--help" ;
appendlog << " at " ;
appendlog << date ;
appendlog << ".\n\n" ;
appendlog.close();
}
goto End; //NO NOT GOTO
//THE VELOCIRAPTORS
}
//If --emmulate
if ( arg_input == "--emulate" ) {
//State emulation in log
ofstream appendlog_emulate ("./.backup_prefs/log", ios::app );
if (appendlog_emulate.is_open()) {
appendlog_emulate << "Runing emulation..." ;
appendlog_emulate.close();
}
cout << "backup " ;
cin >> emulated_args ;
options_present = 0 ;
goto Start;
}
//If --format
if ( arg_input == "--format" ) {
//Outputs filepath from ~/.backup_prefs/format
ifstream myfile (".backup_prefs/format");
if (myfile.is_open()) {
while (! myfile.eof() ) {
getline (myfile,line_format);
cout << "\n" ;
cout << line_format ;
}
myfile.close();
cout << " is your default archive format. Do you want to edit it? y/n\n" ;
yesno=cin.get();
cin.ignore(256,'\n');
if ( yesno == 'y' ) { //<-Stopped here.
//Archive format changed from <format> ...
ofstream appendlog_format_old ("./.backup_prefs/log", ios::app );
if (appendlog_format_old.is_open()) {
appendlog_format_old << "Archive format changed from " ;
appendlog_format_old << archive_type ;
appendlog_format_old.close();
}
EditFormat () ; //Launch function
//Record date of change to log
ofstream appendlog_format_date ("./.backup_prefs/log", ios::app );
if (appendlog_format_date.is_open()) {
appendlog_format_date << date ;
appendlog_format_date << ".\n" ;
appendlog_format_date.close();
}
}
}
else {
cout << "Unable to open config file. Making a new one...\n" ;
ofstream appendlog_format_old ("./.backup_prefs/log", ios::app );
if (appendlog_format_old.is_open()) {
appendlog_format_old << "Archive format changed from " ;
appendlog_format_old << archive_type ;
appendlog_format_old.close();
}
EditFormat () ;
//Record date of change to log
ofstream appendlog ("./.backup_prefs/log", ios::app );
if (appendlog.is_open()) {
appendlog << date ;
appendlog << " becuase format preference not found.\n\n" ; //State reason
appendlog.close();
}
}
goto End;
}
//If --in
if ( arg_input == "--in" ) {
//Outputs filepath from ~/.backup_prefs/path_in
ifstream myfile (".backup_prefs/path_in");
if (myfile.is_open()) {
while (! myfile.eof() ) {
getline (myfile,line_inpath);
cout << "\n" ;
cout << line_inpath << endl;
}
myfile.close();
cout << "This is the location that will be archived. Do you want to edit it? y/n\n" ;
yesno=cin.get();
cin.ignore(256,'\n');
if ( yesno == 'y' ) {
EditPathIn () ;
}
}
else {
cout << "You don't have a selected input location. ~/ (user's home) is used as a default, though having a saved preference is recommended.\nDo you want to make a config file? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
if ( yesno == 'y' ) {
cout << "Making a new one...\n" ;
EditPathIn () ;
}
}
goto End;
}
//If --out
if ( arg_input == "--out" ) {
//Outputs filepath from ~/.backup_prefs/path_out
ifstream myfile (".backup_prefs/path_out");
if (myfile.is_open()) {
while (! myfile.eof() ) {
getline (myfile,line_outpath);
cout << "\n" ;
cout << line_outpath << endl;
}
myfile.close();
cout << "This is the location that the backup will be stored. Do you want to edit it? y/n\n" ;
yesno=cin.get();
cin.ignore(256,'\n');
if ( yesno == 'y' ) {
EditPathOut () ;
}
}
else {
cout << "Unable to open config file. Making a new one...\n" ;
EditPathOut () ;
}
goto End;
}
//If --segfault
if (args[ 1 ] == "--segfault" ) {
system ("firefox http://xkcd.com/371/") ;
goto End;
}
//Checks for multiple formats
if ((search_for_option = arg_input.find("t", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("t", search_for_option))) {
multiple_formats = multiple_formats + 1 ; //+1 if tar
}
if ((search_for_option = arg_input.find("z", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("z", search_for_option))) {
multiple_formats = multiple_formats + 1 ; //+1 if zip
}
if ((search_for_option = arg_input.find("7", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("7", search_for_option))) {
multiple_formats = multiple_formats + 1 ; //+1 if 7zip
}
if ( multiple_formats > 1 ) {
cout << "Error. You've selected multiple archive types. Please only pick one.\n" ;
}
else {
//Things that must be initialized first
//Uh...
/* //-c
if ((search_for_option = arg_input.find("c", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("c", search_for_option)) ) {
cout << "Note: Copy does not support excluding hidden files.\n" ;
cout << "Do you want to use copy? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
//If y, set to copy
if ( yesno == 'y' ) {
archive_type = "cp" ;
extension = "" ;
options_present = 1 ;
}
} */
//-i
if ((search_for_option = arg_input.find("i", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("i", search_for_option)) ) {
cout << "Enter the location of the folder you wish to archive. Remember to end with / ! Path: " ;
cin >> path_in ;
cout << "Getting files from " << path_in ;
cout << "\n" ;
options_present = 1 ;
}
//-h
if ((search_for_option = arg_input.find("h", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("h", search_for_option)) ) {
include_hidden_files = 1 ;
options_present = 1 ;
}
//-o
if ((search_for_option = arg_input.find("o", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("o", search_for_option))) {
cout << "Enter the location you wish to put the backup. Remember to end in / ! Note that this does not change the default location of " << settings_outpath ;
cout << "\nLocation:" ;
cin >> settings_outpath ;
options_present = 1 ;
}
//-t
if ((search_for_option = arg_input.find("t", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("t", search_for_option))) {
//Confirmation
cout << "Do you want to use .tar.gz? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
//If y, set to tar
if ( yesno == 'y' ) {
archive_type = "tar" ;
options_present = 1 ;
}
}
//-z
if ((search_for_option = arg_input.find("z", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("z", search_for_option))) {
//Warning
cout << "\nZip format is the least efficiant method of compression. The only advantage of .zip is all modern operating systems have default support. \n" ;
cout << "This is only a concern if you intend to open the archive while on a computer that does not have or allow you to get .tar.gz support. If your issue is not having support for tar.gz preinsalled, see http://www.gzip.org/#exe \n\n" ;
cout << "Do you want to use .zip? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
//If y, set to zip
if ( yesno == 'y' ) {
archive_type = "zip" ;
options_present = 1 ;
}
}
//-7
if ((search_for_option = arg_input.find("7", 0)) && (search_for_option != string::npos) && (search_for_option = arg_input.find("7", search_for_option)) ) {
//Notice
cout << "\nUsing 7zip will take a bit longer, but the end result will be a smaller file.\n" ;
cout << "Do you want to use .7z? y/n " ;
yesno=cin.get();
cin.ignore(256,'\n');
//If y, set to 7zip
if ( yesno == 'y' ) {
archive_type = "7z" ;
options_present = 1 ;
}
}
}
// } No need?
}
//If no args, run, or if options_present = 1, run
if((args.size() <= 1) || (options_present)) {
//Give attributes based on archive format
if ( archive_type == "tar" ) {
options_to_terminal = "-czvf" ;
extension = ".tar.gz" ;
exclude_hidden_files = "-x .*" ;
}
if ( archive_type == "zip" ) {
options_to_terminal = "-r" ;
extension = ".zip" ;
astrisk = "*" ;
}
if ( archive_type == "7z" ) {
options_to_terminal = "a -t7z" ;
extension = ".7z" ;
}
//If include_hidden_files, remove the exclude command
if ( include_hidden_files ) {
exclude_hidden_files = "" ; //-h
}
final_command = archive_type + " " + options_to_terminal + " " + settings_outpath + date + "_backup" + extension + " " + path_in + astrisk + " " + exclude_hidden_files ; //Creates a .tar.gz file called mm-dd_backup .
//To terminal
system (final_command.c_str()) ;
ofstream appendlog ("./.backup_prefs/log", ios::app );
if (appendlog.is_open())
{
appendlog << final_command ;
appendlog << " at " ;
appendlog << date ;
appendlog << ".\n" ;
appendlog.close();
}
else {
cout << "Unable to record to log.\n";
}
}
End:;
}