/*************************************************************************
* UrBackup - Client/Server backup system
* Copyright (C) 2011-2017 Martin Raiber
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
**************************************************************************/
#include "../tclap/CmdLine.h"
#include
#include "../stringtools.h"
#include
#ifndef _WIN32
#include "config.h"
#include "../Server.h"
#include "../Interface/SettingsReader.h"
#include
#else
#define PACKAGE_VERSION "unknown"
#define VARDIR ""
#define SYSCONFDIR ""
#define DATADIR ""
#endif
const std::string cmdline_version = PACKAGE_VERSION;
void show_version()
{
std::cout << "UrBackup Client Backend v" << cmdline_version << std::endl;
std::cout << "Copyright (C) 2011-2018 Martin Raiber" << std::endl;
std::cout << "This is free software; see the source for copying conditions. There is NO"<< std::endl;
std::cout << "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."<< std::endl;
}
int real_main(int argc, char* argv[])
#ifndef _WIN32
;
#else
{return 1;}
#endif
int run_real_main(std::vector args)
{
char** argv = new char*[args.size()];
for(size_t i=0;i(args[i].c_str());
}
int rc = real_main(static_cast(args.size()), argv);
delete[] argv;
return rc;
}
std::string unquote_value(std::string val)
{
val = trim(val);
if(val[0]=='"')
{
size_t last_pos = val.find_last_of('"');
if(last_pos!=0)
{
val=val.substr(1, last_pos-1);
}
}
else if(val[0]=='\'')
{
size_t last_pos = val.find_last_of('\'');
if(last_pos!=0)
{
val=val.substr(1, last_pos-1);
}
}
return val;
}
#ifndef _WIN32
void read_config_file(std::string fn, std::vector& real_args)
{
if (!FileExists(fn))
{
std::cout << "Config file at " << fn << " does not exist. Ignoring." << std::endl;
return;
}
bool destroy_server=false;
if(Server==NULL)
{
Server = new CServer;
destroy_server=true;
}
{
std::auto_ptr settings(Server->createFileSettingsReader(fn));
std::string val;
if(settings->getValue("LOGFILE", &val))
{
val = unquote_value(val);
if(!val.empty())
{
if(val[0]!='/')
{
val = "/var/log/"+val;
}
real_args.push_back("--logfile");
real_args.push_back(val);
}
}
if(settings->getValue("LOGLEVEL", &val))
{
val = trim(unquote_value(val));
if(!val.empty())
{
real_args.push_back("--loglevel");
real_args.push_back(val);
}
}
if(settings->getValue("DAEMON_TMPDIR", &val))
{
std::string tmpdir = unquote_value(val);
if(!tmpdir.empty())
{
if(setenv("TMPDIR", tmpdir.c_str(), 1)!=0)
{
std::cout << "Error setting TMPDIR" << std::endl;
exit(1);
}
}
}
if(settings->getValue("RESTORE", &val))
{
val = trim(unquote_value(val));
if(!val.empty())
{
real_args.push_back("--allow_restore");
real_args.push_back(strlower(val));
}
}
if (settings->getValue("INTERNET_ONLY", &val))
{
val = trim(unquote_value(val));
if (!val.empty())
{
real_args.push_back("--internet_only_mode");
real_args.push_back(strlower(val));
}
}
if (settings->getValue("LOG_ROTATE_FILESIZE", &val))
{
val = trim(unquote_value(val));
if (!val.empty())
{
real_args.push_back("--rotate-filesize");
real_args.push_back(strlower(val));
}
}
if (settings->getValue("LOG_ROTATE_NUM", &val))
{
val = trim(unquote_value(val));
if (!val.empty())
{
real_args.push_back("--rotate-numfiles");
real_args.push_back(strlower(val));
}
}
}
if(destroy_server)
{
delete Server;
}
}
#endif
#ifndef RESTORE_CLIENT
int main(int argc, char* argv[])
{
if(argc==0)
{
std::cout << "Not enough arguments (zero arguments) -- no program name" << std::endl;
return 1;
}
for(size_t i=1;i logfile_arg("l", "logfile",
"Specifies the log file name",
false, "/var/log/urbackupclient.log", "path", cmd);
std::vector loglevels;
loglevels.push_back("debug");
loglevels.push_back("info");
loglevels.push_back("warn");
loglevels.push_back("error");
TCLAP::ValuesConstraint loglevels_constraint(loglevels);
TCLAP::ValueArg loglevel_arg("v", "loglevel",
"Specifies the log level",
false, "info", &loglevels_constraint, cmd);
TCLAP::SwitchArg daemon_arg("d", "daemon", "Daemonize process", cmd, false);
TCLAP::SwitchArg internet_only_arg("i", "internet-only", "Only connect to backup servers via internet", cmd, false);
TCLAP::ValueArg pidfile_arg("w", "pidfile",
"Save pid of daemon in file",
false, "/var/run/urbackup_srv.pid", "path", cmd);
TCLAP::SwitchArg no_console_time_arg("t", "no-consoletime",
"Do not print time when logging to console",
cmd, false);
#if defined(__APPLE__)
int default_rotate_filesize = 20971520;
int default_rotate_numfiles = 10;
#else
int default_rotate_filesize = 0;
int default_rotate_numfiles = 0;
#endif
TCLAP::ValueArg rotate_filesize_arg("g", "rotate-filesize",
"Maximum size of log file before rotation",
false, default_rotate_filesize, "bytes", cmd);
TCLAP::ValueArg rotate_num_files_arg("j", "rotate-num-files",
"Max number of log files during rotation",
false, default_rotate_numfiles, "num", cmd);
#ifndef _WIN32
TCLAP::ValueArg config_arg("c", "config",
"Read configuration parameters from config file",
false, "", "path", cmd);
#endif
std::vector restore_arg_vals;
restore_arg_vals.push_back("client-confirms");
restore_arg_vals.push_back("server-confirms");
restore_arg_vals.push_back("disabled");
TCLAP::ValuesConstraint restore_arg_constraint(restore_arg_vals);
TCLAP::ValueArg restore_arg("r", "restore",
"Specifies if restores are allowed and where they have to be confirmed",
false, "client-confirms", &restore_arg_constraint, cmd);
std::vector real_args;
real_args.push_back(argv[0]);
cmd.parse(argc, argv);
#ifndef _WIN32
if(!config_arg.getValue().empty())
{
read_config_file(config_arg.getValue(), real_args);
}
#endif
real_args.push_back("--no-server");
real_args.push_back("--workingdir");
real_args.push_back(VARDIR);
real_args.push_back("--script_path");
real_args.push_back( DATADIR "/urbackup/scripts:" SYSCONFDIR "/urbackup/scripts");
real_args.push_back("--pidfile");
real_args.push_back(pidfile_arg.getValue());
if(std::find(real_args.begin(), real_args.end(), "--logfile")==real_args.end())
{
real_args.push_back("--logfile");
real_args.push_back(logfile_arg.getValue());
}
if(std::find(real_args.begin(), real_args.end(), "--loglevel")==real_args.end())
{
real_args.push_back("--loglevel");
real_args.push_back(loglevel_arg.getValue());
}
if(daemon_arg.getValue())
{
real_args.push_back("--daemon");
}
if(no_console_time_arg.getValue())
{
real_args.push_back("--log_console_no_time");
}
if(std::find(real_args.begin(), real_args.end(), "--internet_only_mode") == real_args.end()
&& internet_only_arg.getValue())
{
real_args.push_back("--internet_only_mode");
real_args.push_back("true");
}
if(std::find(real_args.begin(), real_args.end(), "--allow_restore")==real_args.end())
{
real_args.push_back("--allow_restore");
real_args.push_back(restore_arg.getValue());
}
if (rotate_filesize_arg.getValue() > 0
&& std::find(real_args.begin(), real_args.end(), "--rotate-filesize") == real_args.end())
{
real_args.push_back("--rotate-filesize");
real_args.push_back(convert(rotate_filesize_arg.getValue()));
}
if(rotate_num_files_arg.getValue() > 0
&& std::find(real_args.begin(), real_args.end(), "--rotate-numfiles") == real_args.end())
{
real_args.push_back("--rotate-numfiles");
real_args.push_back(convert(rotate_num_files_arg.getValue()));
}
return run_real_main(real_args);
}
catch (TCLAP::ArgException &e)
{
std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
return 1;
}
}
#endif
#ifdef RESTORE_CLIENT
int main(int argc, char* argv[])
{
if (argc == 0)
{
std::cout << "Not enough arguments (zero arguments) -- no program name" << std::endl;
return 1;
}
for (size_t i = 1; i logfile_arg("l", "logfile",
"Specifies the log file name",
false, "/var/log/urbackup.log", "path", cmd);
std::vector loglevels;
loglevels.push_back("debug");
loglevels.push_back("info");
loglevels.push_back("warn");
loglevels.push_back("error");
TCLAP::ValuesConstraint loglevels_constraint(loglevels);
TCLAP::ValueArg loglevel_arg("v", "loglevel",
"Specifies the log level",
false, "info", &loglevels_constraint, cmd);
TCLAP::SwitchArg daemon_arg("d", "daemon", "Daemonize process", cmd, false);
TCLAP::SwitchArg internet_only_arg("i", "internet-only", "Only connect to backup servers via internet", cmd, false);
TCLAP::ValueArg pidfile_arg("w", "pidfile",
"Save pid of daemon in file",
false, "/var/run/urbackup_srv.pid", "path", cmd);
TCLAP::SwitchArg no_console_time_arg("t", "no-consoletime",
"Do not print time when logging to console",
cmd, false);
TCLAP::ValueArg config_arg("c", "config",
"Read configuration parameters from config file",
false, "", "path", cmd);
TCLAP::ValueArg restore_mbr_arg("m", "restore-mbr",
"MBR file to restore to out_device",
false, "", "path");
TCLAP::ValueArg mbr_info_arg("j", "mbr-info",
"Show contents of .mbr file",
false, "", "path");
TCLAP::ValueArg out_device_arg("o", "out-device",
"Device file to restore to",
false, "", "path", cmd);
TCLAP::ValueArg restore_image_arg("r", "restore-image",
"Image file to restore to out_device",
false, "", "path");
TCLAP::SwitchArg restore_wizard_arg("e", "restore-wizard", "Start restore wizard");
TCLAP::SwitchArg restore_client_arg("n", "restore-client", "Start restore client");
TCLAP::ValueArg ping_server_arg("p", "ping-server",
"Ping server to notify it of client",
false, "", "IP/hostname");
TCLAP::SwitchArg image_download_progress_arg("q", "image-download-progress",
"Return image download progress for piping to dialog");
std::vector xorArgs;
xorArgs.push_back(&restore_mbr_arg);
xorArgs.push_back(&mbr_info_arg);
xorArgs.push_back(&restore_image_arg);
xorArgs.push_back(&restore_wizard_arg);
xorArgs.push_back(&restore_client_arg);
xorArgs.push_back(&ping_server_arg);
xorArgs.push_back(&image_download_progress_arg);
cmd.xorAdd(xorArgs);
cmd.parse(argc, argv);
std::vector real_args;
real_args.push_back(argv[0]);
if (!config_arg.getValue().empty())
{
read_config_file(config_arg.getValue(), real_args);
}
real_args.push_back("--pidfile");
real_args.push_back(pidfile_arg.getValue());
if (std::find(real_args.begin(), real_args.end(), "--logfile") == real_args.end())
{
real_args.push_back("--logfile");
real_args.push_back(logfile_arg.getValue());
}
if (std::find(real_args.begin(), real_args.end(), "--loglevel") == real_args.end())
{
real_args.push_back("--loglevel");
real_args.push_back(loglevel_arg.getValue());
}
if (daemon_arg.getValue())
{
real_args.push_back("--daemon");
}
if (no_console_time_arg.getValue())
{
real_args.push_back("--log_console_no_time");
}
if (internet_only_arg.getValue())
{
real_args.push_back("--internet_only_mode");
real_args.push_back("true");
}
real_args.push_back("--allow_restore");
real_args.push_back("server-confirms");
if (restore_mbr_arg.isSet())
{
if (!out_device_arg.isSet())
{
std::cout << "You need to specify a device to which restore the MBR via --out-device" << std::endl;
return 1;
}
real_args.push_back("--no-server");
real_args.push_back("--restore");
real_args.push_back("true");
real_args.push_back("--restore_cmd");
real_args.push_back("write_mbr");
real_args.push_back("--mbr_filename");
real_args.push_back(restore_mbr_arg.getValue());
real_args.push_back("--out_device");
real_args.push_back(out_device_arg.getValue());
}
else if (mbr_info_arg.isSet())
{
real_args.push_back("--no-server");
real_args.push_back("--restore");
real_args.push_back("true");
real_args.push_back("--restore_cmd");
real_args.push_back("mbrinfo");
real_args.push_back("--mbr_filename");
real_args.push_back(mbr_info_arg.getValue());
}
else if (restore_image_arg.isSet())
{
real_args.push_back("--no-server");
real_args.push_back("--vhdcopy_in");
real_args.push_back(restore_image_arg.getValue());
real_args.push_back("--vhdcopy_out");
real_args.push_back(out_device_arg.getValue());
}
else if (restore_wizard_arg.isSet())
{
real_args.push_back("--no-server");
real_args.push_back("--restore_wizard");
real_args.push_back("true");
}
else if (restore_client_arg.isSet())
{
real_args.push_back("--no-server");
real_args.push_back("--restore_mode");
real_args.push_back("true");
}
else if (ping_server_arg.isSet())
{
real_args.push_back("--no-server");
real_args.push_back("--restore");
real_args.push_back("true");
real_args.push_back("--restore_cmd");
real_args.push_back("ping_server");
real_args.push_back("--ping_server");
real_args.push_back(ping_server_arg.getValue());
}
else if (image_download_progress_arg.isSet())
{
real_args.push_back("--no-server");
real_args.push_back("--restore");
real_args.push_back("true");
real_args.push_back("--restore_cmd");
real_args.push_back("download_progress");
}
return run_real_main(real_args);
}
catch (TCLAP::ArgException &e)
{
std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
return 1;
}
}
#endif