mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
265 lines
6.5 KiB
C++
265 lines
6.5 KiB
C++
#include "LogReport.h"
|
|
#include "../Interface/Server.h"
|
|
#include "../Interface/Mutex.h"
|
|
#include "../Interface/Database.h"
|
|
#include "../stringtools.h"
|
|
#include "database.h"
|
|
#include "../luaplugin/ILuaInterpreter.h"
|
|
#include "../urlplugin/IUrlFactory.h"
|
|
#include "Mailer.h"
|
|
#include "server_status.h"
|
|
#include "ClientMain.h"
|
|
#include "dao/ServerBackupDao.h"
|
|
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
|
#include "../common/miniz.h"
|
|
|
|
extern ILuaInterpreter* lua_interpreter;
|
|
extern IUrlFactory *url_fak;
|
|
|
|
namespace
|
|
{
|
|
IMutex* mutex;
|
|
std::string script;
|
|
|
|
class MailBridge : public ILuaInterpreter::IEMailFunction
|
|
{
|
|
public:
|
|
// Inherited via IEMailFunction
|
|
virtual bool mail(const std::string & send_to, const std::string & subject, const std::string & message)
|
|
{
|
|
return Mailer::sendMail(send_to, subject, message);
|
|
}
|
|
};
|
|
|
|
class UrlBridge : public ILuaInterpreter::IUrlFunction
|
|
{
|
|
public:
|
|
// Inherited via IUrlFunction
|
|
virtual bool requestUrl(const std::string & url, str_map & params, std::string & ret, long & http_code, std::string * errmsg = NULL)
|
|
{
|
|
return url_fak->requestUrl(url, params, ret, http_code, errmsg);
|
|
}
|
|
};
|
|
|
|
ILuaInterpreter::SInterpreterFunctions funcs;
|
|
|
|
IMutex* global_mutex;
|
|
std::string global_data_mem;
|
|
bool has_global_data = false;
|
|
bool has_global_data_misc = false;
|
|
std::string global_data;
|
|
|
|
#include "report_lua.h"
|
|
|
|
std::string get_report_lua()
|
|
{
|
|
size_t out_len;
|
|
void* cdata = tinfl_decompress_mem_to_heap(report_lua_z, report_lua_z_len, &out_len, TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32);
|
|
if (cdata == NULL)
|
|
{
|
|
return std::string();
|
|
}
|
|
|
|
std::string ret(reinterpret_cast<char*>(cdata), reinterpret_cast<char*>(cdata) + out_len);
|
|
mz_free(cdata);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
std::string load_report_script()
|
|
{
|
|
if (FileExists("urbackupserver/report.lua"))
|
|
{
|
|
std::string ret = getFile("urbackupserver/report.lua");
|
|
if (!ret.empty())
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
IDatabase* db = Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
|
|
|
|
db_results res = db->Read("SELECT tvalue FROM misc WHERE tkey='report_script'");
|
|
|
|
if (!res.empty())
|
|
{
|
|
has_global_data_misc = true;
|
|
return res[0]["tvalue"];
|
|
}
|
|
|
|
return get_report_lua();
|
|
}
|
|
|
|
void load_global_data()
|
|
{
|
|
if (has_global_data)
|
|
return;
|
|
|
|
IDatabase* db = Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
|
|
db_results res = db->Read("SELECT tvalue FROM misc WHERE tkey='report_script_global_state'");
|
|
|
|
has_global_data = true;
|
|
|
|
if (!res.empty())
|
|
{
|
|
global_data = res[0]["tvalue"];
|
|
}
|
|
}
|
|
|
|
void update_global_data(const std::string& new_global_data)
|
|
{
|
|
IDatabase* db = Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
|
|
|
|
if (has_global_data_misc)
|
|
{
|
|
IQuery* q_update = db->Prepare("UPDATE misc SET tvalue=? WHERE tkey='report_script_global_state'", false);
|
|
q_update->Bind(new_global_data.c_str(), new_global_data.size());
|
|
q_update->Write();
|
|
q_update->Reset();
|
|
db->destroyQuery(q_update);
|
|
}
|
|
else
|
|
{
|
|
IQuery* q_insert = db->Prepare("INSERT INTO misc (tkey, tvalue) VALUES ('report_script_global_state', ?)", false);
|
|
q_insert->Bind(new_global_data.c_str(), new_global_data.size());
|
|
q_insert->Write();
|
|
q_insert->Reset();
|
|
db->destroyQuery(q_insert);
|
|
}
|
|
|
|
global_data = new_global_data;
|
|
}
|
|
|
|
std::string get_report_script()
|
|
{
|
|
IScopedLock lock(mutex);
|
|
if (!script.empty())
|
|
{
|
|
return script;
|
|
}
|
|
|
|
script = load_report_script();
|
|
if (script.empty())
|
|
return script;
|
|
|
|
if (script.find("--disable_lua_compile") != std::string::npos)
|
|
return script;
|
|
|
|
std::string compiled_script = lua_interpreter->compileScript(script);
|
|
|
|
if (!compiled_script.empty())
|
|
{
|
|
script = compiled_script;
|
|
return compiled_script;
|
|
}
|
|
|
|
return script;
|
|
}
|
|
|
|
void init_log_report()
|
|
{
|
|
mutex = Server->createMutex();
|
|
funcs.mail_func = new MailBridge;
|
|
funcs.url_func = new UrlBridge;
|
|
global_mutex = Server->createMutex();
|
|
}
|
|
|
|
void reload_report_script()
|
|
{
|
|
IScopedLock lock(mutex);
|
|
script.clear();
|
|
}
|
|
|
|
bool run_report_script(int incremental, bool resumed, int image,
|
|
int infos, int warnings, int errors, bool success, const std::string& report_mail,
|
|
const std::string & data, const std::string& clientname, int clientid, IDatabase* db)
|
|
{
|
|
if (lua_interpreter == NULL)
|
|
return false;
|
|
|
|
std::string script;
|
|
{
|
|
IScopedLock lock(mutex);
|
|
script = get_report_script();
|
|
}
|
|
|
|
if (script.empty())
|
|
return false;
|
|
|
|
ILuaInterpreter::Param param_raw;
|
|
ILuaInterpreter::Param::params_map& param = *param_raw.u.params;
|
|
|
|
param["incremental"] = incremental;
|
|
param["resumed"] = resumed;
|
|
param["image"] = image;
|
|
param["infos"] = infos;
|
|
param["warnings"] = warnings;
|
|
param["errors"] = errors;
|
|
param["report_mail"] = report_mail;
|
|
param["clientname"] = clientname;
|
|
param["success"] = success;
|
|
param["clientip"] = ClientMain::getClientIpStr(clientname);
|
|
SStatus status = ServerStatus::getStatus(clientname);
|
|
param["clientos"] = status.os_version_string;
|
|
param["clientversion"] = status.client_version_string;
|
|
param["clientid"] = clientid;
|
|
|
|
if (clientid != 0 && db!=NULL)
|
|
{
|
|
ServerBackupDao backup_dao(db);
|
|
ServerBackupDao::CondInt groupid = backup_dao.getClientGroup(clientid);
|
|
if (groupid.exists)
|
|
{
|
|
param["groupid"] = groupid.value;
|
|
|
|
if (groupid.value != 0)
|
|
{
|
|
param["groupname"] = backup_dao.getGroupName(groupid.value).value;
|
|
}
|
|
}
|
|
}
|
|
|
|
ILuaInterpreter::Param::params_map& pdata = *param["data"].u.params;
|
|
|
|
std::vector<std::string> msgs;
|
|
Tokenize(data, msgs, "\n");
|
|
|
|
for (size_t j = 0; j<msgs.size(); ++j)
|
|
{
|
|
ILuaInterpreter::Param::params_map& obj = *pdata[static_cast<int>(j + 1)].u.params;
|
|
std::string ll;
|
|
if (!msgs[j].empty()) ll = msgs[j][0];
|
|
int li = watoi(ll);
|
|
msgs[j].erase(0, 2);
|
|
std::string tt = getuntil("-", msgs[j]);
|
|
std::string m = getafter("-", msgs[j]);
|
|
obj["time"] = watoi64(tt);
|
|
obj["msg"] = m;
|
|
obj["ll"] = li;
|
|
}
|
|
|
|
int64 ret2;
|
|
std::string state;
|
|
std::string state_mem;
|
|
int64 ret;
|
|
{
|
|
IScopedLock lock(global_mutex);
|
|
load_global_data();
|
|
std::string local_global_data = global_data;
|
|
ret = lua_interpreter->runScript(script, param_raw, ret2, state, state_mem, local_global_data, global_data_mem, funcs);
|
|
if (local_global_data != global_data)
|
|
{
|
|
update_global_data(local_global_data);
|
|
}
|
|
}
|
|
|
|
if (ret<0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|