mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
Added mailed reports of backups
This commit is contained in:
parent
1c4d45eb8a
commit
6ab15ebd4c
@ -51,6 +51,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "downloadplugin", "downloadp
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jswiki", "jswiki\jswiki.vcxproj", "{81EE2F6D-6A48-423B-8BBB-B97DB74EDD0F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "urlplugin", "urlplugin\urlplugin.vcxproj", "{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug WinXP|Win32 = Debug WinXP|Win32
|
||||
@ -364,6 +366,18 @@ Global
|
||||
{81EE2F6D-6A48-423B-8BBB-B97DB74EDD0F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{81EE2F6D-6A48-423B-8BBB-B97DB74EDD0F}.Release|Win32.Build.0 = Release|Win32
|
||||
{81EE2F6D-6A48-423B-8BBB-B97DB74EDD0F}.Release|x64.ActiveCfg = Release|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Debug WinXP|Win32.ActiveCfg = Debug|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Debug WinXP|Win32.Build.0 = Debug|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Debug WinXP|x64.ActiveCfg = Debug|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Debug XP|Win32.ActiveCfg = Debug|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Debug XP|Win32.Build.0 = Debug|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Debug XP|x64.ActiveCfg = Debug|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Release|Win32.Build.0 = Release|Win32
|
||||
{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}.Release|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@ -8,7 +8,7 @@ AM_CXXFLAGS = $(PTHREAD_CFLAGS) -DLINUX
|
||||
AM_CFLAGS = -DSQLITE_ENABLE_UNLOCK_NOTIFY
|
||||
AM_LDFLAGS = $(PTHREAD_LIBS) -ldl
|
||||
#$(BOOST_LDFLAGS) $(BOOST_THREAD_LIB)
|
||||
SUBDIRS=. pychart downloadplugin fsimageplugin httpserver urbackup
|
||||
SUBDIRS=. pychart urlplugin downloadplugin fsimageplugin httpserver urbackup
|
||||
install-exec-local: $(srcdir)/defaults $(srcdir)/init.d
|
||||
$(INSTALL) -D $(srcdir)/init.d $(sysconfdir)/init.d/urbackup_srv
|
||||
if ! test -e $(sysconfdir)/default/urbackup_srv; then $(INSTALL) -D $(srcdir)/defaults $(sysconfdir)/default/urbackup_srv; fi
|
||||
|
||||
@ -50,6 +50,6 @@ AC_FUNC_SELECT_ARGTYPES
|
||||
AC_FUNC_STRFTIME
|
||||
AC_CHECK_FUNCS([gettimeofday memset select socket strstr])
|
||||
|
||||
AC_CONFIG_SUBDIRS([pychart downloadplugin fsimageplugin httpserver urbackup])
|
||||
AC_CONFIG_SUBDIRS([pychart urlplugin downloadplugin fsimageplugin httpserver urbackup])
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
@ -13,5 +13,5 @@ install-data-local: $(srcdir)/backup_server.db $(srcdir)/status.htm $(srcdir)/ww
|
||||
$(INSTALL_DATA) $(INSTALL_OPTS) $(srcdir)/www/*.css $(DESTDIR)$(localstatedir)/urbackup/www/
|
||||
$(INSTALL_DATA) $(INSTALL_OPTS) $(srcdir)/www/*.png $(DESTDIR)$(localstatedir)/urbackup/www/
|
||||
$(INSTALL_DATA) $(INSTALL_OPTS) $(srcdir)/www/*.gif $(DESTDIR)$(localstatedir)/urbackup/www/
|
||||
noinst_HEADERS = server_ping.h server_cleanup.h DirectoryWatcherThread.h os_functions.h serverinterface/json.h serverinterface/helper.h serverinterface/action_header.h serverinterface/actions.h server_writer.h settings.h server_image.h server_settings.h ChangeJournalWatcher.h zero_hash.h server_update.h server_log.h server_hash.h server_status.h bufmgr.h watchdir/DelayedDirectoryChangeHandler.h watchdir/Event.h watchdir/CriticalSection.h watchdir/DirectoryChanges.h server_update_stats.h sha2/sha2.h fileclient/FileClient.h fileclient/data.h fileclient/socket_header.h fileclient/tcpstack.h fileclient/packet_ids.h ServerIdentityMgr.h database.h mbr_code.h action_header.h escape.h server.h server_running.h ClientSend.h clientdao.h server_prepare_hash.h actions.h server_channel.h server_get.h client.h ClientService.h treediff/TreeDiff.h treediff/TreeNode.h treediff/TreeReader.h ../pychart/IPychart.h ../pychart/IPychartFactory.h ../fileservplugin/IFileServFactory.h ../fileservplugin/IFileServ.h
|
||||
noinst_HEADERS = server_ping.h server_cleanup.h DirectoryWatcherThread.h os_functions.h serverinterface/json.h serverinterface/helper.h serverinterface/action_header.h serverinterface/actions.h server_writer.h settings.h server_image.h server_settings.h ChangeJournalWatcher.h zero_hash.h server_update.h server_log.h server_hash.h server_status.h bufmgr.h watchdir/DelayedDirectoryChangeHandler.h watchdir/Event.h watchdir/CriticalSection.h watchdir/DirectoryChanges.h server_update_stats.h sha2/sha2.h fileclient/FileClient.h fileclient/data.h fileclient/socket_header.h fileclient/tcpstack.h fileclient/packet_ids.h ServerIdentityMgr.h database.h mbr_code.h action_header.h escape.h server.h server_running.h ClientSend.h clientdao.h server_prepare_hash.h actions.h server_channel.h server_get.h client.h ClientService.h treediff/TreeDiff.h treediff/TreeNode.h treediff/TreeReader.h ../pychart/IPychart.h ../pychart/IPychartFactory.h ../fileservplugin/IFileServFactory.h ../fileservplugin/IFileServ.h ../urlplugin/IUrlFactory.h
|
||||
EXTRA_DIST = backup_server.db status.htm google_chart.js www/*.js www/*.htm www/*.css www/*.png www/*.gif www/*.ico
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "../pychart/IPychartFactory.h"
|
||||
#include "../downloadplugin/IDownloadFactory.h"
|
||||
#include "../cryptoplugin/ICryptoFactory.h"
|
||||
#include "../urlplugin/IUrlFactory.h"
|
||||
|
||||
IServer *Server;
|
||||
|
||||
@ -67,6 +68,7 @@ IFSImageFactory *image_fak;
|
||||
IPychartFactory *pychart_fak;
|
||||
IDownloadFactory *download_fak;
|
||||
ICryptoFactory *crypto_fak;
|
||||
IUrlFactory *url_fak=NULL;
|
||||
std::string server_identity;
|
||||
std::string server_token;
|
||||
|
||||
@ -371,7 +373,11 @@ DLLEXPORT void LoadActions(IServer* pServer)
|
||||
{
|
||||
Server->Log("Error loading IDownloadFactory", LL_ERROR);
|
||||
}
|
||||
|
||||
url_fak=(IUrlFactory*)Server->getPlugin(Server->getThreadID(), Server->StartPlugin("url", params));
|
||||
if(url_fak==NULL)
|
||||
{
|
||||
Server->Log("Error loading IUrlFactory", LL_ERROR);
|
||||
}
|
||||
|
||||
server_exit_pipe=Server->createMemoryPipe();
|
||||
BackupServer *backup_server=new BackupServer(server_exit_pipe);
|
||||
@ -584,6 +590,14 @@ void upgrade8_9(void)
|
||||
db->Write("CREATE TABLE assoc_images ( img_id INTEGER REFERENCES backup_images(id) ON DELETE CASCADE, assoc_id INTEGER REFERENCES backup_images(id) ON DELETE CASCADE)");
|
||||
}
|
||||
|
||||
void upgrade9_10(void)
|
||||
{
|
||||
IDatabase *db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
|
||||
db->Write("ALTER TABLE si_users ADD report_mail TEXT");
|
||||
db->Write("ALTER TABLE si_users ADD report_loglevel INTEGER");
|
||||
db->Write("ALTER TABLE si_users ADD report_sendonly INTEGER");
|
||||
}
|
||||
|
||||
void upgrade(void)
|
||||
{
|
||||
IDatabase *db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
|
||||
@ -639,6 +653,10 @@ void upgrade(void)
|
||||
upgrade8_9();
|
||||
++ver;
|
||||
break;
|
||||
case 9:
|
||||
upgrade9_10();
|
||||
++ver;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -33,16 +33,19 @@
|
||||
#include "server_log.h"
|
||||
#include "server_writer.h"
|
||||
#include "server_cleanup.h"
|
||||
#include "server_update_stats.h"
|
||||
#include "escape.h"
|
||||
#include "mbr_code.h"
|
||||
#include "zero_hash.h"
|
||||
#include "server_running.h"
|
||||
#include "treediff/TreeDiff.h"
|
||||
#include "../urlplugin/IUrlFactory.h"
|
||||
#include <time.h>
|
||||
#include <algorithm>
|
||||
#include <memory.h>
|
||||
|
||||
extern IFSImageFactory *image_fak;
|
||||
extern IUrlFactory *url_fak;
|
||||
extern std::string server_identity;
|
||||
extern std::string server_token;
|
||||
|
||||
@ -127,6 +130,10 @@ void BackupServerGet::unloadSQL(void)
|
||||
db->destroyQuery(q_get_unsent_logdata);
|
||||
db->destroyQuery(q_set_logdata_sent);
|
||||
db->destroyQuery(q_save_image_assoc);
|
||||
db->destroyQuery(q_get_users);
|
||||
db->destroyQuery(q_get_rights);
|
||||
db->destroyQuery(q_get_report_settings);
|
||||
db->destroyQuery(q_format_unixtime);
|
||||
}
|
||||
|
||||
void BackupServerGet::operator ()(void)
|
||||
@ -589,6 +596,10 @@ void BackupServerGet::prepareSQL(void)
|
||||
q_get_unsent_logdata=db->Prepare("SELECT id, strftime('%s', created) AS created, logdata FROM logs WHERE sent=0 AND clientid=?", false);
|
||||
q_set_logdata_sent=db->Prepare("UPDATE logs SET sent=1 WHERE id=?", false);
|
||||
q_save_image_assoc=db->Prepare("INSERT INTO assoc_images (img_id, assoc_id) VALUES (?,?)", false);
|
||||
q_get_users=db->Prepare("SELECT id FROM si_users WHERE report_mail IS NOT NULL AND report_mail<>''", false);
|
||||
q_get_rights=db->Prepare("SELECT t_right FROM si_permissions WHERE clientid=? AND t_domain=?", false);
|
||||
q_get_report_settings=db->Prepare("SELECT report_mail, report_loglevel, report_sendonly FROM si_users WHERE id=?", false);
|
||||
q_format_unixtime=db->Prepare("SELECT datetime(?, 'unixepoch', 'localtime') AS time", false);
|
||||
}
|
||||
|
||||
int BackupServerGet::getClientID(void)
|
||||
@ -1983,9 +1994,187 @@ void BackupServerGet::saveClientLogdata(int image, int incremental)
|
||||
q_save_logdata->Write();
|
||||
q_save_logdata->Reset();
|
||||
|
||||
sendLogdataMail(image, incremental, errors, warnings, infos, logdata);
|
||||
|
||||
ServerLogger::reset(clientid);
|
||||
}
|
||||
|
||||
std::wstring BackupServerGet::getUserRights(int userid, std::string domain)
|
||||
{
|
||||
if(domain!="all")
|
||||
{
|
||||
if(getUserRights(userid, "all")==L"all")
|
||||
return L"all";
|
||||
}
|
||||
q_get_rights->Bind(userid);
|
||||
q_get_rights->Bind(domain);
|
||||
db_results res=q_get_rights->Read();
|
||||
q_get_rights->Reset();
|
||||
if(!res.empty())
|
||||
{
|
||||
return res[0][L"t_right"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return L"none";
|
||||
}
|
||||
}
|
||||
|
||||
void BackupServerGet::sendLogdataMail(int image, int incremental, int errors, int warnings, int infos, std::wstring &data)
|
||||
{
|
||||
MailServer mail_server=getMailServerSettings();
|
||||
if(mail_server.servername.empty())
|
||||
return;
|
||||
|
||||
if(url_fak==NULL)
|
||||
return;
|
||||
|
||||
db_results res_users=q_get_users->Read();
|
||||
q_get_users->Reset();
|
||||
for(size_t i=0;i<res_users.size();++i)
|
||||
{
|
||||
std::wstring logr=getUserRights(watoi(res_users[i][L"id"]), "logs");
|
||||
bool has_r=false;
|
||||
if(logr!=L"all")
|
||||
{
|
||||
std::vector<std::wstring> toks;
|
||||
Tokenize(logr, toks, L",");
|
||||
for(size_t j=0;j<toks.size();++j)
|
||||
{
|
||||
if(toks[j]==res_users[i][L"id"])
|
||||
{
|
||||
has_r=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
has_r=true;
|
||||
}
|
||||
|
||||
if(has_r)
|
||||
{
|
||||
q_get_report_settings->Bind(watoi(res_users[i][L"id"]));
|
||||
db_results res=q_get_report_settings->Read();
|
||||
q_get_report_settings->Reset();
|
||||
|
||||
if(!res.empty())
|
||||
{
|
||||
std::wstring report_mail=res[0][L"report_mail"];
|
||||
int report_loglevel=watoi(res[0][L"report_loglevel"]);
|
||||
int report_sendonly=watoi(res[0][L"report_sendonly"]);
|
||||
|
||||
if( ( report_loglevel==0 && infos>0 )
|
||||
|| ( report_loglevel<=1 && warnings>0 )
|
||||
|| ( report_loglevel<=2 && errors>0 ) )
|
||||
{
|
||||
std::vector<std::string> to_addrs;
|
||||
Tokenize(Server->ConvertToUTF8(report_mail), to_addrs, ",;");
|
||||
|
||||
std::string subj="UrBackup: ";
|
||||
std::string msg="UrBackup just did ";
|
||||
if(incremental>0)
|
||||
{
|
||||
msg+="an incremental ";
|
||||
subj="Incremental ";
|
||||
}
|
||||
else
|
||||
{
|
||||
msg+="a full ";
|
||||
subj="Full";
|
||||
}
|
||||
|
||||
if(image>0)
|
||||
{
|
||||
msg+="image ";
|
||||
subj+="image ";
|
||||
}
|
||||
else
|
||||
{
|
||||
msg+="file ";
|
||||
subj+="file ";
|
||||
}
|
||||
subj+="backup of \""+Server->ConvertToUTF8(clientname)+"\"\n";
|
||||
msg+="backup of \""+Server->ConvertToUTF8(clientname)+"\".\n";
|
||||
msg+="\nReport:\n";
|
||||
msg+="( "+nconvert(infos);
|
||||
if(infos!=1) msg+=" infos, ";
|
||||
else msg+=" info, ";
|
||||
msg+=nconvert(warnings);
|
||||
if(warnings!=1) msg+=" warnings, ";
|
||||
else msg+=" warning, ";
|
||||
msg+=nconvert(errors);
|
||||
if(errors!=1) msg+=" errors";
|
||||
else msg+=" error";
|
||||
msg+=" )\n\n";
|
||||
std::vector<std::wstring> msgs;
|
||||
Tokenize(data, msgs, L"\n");
|
||||
bool not_complete=false;
|
||||
for(size_t j=0;j<msgs.size();++j)
|
||||
{
|
||||
std::wstring ll;
|
||||
if(!msgs[j].empty()) ll=msgs[j][0];
|
||||
int li=watoi(ll);
|
||||
msgs[j].erase(0, 2);
|
||||
std::wstring tt=getuntil(L"-", msgs[j]);
|
||||
std::wstring m=getafter(L"-", msgs[j]);
|
||||
if(li==2 && m.find(L"not complete")!=std::string::npos )
|
||||
not_complete=true;
|
||||
|
||||
q_format_unixtime->Bind(tt);
|
||||
db_results ft=q_format_unixtime->Read();
|
||||
q_format_unixtime->Reset();
|
||||
if( !ft.empty() )
|
||||
{
|
||||
tt=ft[0][L"time"];
|
||||
}
|
||||
std::string lls="info";
|
||||
if(li==1) lls="warning";
|
||||
else if(li==2) lls="error";
|
||||
msg+=Server->ConvertToUTF8(tt)+"("+lls+"): "+Server->ConvertToUTF8(m)+"\n";
|
||||
}
|
||||
if(not_complete)
|
||||
subj+=" - failed";
|
||||
else
|
||||
subj+=" - success";
|
||||
|
||||
if( report_sendonly==0 ||
|
||||
( report_sendonly==1 && not_complete ) ||
|
||||
( report_sendonly==2 && !not_complete) )
|
||||
{
|
||||
std::string errmsg;
|
||||
bool b=url_fak->sendMail(mail_server, to_addrs, subj, msg, &errmsg);
|
||||
if(!b)
|
||||
{
|
||||
Server->Log("Sending mail failed. "+errmsg, LL_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MailServer BackupServerGet::getMailServerSettings(void)
|
||||
{
|
||||
ISettingsReader *settings=Server->createDBSettingsReader(Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER), "settings", "SELECT value FROM settings WHERE key=? AND clientid=0");
|
||||
|
||||
MailServer ms;
|
||||
ms.servername=settings->getValue("mail_servername", "");
|
||||
ms.port=(unsigned short)watoi(settings->getValue(L"mail_serverport", L"25"));
|
||||
ms.username=settings->getValue("mail_username", "");
|
||||
ms.password=settings->getValue("mail_password", "");
|
||||
ms.mailfrom=settings->getValue("mail_from", "");
|
||||
if(ms.mailfrom.empty())
|
||||
ms.mailfrom="report@urbackup.org";
|
||||
|
||||
ms.ssl_only=settings->getValue("mail_ssl_only", "false")=="true"?true:false;
|
||||
ms.check_certificate=settings->getValue("mail_check_certificate", "false")=="true"?true:false;
|
||||
|
||||
Server->destroy(settings);
|
||||
return ms;
|
||||
}
|
||||
|
||||
const unsigned int stat_update_skip=20;
|
||||
const unsigned int sector_size=512;
|
||||
const unsigned int sha_size=32;
|
||||
@ -2029,6 +2218,8 @@ bool BackupServerGet::doImage(const std::string &pLetter, const std::wstring &pP
|
||||
if(hashfile==NULL)
|
||||
{
|
||||
ServerLogger::Log(clientid, "Error opening hashfile", LL_ERROR);
|
||||
Server->Log("Starting image path repair...", LL_INFO);
|
||||
ServerUpdateStats::repairImages();
|
||||
Server->destroy(cc);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "../Interface/SettingsReader.h"
|
||||
#include "../Interface/Mutex.h"
|
||||
#include "../Interface/ThreadPool.h"
|
||||
#include "../urlplugin/IUrlFactory.h"
|
||||
#include "fileclient/FileClient.h"
|
||||
#include "os_functions.h"
|
||||
#include "server_hash.h"
|
||||
@ -43,6 +44,7 @@ public:
|
||||
static void destroy_mutex(void);
|
||||
|
||||
static bool isInBackupWindow(std::vector<STimeSpan> bw);
|
||||
static MailServer getMailServerSettings(void);
|
||||
|
||||
private:
|
||||
void unloadSQL(void);
|
||||
@ -74,7 +76,9 @@ private:
|
||||
void setBackupDone(void);
|
||||
void setBackupImageComplete(void);
|
||||
void sendClientLogdata(void);
|
||||
std::wstring getUserRights(int userid, std::string domain);
|
||||
void saveClientLogdata(int image, int incremental);
|
||||
void sendLogdataMail(int image, int incremental, int errors, int warnings, int infos, std::wstring &data);
|
||||
bool doImage(const std::string &pLetter, const std::wstring &pParentvhd, int incremental, int incremental_ref);
|
||||
std::string getMBR(const std::wstring &dl);
|
||||
unsigned int writeMBR(ServerVHDWriter *vhdfile, uint64 volsize);
|
||||
@ -145,6 +149,11 @@ private:
|
||||
IQuery *q_get_unsent_logdata;
|
||||
IQuery *q_set_logdata_sent;
|
||||
IQuery *q_save_image_assoc;
|
||||
IQuery *q_get_users;
|
||||
IQuery *q_get_rights;
|
||||
IQuery *q_get_report_settings;
|
||||
IQuery *q_format_unixtime;
|
||||
|
||||
|
||||
int state;
|
||||
std::string t_name;
|
||||
|
||||
@ -8,13 +8,19 @@
|
||||
#include "../Interface/File.h"
|
||||
#include "os_functions.h"
|
||||
#include "../stringtools.h"
|
||||
#include "server_settings.h"
|
||||
|
||||
const bool update_stats_use_transactions=true;
|
||||
const bool update_stats_autocommit=true;
|
||||
|
||||
ServerUpdateStats::ServerUpdateStats(bool image_repair_mode)
|
||||
: image_repair_mode(image_repair_mode)
|
||||
{
|
||||
}
|
||||
|
||||
void ServerUpdateStats::createQueries(void)
|
||||
{
|
||||
q_get_images=db->Prepare("SELECT clientid,path FROM backup_images WHERE complete=1 AND running<datetime('now','-300 seconds')", false);
|
||||
q_get_images=db->Prepare("SELECT id,clientid,path FROM backup_images WHERE complete=1 AND running<datetime('now','-300 seconds')", false);
|
||||
q_update_images_size=db->Prepare("UPDATE clients SET bytes_used_images=? WHERE id=?", false);
|
||||
q_get_ncount_files=db->Prepare("SELECT files.rowid AS id, shahash, filesize, rsize, clientid, backupid FROM (files INNER JOIN backups ON files.backupid=backups.id) WHERE did_count=0 LIMIT 10000", false);
|
||||
q_has_client=db->Prepare("SELECT count(*) AS c FROM (files INNER JOIN backups ON files.backupid=backups.id) WHERE shahash=? AND filesize=? AND clientid=?", false);
|
||||
@ -70,25 +76,32 @@ void ServerUpdateStats::operator()(void)
|
||||
|
||||
createQueries();
|
||||
|
||||
q_create_hist->Write();
|
||||
q_create_hist->Reset();
|
||||
if(!image_repair_mode)
|
||||
{
|
||||
q_create_hist->Write();
|
||||
q_create_hist->Reset();
|
||||
|
||||
q_save_client_hist->Bind(db->getLastInsertID());
|
||||
q_save_client_hist->Write();
|
||||
q_save_client_hist->Reset();
|
||||
q_save_client_hist->Bind(db->getLastInsertID());
|
||||
q_save_client_hist->Write();
|
||||
q_save_client_hist->Reset();
|
||||
}
|
||||
|
||||
update_images();
|
||||
update_files();
|
||||
|
||||
q_create_hist->Write();
|
||||
q_create_hist->Reset();
|
||||
if(!image_repair_mode)
|
||||
{
|
||||
update_files();
|
||||
|
||||
q_save_client_hist->Bind(db->getLastInsertID());
|
||||
q_save_client_hist->Write();
|
||||
q_save_client_hist->Reset();
|
||||
q_create_hist->Write();
|
||||
q_create_hist->Reset();
|
||||
|
||||
q_set_file_backup_null->Write();
|
||||
q_set_file_backup_null->Reset();
|
||||
q_save_client_hist->Bind(db->getLastInsertID());
|
||||
q_save_client_hist->Write();
|
||||
q_save_client_hist->Reset();
|
||||
|
||||
q_set_file_backup_null->Write();
|
||||
q_set_file_backup_null->Reset();
|
||||
}
|
||||
|
||||
destroyQueries();
|
||||
if(!cache_res.empty())
|
||||
@ -97,9 +110,17 @@ void ServerUpdateStats::operator()(void)
|
||||
}
|
||||
}
|
||||
|
||||
void ServerUpdateStats::repairImages(void)
|
||||
{
|
||||
ServerUpdateStats sus(true);
|
||||
sus();
|
||||
}
|
||||
|
||||
void ServerUpdateStats::update_images(void)
|
||||
{
|
||||
Server->Log("Updating image stats...",LL_INFO);
|
||||
if(!image_repair_mode)
|
||||
Server->Log("Updating image stats...",LL_INFO);
|
||||
|
||||
db_results res=q_get_images->Read();
|
||||
q_get_images->Reset();
|
||||
|
||||
@ -119,6 +140,12 @@ void ServerUpdateStats::update_images(void)
|
||||
IFile * file=Server->openFile(os_file_prefix()+fn, MODE_READ);
|
||||
if(file==NULL)
|
||||
{
|
||||
bool b=repairImagePath(res[i]);
|
||||
if(b)
|
||||
{
|
||||
update_images();
|
||||
return;
|
||||
}
|
||||
Server->Log(L"Error opening file '"+fn+L"'", LL_ERROR);
|
||||
continue;
|
||||
}
|
||||
@ -585,4 +612,40 @@ void ServerUpdateStats::updateDels(std::map<int, SDelInfo> &data)
|
||||
}
|
||||
}
|
||||
|
||||
bool ServerUpdateStats::repairImagePath(str_map img)
|
||||
{
|
||||
int clientid=watoi(img[L"clientid"]);
|
||||
ServerSettings settings(db, clientid);
|
||||
IQuery *q=db->Prepare("SELECT name FROM clients WHERE id=?", false);
|
||||
q->Bind(clientid);
|
||||
db_results res=q->Read();
|
||||
q->Reset();
|
||||
db->destroyQuery(q);
|
||||
if(!res.empty())
|
||||
{
|
||||
std::wstring clientname=res[0][L"name"];
|
||||
std::wstring imgname=ExtractFileName(img[L"path"]);
|
||||
|
||||
std::wstring new_name=settings.getSettings()->backupfolder+os_file_sep()+clientname+os_file_sep()+imgname;
|
||||
|
||||
IFile * file=Server->openFile(os_file_prefix()+new_name, MODE_READ);
|
||||
if(file==NULL)
|
||||
{
|
||||
Server->Log(L"Repairing image failed", LL_INFO);
|
||||
return false;
|
||||
}
|
||||
Server->destroy(file);
|
||||
|
||||
q=db->Prepare("UPDATE backup_images SET path=? WHERE id=?", false);
|
||||
q->Bind(new_name);
|
||||
q->Bind(img[L"id"]);
|
||||
q->Write();
|
||||
q->Reset();
|
||||
db->destroyQuery(q);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif //CLIENT_ONLY
|
||||
@ -14,6 +14,8 @@ struct SDelInfo
|
||||
class ServerUpdateStats : public IThread
|
||||
{
|
||||
public:
|
||||
ServerUpdateStats(bool image_repair_mode=false);
|
||||
|
||||
void operator()(void);
|
||||
|
||||
void update_files(void);
|
||||
@ -21,6 +23,8 @@ public:
|
||||
|
||||
void createQueries(void);
|
||||
void destroyQueries(void);
|
||||
|
||||
static void repairImages(void);
|
||||
private:
|
||||
|
||||
std::map<int, _i64> calculateSizeDeltas(const std::wstring &pShaHash, _i64 filesize, _i64 *rsize);
|
||||
@ -32,6 +36,10 @@ private:
|
||||
void updateBackups(std::map<int, _i64> &data);
|
||||
void updateDels(std::map<int, SDelInfo> &data);
|
||||
|
||||
bool repairImagePath(str_map img);
|
||||
|
||||
bool image_repair_mode;
|
||||
|
||||
IQuery *q_get_images;
|
||||
IQuery *q_update_images_size;
|
||||
IQuery *q_get_ncount_files;
|
||||
|
||||
@ -130,6 +130,45 @@ ACTION_IMPL(logs)
|
||||
}
|
||||
ret.set("logs", logs);
|
||||
ret.set("ll", ll);
|
||||
|
||||
if(GET.find(L"report_mail")!=GET.end())
|
||||
{
|
||||
IQuery *q=db->Prepare("UPDATE si_users SET report_mail=?, report_loglevel=? WHERE id=?");
|
||||
q->Bind(GET[L"report_mail"]);
|
||||
q->Bind(watoi(GET[L"report_loglevel"]));
|
||||
q->Bind(session->id);
|
||||
q->Write();
|
||||
q->Reset();
|
||||
}
|
||||
|
||||
if(GET.find(L"report_mail")!=GET.end())
|
||||
{
|
||||
IQuery *q=db->Prepare("UPDATE si_users SET report_mail=?, report_loglevel=?, report_sendonly=? WHERE id=?");
|
||||
q->Bind(GET[L"report_mail"]);
|
||||
q->Bind(watoi(GET[L"report_loglevel"]));
|
||||
q->Bind(watoi(GET[L"report_sendonly"]));
|
||||
q->Bind(session->id);
|
||||
q->Write();
|
||||
ret.set("saved_ok", true);
|
||||
}
|
||||
|
||||
IQuery *mq=db->Prepare("SELECT report_mail, report_loglevel, report_sendonly FROM si_users WHERE id=? AND report_mail IS NOT NULL");
|
||||
mq->Bind(session->id);
|
||||
res=mq->Read();
|
||||
mq->Reset();
|
||||
|
||||
if(!res.empty())
|
||||
{
|
||||
ret.set("report_mail", res[0][L"report_mail"]);
|
||||
ret.set("report_loglevel", watoi(res[0][L"report_loglevel"]));
|
||||
ret.set("report_sendonly", watoi(res[0][L"report_sendonly"]));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.set("report_mail", "");
|
||||
ret.set("report_sendonly", "");
|
||||
ret.set("report_loglevel", "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -21,7 +21,24 @@
|
||||
#include "action_header.h"
|
||||
#include "../server_settings.h"
|
||||
#include "../../Interface/SettingsReader.h"
|
||||
#include "../../urlplugin/IUrlFactory.h"
|
||||
#include "../os_functions.h"
|
||||
#include "../server_get.h"
|
||||
|
||||
extern IUrlFactory *url_fak;
|
||||
|
||||
std::vector<std::wstring> getMailSettingsList(void)
|
||||
{
|
||||
std::vector<std::wstring> tmp;
|
||||
tmp.push_back(L"mail_servername");
|
||||
tmp.push_back(L"mail_serverport");
|
||||
tmp.push_back(L"mail_username");
|
||||
tmp.push_back(L"mail_password");
|
||||
tmp.push_back(L"mail_from");
|
||||
tmp.push_back(L"mail_ssl_only");
|
||||
tmp.push_back(L"mail_check_certificate");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
JSON::Object getJSONClientSettings(ServerSettings &settings)
|
||||
{
|
||||
@ -96,6 +113,29 @@ SGeneralSettings getGeneralSettings(IDatabase *db)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void getMailSettings(JSON::Object &obj, IDatabase *db)
|
||||
{
|
||||
std::vector<std::wstring> slist=getMailSettingsList();
|
||||
IQuery *q=db->Prepare("SELECT key, value FROM settings WHERE clientid=0 AND key=?");
|
||||
for(size_t i=0;i<slist.size();++i)
|
||||
{
|
||||
q->Bind(slist[i]);
|
||||
db_results res=q->Read();
|
||||
q->Reset();
|
||||
if(!res.empty())
|
||||
{
|
||||
obj.set(Server->ConvertToUTF8(slist[i]), res[0][L"value"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string v="";
|
||||
if(slist[i]==L"mail_serverport")
|
||||
v="25";
|
||||
obj.set(Server->ConvertToUTF8(slist[i]), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SClientSettings getClientSettings(IDatabase *db, int clientid)
|
||||
{
|
||||
IQuery *q=db->Prepare("SELECT key, value FROM settings WHERE clientid=?");
|
||||
@ -158,6 +198,23 @@ void saveGeneralSettings(SGeneralSettings settings, IDatabase *db)
|
||||
#endif
|
||||
}
|
||||
|
||||
void updateMailSettings(str_map &GET, IDatabase *db)
|
||||
{
|
||||
IQuery *q_get=db->Prepare("SELECT value FROM settings WHERE clientid=0 AND key=?");
|
||||
IQuery *q_update=db->Prepare("UPDATE settings SET value=? WHERE key=? AND clientid=0");
|
||||
IQuery *q_insert=db->Prepare("INSERT INTO settings (key, value, clientid) VALUES (?,?,0)");
|
||||
|
||||
std::vector<std::wstring> settings=getMailSettingsList();
|
||||
for(size_t i=0;i<settings.size();++i)
|
||||
{
|
||||
str_map::iterator it=GET.find(settings[i]);
|
||||
if(it!=GET.end())
|
||||
{
|
||||
updateSetting(settings[i], it->second, q_get, q_update, q_insert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void saveClientSettings(SClientSettings settings, IDatabase *db, int clientid)
|
||||
{
|
||||
IQuery *q_get=db->Prepare("SELECT value FROM settings WHERE clientid="+nconvert(clientid)+" AND key=?");
|
||||
@ -290,6 +347,11 @@ ACTION_IMPL(settings)
|
||||
navitems.set("users", true);
|
||||
}
|
||||
|
||||
if(helper.getRights("mail_settings")=="all")
|
||||
{
|
||||
navitems.set("mail", true);
|
||||
}
|
||||
|
||||
JSON::Array clients;
|
||||
|
||||
if(rights=="all" )
|
||||
@ -532,6 +594,43 @@ ACTION_IMPL(settings)
|
||||
ret.set("settings", obj);
|
||||
}
|
||||
}
|
||||
if(sa==L"mail_save" && helper.getRights("mail_settings")=="all")
|
||||
{
|
||||
updateMailSettings(GET, db);
|
||||
ret.set("saved_ok", true);
|
||||
std::wstring testmailaddr=GET[L"testmailaddr"];
|
||||
if(!testmailaddr.empty())
|
||||
{
|
||||
MailServer mail_server=BackupServerGet::getMailServerSettings();
|
||||
if(url_fak!=NULL)
|
||||
{
|
||||
std::vector<std::string> to;
|
||||
to.push_back(Server->ConvertToUTF8(testmailaddr));
|
||||
std::string errmsg;
|
||||
bool b=url_fak->sendMail(mail_server, to, "UrBackup mail test", "This is a test mail from UrBackup", &errmsg);
|
||||
if(!b)
|
||||
{
|
||||
ret.set("mail_test", errmsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.set("mail_test", "ok");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.set("mail_test", "Mail module not loaded");
|
||||
}
|
||||
}
|
||||
sa=L"mail";
|
||||
}
|
||||
if( sa==L"mail" && helper.getRights("mail_settings")=="all")
|
||||
{
|
||||
JSON::Object obj;
|
||||
getMailSettings(obj, db);
|
||||
ret.set("settings", obj);
|
||||
ret.set("sa", sa);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -86,6 +86,9 @@ ACTION_IMPL(generate_templ)
|
||||
templates.push_back("status_detail_extra_row");
|
||||
templates.push_back("status_detail_row");
|
||||
templates.push_back("status_row_delete_pending");
|
||||
templates.push_back("settings_mail");
|
||||
templates.push_back("settings_mail_test_ok");
|
||||
templates.push_back("settings_mail_test_failed");
|
||||
|
||||
IFile *out=Server->openFile("urbackup/www/templates.js", MODE_WRITE);
|
||||
if(out==NULL)
|
||||
|
||||
@ -6,7 +6,7 @@ tmpls.main_nav=new Template("<a class=\"links_item\" href=\"javascript: #{func}(
|
||||
tmpls.main_nav_sel=new Template("<a class=\"links1_active\" href=\"javascript: #{func}('#{params}')\">#{name}</a>");
|
||||
tmpls.lastacts_table=new Template("<h1>#{tLast activities}</h1>\r\n\r\n<table cellspacing=\"0\" cellpadding=\"0\">\r\n<tr>\t\t\t\r\n\t<th style=\"width: 50px\" class=\"tabHeader\">#{tID}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tComputer name}</th>\r\n\t<th style=\"width: 200px\" class=\"tabHeader\">#{tAction}</th>\r\n\t<th style=\"width: 200px\" class=\"tabHeader\">#{tStarting time}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tRequired time}</th>\r\n\t<th style=\"width: 200px\" class=\"tabHeaderRight\">#{tUsed Storage}</th>\r\n</tr>\r\n#{rows}\r\n</table>");
|
||||
tmpls.lastacts_row=new Template("<tr>\r\n\t<td class=\"tabFLeft\">#{id}</td>\r\n\t<td class=\"tabFLeft\">#{name}</td>\r\n\t<td class=\"tabFLeft\">#{action}</td>\r\n\t<td class=\"tabFLeft\">#{backuptime}</td>\r\n\t<td class=\"tabFLeft\">#{duration}</td>\r\n\t<td class=\"tabFRight\">#{size}</td>\r\n</tr>");
|
||||
tmpls.stat_general=new Template("<h1>#{tStorage allocation}</h1>\r\n\r\n<div id=\"piegraph\"><img src=\"indicator.gif\" />#{tLoading}...<br /><br /></div>\r\n\r\n<table cellspacing=\"0\" cellpadding=\"0\">\r\n<tr>\t\t\t\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tComputer name}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tImages}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tFiles}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeaderRight\">#{tAll}</th>\r\n</tr>\r\n#{rows}\r\n<tr>\r\n\t<td class=\"tabFRight\" colspan=\"4\" style=\"height:0px\"></td>\r\n</tr>\r\n<tr>\r\n\t<td class=\"tabFLeft\">#{tAll}</td>\r\n\t<td class=\"tabFLeft\">#{images_total}</td>\r\n\t<td class=\"tabFLeft\">#{files_total}</td>\r\n\t<td class=\"tabFRight\">#{used_total}</td>\r\n</tr>\r\n</table>\r\n\r\n<h1>#{tStorage usage}</h1>\r\n\r\n<div id=\"usagegraph\"><img src=\"indicator.gif\" />#{tLoading}...</div>");
|
||||
tmpls.stat_general=new Template("<h1>#{tStorage allocation}</h1>\r\n\r\n<div id=\"piegraph\"><img src=\"indicator.gif\" />#{tLoading}...<br /><br /></div>\r\n\r\n<table cellspacing=\"0\" cellpadding=\"0\">\r\n<tr>\t\t\t\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tComputer name}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tImages}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tFiles}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeaderRight\">#{tAll}</th>\r\n</tr>\r\n#{rows}\r\n<tr>\r\n\t<td class=\"tabFRight\" colspan=\"4\" style=\"height:0px\"></td>\r\n</tr>\r\n<tr>\r\n\t<td class=\"tabFLeft\">#{tSum}</td>\r\n\t<td class=\"tabFLeft\">#{images_total}</td>\r\n\t<td class=\"tabFLeft\">#{files_total}</td>\r\n\t<td class=\"tabFRight\">#{used_total}</td>\r\n</tr>\r\n</table>\r\n\r\n<h1>#{tStorage usage}</h1>\r\n\r\n<div id=\"usagegraph\"><img src=\"indicator.gif\" />#{tLoading}...</div>");
|
||||
tmpls.stat_general_row=new Template("<tr>\r\n\t<td class=\"tabFLeft\">#{name}</td>\r\n\t<td class=\"tabFLeft\">#{images}</td>\r\n\t<td class=\"tabFLeft\">#{files}</td>\r\n\t<td class=\"tabFRight\">#{used}</td>\r\n</tr>");
|
||||
tmpls.stat_user=new Template("<h1>#{tStorage usage of} #{clientname}</h1>\r\n\r\n<div id=\"usagegraph\"><img src=\"indicator.gif\" />#{tLoading}...</div>");
|
||||
tmpls.status=new Template("<h1>#{tBackup status}</h1>\r\n\r\n#{dir_error}\r\n#{tmpdir_error}\r\n\r\n<table cellspacing=\"0\" cellpadding=\"0\">\r\n<tr>\t\t\t\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tComputer name}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tLast seen}</th>\r\n\t<th style=\"width: 200px\" class=\"tabHeader\">#{tLast file backup}</th>\r\n\t<th style=\"width: 200px\" class=\"tabHeader\">#{tLast image backup}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tFile backup status}</th>\r\n\t<th style=\"width: 200px\" class=\"tabHeaderRight\">#{tImage backup status}</th>\r\n</tr>\r\n#{rows}\r\n</table>\r\n<br><br>\r\n#{dtl_c1}<a href=\"javascript: show_status1(true);\">#{tShow details}</a>#{dtl_c2}");
|
||||
@ -31,7 +31,7 @@ tmpls.settings_user_create_admin=new Template("<br />\r\n<form action=\"#\" o
|
||||
tmpls.settings_user_rights_change=new Template("<br />\r\n<strong>#{tChange rights for user}: #{username}</strong>\r\n<br />\r\n<form action=\"#\" onsubmit=\"submitChangeUserRights(#{userid}); return false;\">\r\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" class=\"formtable\" id=\"rightstable\">\r\n<tr>\r\n<th class=\"tabHeaderNB\">#{tDomain}</td>\r\n<th class=\"tabHeaderNB\">#{tRights}</td>\r\n<th class=\"tabHeaderNB\">#{tTranslation}</td>\r\n<th class=\"tabHeaderNB\">#{tActions}</td>\r\n</tr>\r\n#{rows}\r\n</table>\r\n<br />\r\n<a href=\"javascript: addNewDomain(#{userid}, '#{username}')\">#{tNew domain}</a>\r\n<br />\r\n<br />\r\n<input type=\"button\" value=\"#{tAbort}\" onclick=\"userSettings()\"> <input type=\"submit\" value=\"#{tChange}\" />\r\n</form>");
|
||||
tmpls.settings_user_rights_change_row=new Template("<tr>\r\n<td class=\"tabFNB\"><input type=\"text\" size=\"20\" value=\"#{domain}\" id=\"domain#{n}\" /></td>\r\n<td class=\"tabFNB\"><input type=\"text\" size=\"20\" value=\"#{right}\" id=\"right#{n}\" onchange=\"transRights()\" onkeyup=\"transRights()\"/></td>\r\n<td class=\"tabFNB\"><input type=\"text\" size=\"20\" value=\"\" id=\"right_trans#{n}\" disabled=\"distabled\" /></td>\r\n<td class=\"tabFNB\"><input type=\"button\" value=\"#{tDelete domain}\" onclick=\"deleteDomain(#{userid}, '#{username}', #{n})\" /></td>\r\n</tr>");
|
||||
tmpls.settings_user_pw_change=new Template("<br />\r\n<form action=\"#\" onsubmit=\"changeUserPW(#{userid}); return false;\">\r\n<strong>#{tChange password for user}: #{username}</strong>\r\n<br />\r\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" class=\"formtable\">\r\n<tr>\r\n<td>#{tPassword}:</td>\r\n<td><input type=\"password\" id=\"password1\" value=\"\" size=\"40\"/></td>\r\n</tr>\r\n<tr>\r\n<td>#{tRepeat password}:</td>\r\n<td><input type=\"password\" id=\"password2\" value=\"\" size=\"40\"/></td>\r\n</tr>\r\n</table>\r\n<br />\r\n<br />\r\n<input type=\"button\" value=\"#{tAbort}\" onclick=\"userSettings()\"> <input type=\"submit\" value=\"#{tChange}\" />\r\n</form>");
|
||||
tmpls.logs_table=new Template("<h1>#{tLogs}</h1>\r\n\r\n<table cellspacing=\"0\" cellpadding=\"0\">\r\n<tr>\t\r\n\t<th style=\"width: 25px\" class=\"tabHeader\"> </th>\r\n\t<th style=\"width: 130px\" class=\"tabHeader\">#{tComputer name}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tBackup time}</th>\r\n\t<th style=\"width: 70px\" class=\"tabHeader\">#{tErrors}</th>\r\n\t<th style=\"width: 70px\" class=\"tabHeader\">#{tWarnings}</th>\r\n\t<th style=\"width: 300px\" class=\"tabHeaderRight\">#{tAction}</th>\r\n</tr>\r\n#{rows}\r\n</table>");
|
||||
tmpls.logs_table=new Template("<h1>#{tLogs}</h1>\r\n\r\n<table cellspacing=\"0\" cellpadding=\"0\">\r\n<tr>\t\r\n\t<th style=\"width: 25px\" class=\"tabHeader\"> </th>\r\n\t<th style=\"width: 130px\" class=\"tabHeader\">#{tComputer name}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tBackup time}</th>\r\n\t<th style=\"width: 70px\" class=\"tabHeader\">#{tErrors}</th>\r\n\t<th style=\"width: 70px\" class=\"tabHeader\">#{tWarnings}</th>\r\n\t<th style=\"width: 300px\" class=\"tabHeaderRight\">#{tAction}</th>\r\n</tr>\r\n#{rows}\r\n</table>\r\n\r\n<h1>#{tReports}</h1>\r\n#{tSend reports to}\r\n<input type=\"text\" size=\"40\" id=\"report_mail\" value=\"#{report_mail}\"/> (#{tE-Mail addresses seperated by ';'}). <br />\r\n#{tSend}\r\n<select size=\"1\" style=\"width: 150px\" id=\"report_sendonly\">\r\n<option value=\"0\" #{sel_all}>#{tAll}</option>\r\n<option value=\"1\" #{sel_failed}>#{tFailed}</option>\r\n<option value=\"2\" #{sel_succ}>#{tSuccessfull}</option>\r\n</select>\r\n#{tBackups with a log message of at least log level}\r\n<select size=\"1\" style=\"width: 150px\" id=\"report_loglevel\">\r\n<option value=\"0\" #{sel_info}>#{tInfo}</option>\r\n<option value=\"1\" #{sel_warn}>#{tWarning}</option>\r\n<option value=\"2\" #{sel_error}>#{tError}</option>\r\n</select>\r\n<br />\r\n<input type=\"button\" value=\"#{tSave}\" onClick=\"saveReportSettings()\" />");
|
||||
tmpls.logs_row=new Template("<tr onmouseover=\"tabMouseOver(this)\" onmouseout=\"tabMouseOut(this)\" onclick=\"g.tabMouseClickLogs(#{id})\">\r\n\t<td class=\"tabFLeftH\"></td>\r\n\t<td class=\"tabFLeftH\">#{name}</td>\r\n\t<td class=\"tabFLeftH\">#{time}</td>\r\n\t<td class=\"tabFLeftH\" style=\"#{estyle}\"><div style=\"background-color:white\">#{errors}</div></td>\r\n\t<td class=\"tabFLeftH\" style=\"#{wstyle}\"><div style=\"background-color:white\">#{warnings}</div></td>\r\n\t<td class=\"tabFRightH\">#{action}</td>\r\n</tr>");
|
||||
tmpls.log_single=new Template("<a href=\"javascript: show_logs1('#{params}')\">#{tBack}</a>\r\n\r\n<h1>#{tLog} (#{name})</h1>\r\n\r\n<table cellspacing=\"0\" cellpadding=\"0\">\r\n<tr>\t\r\n\t<th style=\"width: 50px\" class=\"tabHeader\">#{tLevel}</th>\r\n\t<th style=\"width: 150px\" class=\"tabHeader\">#{tTime}</th>\r\n\t<th style=\"width: 650px\" class=\"tabHeaderRight\">#{tMessage}</th>\r\n</tr>\r\n#{rows}\r\n</table>");
|
||||
tmpls.log_single_row=new Template("<tr>\n\t<td class=\"tabFLeft\" style=\"#{lstyle}\"><div style=\"background-color: white\">#{level}</div></td>\n\t<td class=\"tabFLeft\"><div style=\"background-color: white\">#{time}</div></td>\n\t<td class=\"tabFRight\">#{message}</td>\n</tr>");
|
||||
@ -46,3 +46,6 @@ tmpls.status_detail_extra_empty=new Template("<tr>\r\n\t<td class=\"tabFRight\"
|
||||
tmpls.status_detail_extra_row=new Template("<tr>\r\n\t<td class=\"tabFLeft\">#{hostname}</td>\r\n\t<td class=\"tabFLeft\">#{online}</td>\r\n\t<td class=\"tabFRight\"><input type=\"button\" value=\"#{tRemove}\" onClick=\"removeExtraClient(#{id})\"></td>\r\n</tr>");
|
||||
tmpls.status_detail_row=new Template("<tr>\r\n\t<td class=\"tabFLeft\">#{name}</td>\r\n\t<td class=\"tabFLeft\">#{online}</td>\r\n\t<td class=\"tabFLeft\">#{status}</td>\r\n\t<td class=\"tabFLeft\">#{lastseen}</td>\r\n\t<td class=\"tabFLeft\">#{lastbackup}</td>\r\n\t<td class=\"tabFLeft\">#{lastbackup_image}</td>\r\n\t<td class=\"tabFLeft\" style=\"#{file_style}\"><div style=\"background-color:white\">#{file_ok_t}</div></td>\r\n\t<td class=\"tabFLeft\" style=\"#{image_style}\"><div style=\"background-color:white\">#{image_ok_t}</div></td>\r\n\t<td class=\"#{prev_tab_class}\">#{ip}</td>\r\n#{Actions_start}\r\n\t<td class=\"tabFRight\">\r\n#{Action_remove_start}\r\n\t<input type=\"button\" value=\"#{tRemove}\" onclick=\"removeClient(#{id})\" />\r\n#{Action_remove_end}\r\n\t</td>\t\r\n#{Actions_end}\r\n</tr>");
|
||||
tmpls.status_row_delete_pending=new Template("<tr>\n\t<td class=\"tabFLeft\">#{name}</td>\n\t<td class=\"tabFRight\" colspan=\"#{colspan}\">\n\t#{tThis client is going to be removed.}\n#{stop_remove_start}\n\t<a href=\"javascript: stopRemove(#{id})\">#{tStop removing client}</a>\n#{stop_remove_stop}\n\t</td>\n</tr>");
|
||||
tmpls.settings_mail=new Template("<br />\r\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" class=\"formtable\">\r\n<tr>\r\n<td>#{tMail server name}:</td>\r\n<td><input type=\"text\" size=\"40\" id=\"mail_servername\" value=\"#{mail_servername}\"/> </td>\r\n</tr>\r\n<tr>\r\n<td>#{tMail server port}:</td>\r\n<td><input type=\"text\" size=\"40\" id=\"mail_serverport\" value=\"#{mail_serverport}\"/> </td>\r\n</tr>\r\n<tr>\r\n<td>#{tMail server username (empty for none)}:</td>\r\n<td><input type=\"text\" size=\"40\" id=\"mail_username\" value=\"#{mail_username}\"/> </td>\r\n</tr>\r\n<tr>\r\n<td>#{tMail server password}:</td>\r\n<td><input type=\"text\" size=\"40\" id=\"mail_password\" value=\"#{mail_password}\"/> </td>\r\n</tr>\r\n<tr>\r\n<td>#{tSender E-Mail Address}:</td>\r\n<td><input type=\"text\" id=\"mail_from\" value=\"#{mail_from}\" /></td>\r\n</tr>\r\n<tr>\r\n<td>#{tSend mails only with SSL/TLS}:</td>\r\n<td><input type=\"checkbox\" id=\"mail_ssl_only\" value=\"false\" #{mail_ssl_only}/></td>\r\n</tr>\r\n<td>#{tCheck SSL/TLS certificate}:</td>\r\n<td><input type=\"checkbox\" id=\"mail_check_certificate\" value=\"false\" #{mail_check_certificate}/></td>\r\n</tr>\r\n</table>\r\n<br />\r\n<br />\r\n<input type=\"button\" value=\"#{tSave}\" onClick=\"saveMailSettings()\" />\r\n<br />\r\n#{tSend test mail to this email address after saving the settings (leave empty to not send a test mail)}:<br />\r\n<input type=\"text\" size=\"40\" id=\"testmailaddr\" value=\"\"/>\r\n");
|
||||
tmpls.settings_mail_test_ok=new Template("<br />\r\n<br />\r\n<strong>#{tTest Mail sent successfully}.</strong>");
|
||||
tmpls.settings_mail_test_failed=new Template("<br />\r\n<br />\r\n<strong>#{tSending test mail failed. Error:}</strong> #{mail_err}");
|
||||
|
||||
@ -10,4 +10,22 @@
|
||||
<th style="width: 300px" class="tabHeaderRight">#{tAction}</th>
|
||||
</tr>
|
||||
#{rows}
|
||||
</table>
|
||||
</table>
|
||||
|
||||
<h1>#{tReports}</h1>
|
||||
#{tSend reports to}
|
||||
<input type="text" size="40" id="report_mail" value="#{report_mail}"/> (#{tE-Mail addresses seperated by ';'}). <br />
|
||||
#{tSend}
|
||||
<select size="1" style="width: 150px" id="report_sendonly">
|
||||
<option value="0" #{sel_all}>#{tAll}</option>
|
||||
<option value="1" #{sel_failed}>#{tFailed}</option>
|
||||
<option value="2" #{sel_succ}>#{tSuccessfull}</option>
|
||||
</select>
|
||||
#{tBackups with a log message of at least log level}
|
||||
<select size="1" style="width: 150px" id="report_loglevel">
|
||||
<option value="0" #{sel_info}>#{tInfo}</option>
|
||||
<option value="1" #{sel_warn}>#{tWarning}</option>
|
||||
<option value="2" #{sel_error}>#{tError}</option>
|
||||
</select>
|
||||
<br />
|
||||
<input type="button" value="#{tSave}" onClick="saveReportSettings()" />
|
||||
36
urbackup/www/templates/settings_mail.htm
Normal file
36
urbackup/www/templates/settings_mail.htm
Normal file
@ -0,0 +1,36 @@
|
||||
<br />
|
||||
<table cellspacing="0" cellpadding="0" border="0" class="formtable">
|
||||
<tr>
|
||||
<td>#{tMail server name}:</td>
|
||||
<td><input type="text" size="40" id="mail_servername" value="#{mail_servername}"/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>#{tMail server port}:</td>
|
||||
<td><input type="text" size="40" id="mail_serverport" value="#{mail_serverport}"/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>#{tMail server username (empty for none)}:</td>
|
||||
<td><input type="text" size="40" id="mail_username" value="#{mail_username}"/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>#{tMail server password}:</td>
|
||||
<td><input type="text" size="40" id="mail_password" value="#{mail_password}"/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>#{tSender E-Mail Address}:</td>
|
||||
<td><input type="text" id="mail_from" value="#{mail_from}" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>#{tSend mails only with SSL/TLS}:</td>
|
||||
<td><input type="checkbox" id="mail_ssl_only" value="false" #{mail_ssl_only}/></td>
|
||||
</tr>
|
||||
<td>#{tCheck SSL/TLS certificate}:</td>
|
||||
<td><input type="checkbox" id="mail_check_certificate" value="false" #{mail_check_certificate}/></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<br />
|
||||
<input type="button" value="#{tSave}" onClick="saveMailSettings()" />
|
||||
<br />
|
||||
#{tSend test mail to this email address after saving the settings (leave empty to not send a test mail)}:<br />
|
||||
<input type="text" size="40" id="testmailaddr" value=""/>
|
||||
3
urbackup/www/templates/settings_mail_test_failed.htm
Normal file
3
urbackup/www/templates/settings_mail_test_failed.htm
Normal file
@ -0,0 +1,3 @@
|
||||
<br />
|
||||
<br />
|
||||
<strong>#{tSending test mail failed. Error:}</strong> #{mail_err}
|
||||
3
urbackup/www/templates/settings_mail_test_ok.htm
Normal file
3
urbackup/www/templates/settings_mail_test_ok.htm
Normal file
@ -0,0 +1,3 @@
|
||||
<br />
|
||||
<br />
|
||||
<strong>#{tTest Mail sent successfully}.</strong>
|
||||
@ -14,7 +14,7 @@
|
||||
<td class="tabFRight" colspan="4" style="height:0px"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tabFLeft">#{tAll}</td>
|
||||
<td class="tabFLeft">#{tSum}</td>
|
||||
<td class="tabFLeft">#{images_total}</td>
|
||||
<td class="tabFLeft">#{files_total}</td>
|
||||
<td class="tabFRight">#{used_total}</td>
|
||||
|
||||
@ -79,7 +79,8 @@ translations.en={
|
||||
"storage_usage_bar_graph_title": "Storage usage",
|
||||
"storage_usage_bar_graph_colname1": "Date",
|
||||
"storage_usage_bar_graph_colname2": "Storage usage",
|
||||
"validate_err_notregexp_cleanup_window": "Format for cleanup window wrong"
|
||||
"validate_err_notregexp_cleanup_window": "Format for cleanup window wrong",
|
||||
"mail_settings": "Mail"
|
||||
}
|
||||
translations.de={
|
||||
"action_1": "Inkrementelles Datei Backup",
|
||||
@ -168,7 +169,7 @@ translations.de={
|
||||
"tStorage allocation": "Speicherbelegung",
|
||||
"tImages": "Images",
|
||||
"tFiles": "Dateien",
|
||||
"tAll": "Gesamt",
|
||||
"tSum": "Gesamt",
|
||||
"tStorage usage": "Speichernutzungsverlauf",
|
||||
"tNo Users": "Keine Benutzer",
|
||||
"tRemove": "Löschen",
|
||||
@ -260,5 +261,26 @@ translations.de={
|
||||
"tServer identity": "Serveridentität",
|
||||
"tNondefault temporary file directory": "Vom Standard abweichender temporärer Dateiordner",
|
||||
"tCleanup time window": "Aufräum Zeitfenster",
|
||||
"validate_err_notregexp_cleanup_window": "Falsches Format für das Aufräum Zeitfenster"
|
||||
"validate_err_notregexp_cleanup_window": "Falsches Format für das Aufräum Zeitfenster",
|
||||
"mail_settings": "E-Mail",
|
||||
"tReports": "Reports",
|
||||
"tSend reports to": "Reports senden an",
|
||||
"tE-Mail addresses seperated by ';'": "E-Mail Adresssen getrennt durch ';'",
|
||||
"tSend": "Sende",
|
||||
"tBackups with a log message of at least log level": "Backups mit Benachrichtigungen mit wenigstens Wichtigkeit",
|
||||
"tFailed": "Fehlgeschlagene",
|
||||
"tSuccessfull": "Erfolgreiche",
|
||||
"tInfo": "Info",
|
||||
"tError": "Fehler",
|
||||
"tWarning": "Warnung",
|
||||
"tMail server name": "Mailserver name",
|
||||
"tMail server port": "Mailserver port",
|
||||
"tMail server username (empty for none)": "enutzername (leer für keinen)",
|
||||
"tMail server password": "Passwort",
|
||||
"tSender E-Mail Address": "Absender E-Mail Adresse",
|
||||
"tSend mails only with SSL/TLS": "E-Mails nur mit SSL/TLS Sicherung schicken",
|
||||
"tCheck SSL/TLS certificate": "SSL/TLS Zertifikat prüfen",
|
||||
"tSend test mail to this email address after saving the settings (leave empty to not send a test mail)": "Sende test E-Mail an diese Adresse nach speichern der Einstellungen (leer lassen um keine Test E-Mail zu senden)",
|
||||
"tTest Mail sent successfully": "Test E-Mail erfolgreich gesendet",
|
||||
"tSending test mail failed. Error:": "Senden der Test E-Mail fehlgeschlagen. Fehler:"
|
||||
}
|
||||
@ -169,6 +169,21 @@ function build_main_nav()
|
||||
I('main_nav').innerHTML=ndata;
|
||||
}
|
||||
|
||||
function getPar(p)
|
||||
{
|
||||
var obj=I(p);
|
||||
if(!obj) return "";
|
||||
if(obj.type=="checkbox" )
|
||||
{
|
||||
return "&"+p+"="+(obj.checked?"true":"false");
|
||||
}
|
||||
var val=obj.value;
|
||||
if(p=="update_freq_incr") val*=60*60;
|
||||
if(p=="update_freq_full" || p=="update_freq_image_full" || p=="update_freq_image_incr") val*=60*60*24;
|
||||
if(p=="startup_backup_delay") val*=60;
|
||||
return "&"+p+"="+encodeURIComponent(val+"");
|
||||
}
|
||||
|
||||
function show_progress1()
|
||||
{
|
||||
if(!startLoading()) return;
|
||||
@ -805,6 +820,7 @@ function show_settings2(data)
|
||||
var nav=data.navitems;
|
||||
var idx=0;
|
||||
g.user_nav_pos_offset=0;
|
||||
g.mail_nav_pos_offset=0;
|
||||
if(nav.general)
|
||||
{
|
||||
if(g.settings_nav_pos==idx)
|
||||
@ -817,6 +833,22 @@ function show_settings2(data)
|
||||
}
|
||||
++idx;
|
||||
++g.user_nav_pos_offset;
|
||||
++g.mail_nav_pos_offset;
|
||||
}
|
||||
if(nav.mail)
|
||||
{
|
||||
if(n!="" ) n+=" | ";
|
||||
|
||||
if(g.settings_nav_pos==idx)
|
||||
{
|
||||
n+="<strong>"+trans["mail_settings"]+"</strong>";
|
||||
}
|
||||
else
|
||||
{
|
||||
n+="<a href=\"javascript: mailSettings()\">"+trans["mail_settings"]+"</a>";
|
||||
}
|
||||
++idx;
|
||||
++g.user_nav_pos_offset;
|
||||
}
|
||||
if(nav.users)
|
||||
{
|
||||
@ -839,7 +871,7 @@ function show_settings2(data)
|
||||
|
||||
if(nav.clients.length>0)
|
||||
{
|
||||
n+=" | ";
|
||||
if(n!="") n+=" | ";
|
||||
n+="<select size=\"1\" style=\"width: 150px\" onchange=\"clientSettings()\" id=\"settingsclient\">";
|
||||
if(g.settings_nav_pos<idx)
|
||||
{
|
||||
@ -923,6 +955,31 @@ function show_settings2(data)
|
||||
ndata+=tmpls.settings_save_ok.evaluate();
|
||||
}
|
||||
}
|
||||
else if(data.sa=="mail")
|
||||
{
|
||||
if(data.settings.mail_ssl_only) data.settings.mail_ssl_only="checked=\"checked\"";
|
||||
else data.settings.mail_ssl_only="";
|
||||
if(data.settings.mail_check_certificate) data.settings.mail_check_certificate="checked=\"checked\"";
|
||||
else data.settings.mail_check_certificate="";
|
||||
|
||||
ndata+=tmpls.settings_mail.evaluate(data.settings);
|
||||
|
||||
if(data.saved_ok)
|
||||
{
|
||||
ndata+=tmpls.settings_save_ok.evaluate();
|
||||
}
|
||||
if(data.mail_test)
|
||||
{
|
||||
if(data.mail_test=="ok")
|
||||
{
|
||||
ndata+=tmpls.settings_mail_test_ok.evaluate();
|
||||
}
|
||||
else
|
||||
{
|
||||
ndata+=tmpls.settings_mail_test_failed.evaluate({mail_err: data.mail_test});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(data.sa=="listusers")
|
||||
{
|
||||
if(data.add_ok)
|
||||
@ -994,20 +1051,6 @@ function show_settings2(data)
|
||||
updateUserOverwrite();
|
||||
}
|
||||
}
|
||||
function getPar(p)
|
||||
{
|
||||
var obj=I(p);
|
||||
if(!obj) return "";
|
||||
if(obj.type=="checkbox" )
|
||||
{
|
||||
return "&"+p+"="+(obj.checked?"true":"false");
|
||||
}
|
||||
var val=obj.value;
|
||||
if(p=="update_freq_incr") val*=60*60;
|
||||
if(p=="update_freq_full" || p=="update_freq_image_full" || p=="update_freq_image_incr") val*=60*60*24;
|
||||
if(p=="startup_backup_delay") val*=60;
|
||||
return "&"+p+"="+encodeURIComponent(val+"");
|
||||
}
|
||||
|
||||
g.settings_list=[
|
||||
"update_freq_incr",
|
||||
@ -1029,6 +1072,15 @@ g.settings_list=[
|
||||
"exclude_files",
|
||||
"default_dirs"
|
||||
];
|
||||
g.mail_settings_list=[
|
||||
"mail_servername",
|
||||
"mail_serverport",
|
||||
"mail_username",
|
||||
"mail_password",
|
||||
"mail_from",
|
||||
"mail_ssl_only",
|
||||
"mail_check_certificateservername",
|
||||
];
|
||||
|
||||
function validateCommonSettings()
|
||||
{
|
||||
@ -1044,6 +1096,7 @@ function validateCommonSettings()
|
||||
|
||||
function saveGeneralSettings()
|
||||
{
|
||||
if(!startLoading()) return;
|
||||
if(!validate_text_nonempty(["backupfolder"]) ) return;
|
||||
if(!validate_text_int(["max_sim_backups", "max_active_clients"]) ) return;
|
||||
if(!validateCommonSettings() ) return;
|
||||
@ -1064,6 +1117,17 @@ function saveGeneralSettings()
|
||||
}
|
||||
new getJSON("settings", "sa=general_save"+pars, show_settings2);
|
||||
}
|
||||
function saveMailSettings()
|
||||
{
|
||||
if(!startLoading()) return;
|
||||
var pars="";
|
||||
for(var i=0;i<g.mail_settings_list.length;++i)
|
||||
{
|
||||
pars+=getPar(g.mail_settings_list[i]);
|
||||
}
|
||||
pars+=getPar("testmailaddr");
|
||||
new getJSON("settings", "sa=mail_save"+pars, show_settings2);
|
||||
}
|
||||
function clientSettings()
|
||||
{
|
||||
var selidx=I('settingsclient').selectedIndex;
|
||||
@ -1082,9 +1146,14 @@ function generalSettings()
|
||||
g.settings_nav_pos=0;
|
||||
new getJSON("settings", "sa=general", show_settings2);
|
||||
}
|
||||
function mailSettings()
|
||||
{
|
||||
if(!startLoading()) return;
|
||||
g.settings_nav_pos=g.mail_nav_pos_offset;
|
||||
new getJSON("settings", "sa=mail", show_settings2);
|
||||
}
|
||||
function updateUserOverwrite(clientid)
|
||||
{
|
||||
|
||||
var checked=I('overwrite').checked;
|
||||
|
||||
for(var i=0;i<g.settings_list.length;++i)
|
||||
@ -1501,6 +1570,19 @@ function submitChangeUserRights(uid)
|
||||
new getJSON("settings", "sa=updaterights&userid="+uid+"&rights="+generateRightsParam(rights), show_settings2);
|
||||
}
|
||||
|
||||
function saveReportSettings()
|
||||
{
|
||||
if(!startLoading()) return;
|
||||
clearTimeout(g.refresh_timeout);
|
||||
|
||||
var params="d=d";
|
||||
params+=getPar("report_mail");
|
||||
params+=getPar("report_sendonly");
|
||||
params+=getPar("report_loglevel");
|
||||
|
||||
new getJSON("logs", params, show_logs2);
|
||||
}
|
||||
|
||||
function show_logs1(params)
|
||||
{
|
||||
if(!startLoading()) return;
|
||||
@ -1586,7 +1668,20 @@ function show_logs2(data)
|
||||
if(data.logs.length==0)
|
||||
rows=tmpls.logs_none.evaluate();
|
||||
|
||||
ndata+=tmpls.logs_table.evaluate({ rows:rows });
|
||||
|
||||
var sel="selected=\"selected\"";
|
||||
|
||||
var td={};
|
||||
td.rows=rows;
|
||||
td.report_mail=data.report_mail;
|
||||
td.sel_all=(data.report_sendonly==0)?sel:"";
|
||||
td.sel_failed=(data.report_sendonly==1)?sel:"";
|
||||
td.sel_succ=(data.report_sendonly==2)?sel:"";
|
||||
td.sel_info=(data.report_loglevel==0)?sel:"";
|
||||
td.sel_warn=(data.report_loglevel==1)?sel:"";
|
||||
td.sel_error=(data.report_loglevel==2)?sel:"";
|
||||
|
||||
ndata+=tmpls.logs_table.evaluate(td);
|
||||
}
|
||||
|
||||
if(data.log)
|
||||
@ -1610,6 +1705,11 @@ function show_logs2(data)
|
||||
ndata+=tmpls.log_single.evaluate({rows:rows, name: data.log.clientname, params: params});
|
||||
}
|
||||
|
||||
if(data.saved_ok)
|
||||
{
|
||||
ndata+=tmpls.settings_save_ok.evaluate();
|
||||
}
|
||||
|
||||
if(g.data_f!=ndata)
|
||||
{
|
||||
I('data_f').innerHTML=ndata;
|
||||
|
||||
0
urlplugin/AUTHORS
Normal file
0
urlplugin/AUTHORS
Normal file
674
urlplugin/COPYING
Normal file
674
urlplugin/COPYING
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
3
urlplugin/ChangeLog
Normal file
3
urlplugin/ChangeLog
Normal file
@ -0,0 +1,3 @@
|
||||
Please see
|
||||
http://www.urbackup.org
|
||||
for Changelog
|
||||
28
urlplugin/IUrlFactory.h
Normal file
28
urlplugin/IUrlFactory.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef IURLFACTORY_H
|
||||
#define IURLFACTORY_H
|
||||
|
||||
#include "../Interface/Plugin.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct MailServer
|
||||
{
|
||||
MailServer(void) : port(22), ssl_only(false), check_certificate(true) {}
|
||||
std::string servername;
|
||||
unsigned short port;
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string mailfrom;
|
||||
bool ssl_only;
|
||||
bool check_certificate;
|
||||
};
|
||||
|
||||
class IUrlFactory : public IPlugin
|
||||
{
|
||||
public:
|
||||
virtual bool sendMail(const MailServer &server, const std::vector<std::string> &to,
|
||||
const std::string &subject, const std::string &message, std::string *errmsg=NULL)=0;
|
||||
};
|
||||
|
||||
#endif //IURLFACTORY_H
|
||||
6
urlplugin/Makefile.am
Normal file
6
urlplugin/Makefile.am
Normal file
@ -0,0 +1,6 @@
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
lib_LTLIBRARIES = liburbackupserver_urlplugin.la
|
||||
liburbackupserver_urlplugin_la_SOURCES = dllmain.cpp ../stringtools.cpp pluginmgr.cpp UrlFactory.cpp
|
||||
noinst_HEADERS = IUrlFactory.h pluginmgr.h UrlFactory.h
|
||||
AM_CXXFLAGS = -DLINUX $(LIBCURL_CPPFLAGS)
|
||||
AM_LDFLAGS = $(LIBCURL)
|
||||
3
urlplugin/NEWS
Normal file
3
urlplugin/NEWS
Normal file
@ -0,0 +1,3 @@
|
||||
Please see
|
||||
http://www.urbackup.org
|
||||
for Changelog
|
||||
0
urlplugin/README
Normal file
0
urlplugin/README
Normal file
87
urlplugin/UrlFactory.cpp
Normal file
87
urlplugin/UrlFactory.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "UrlFactory.h"
|
||||
#include "../Interface/Server.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "../stringtools.h"
|
||||
|
||||
struct RDUserS
|
||||
{
|
||||
RDUserS(void) : pos(0) {}
|
||||
size_t pos;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
struct RDUserS *pooh = (struct RDUserS*)userp;
|
||||
const char *data;
|
||||
|
||||
if(size*nmemb < 1)
|
||||
return 0;
|
||||
|
||||
if(pooh->pos<pooh->text.size())
|
||||
{
|
||||
data = &pooh->text[pooh->pos];
|
||||
|
||||
size_t len = (std::min)(pooh->text.size()-pooh->pos, size*nmemb);
|
||||
memcpy(ptr, data, len);
|
||||
pooh->pos+=len;
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool UrlFactory::sendMail(const MailServer &server, const std::vector<std::string> &to,
|
||||
const std::string &subject, const std::string &message, std::string *errmsg)
|
||||
{
|
||||
CURL *curl=curl_easy_init();
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, ("smtp://"+server.servername+":"+nconvert(server.port)).c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, server.ssl_only?CURLUSESSL_ALL:CURLUSESSL_TRY);
|
||||
if(!server.check_certificate)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, server.username.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, server.password.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, server.mailfrom.c_str());
|
||||
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
|
||||
curl_slist * recpt=NULL;
|
||||
for(size_t i=0;i<to.size();++i)
|
||||
{
|
||||
recpt=curl_slist_append(recpt, to[i].c_str());
|
||||
}
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recpt);
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
RDUserS rd;
|
||||
std::string header;
|
||||
header+="From: "+server.mailfrom+"\n"
|
||||
"Subject: "+subject+"\n"
|
||||
"\n";
|
||||
rd.text=header+message;
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &rd);
|
||||
std::string errbuf;
|
||||
errbuf.resize(CURL_ERROR_SIZE*2);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, (char*)errbuf.c_str());
|
||||
CURLcode res= curl_easy_perform(curl);
|
||||
if(res!=0)
|
||||
{
|
||||
errbuf.resize(strlen(errbuf.c_str()));
|
||||
if(errmsg==NULL)
|
||||
{
|
||||
Server->Log("Error during cURL operation occured. ec="+nconvert(res)+" -- "+errbuf, LL_DEBUG);
|
||||
}
|
||||
else
|
||||
{
|
||||
*errmsg="ec="+nconvert(res)+" -- "+errbuf;
|
||||
}
|
||||
curl_slist_free_all(recpt);
|
||||
curl_easy_cleanup(curl);
|
||||
return false;
|
||||
}
|
||||
curl_slist_free_all(recpt);
|
||||
curl_easy_cleanup(curl);
|
||||
return true;
|
||||
}
|
||||
8
urlplugin/UrlFactory.h
Normal file
8
urlplugin/UrlFactory.h
Normal file
@ -0,0 +1,8 @@
|
||||
#include "IUrlFactory.h"
|
||||
|
||||
class UrlFactory : public IUrlFactory
|
||||
{
|
||||
public:
|
||||
virtual bool sendMail(const MailServer &server, const std::vector<std::string> &to,
|
||||
const std::string &subject, const std::string &message, std::string *errmsg=NULL);
|
||||
};
|
||||
33
urlplugin/configure.ac
Normal file
33
urlplugin/configure.ac
Normal file
@ -0,0 +1,33 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT([urbackupserver_urlplugin], [0.1], [urpc@gmx.de])
|
||||
AC_CONFIG_SRCDIR([dllmain.cpp])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CC
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
# Checks for libraries.
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([stdlib.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_HEADER_STDBOOL
|
||||
AC_C_CONST
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
LIBCURL_CHECK_CONFIG(,[7.20.0],,[
|
||||
AC_MSG_ERROR([Your system lacks of libcurl >= 7.20.0])
|
||||
])
|
||||
|
||||
# Checks for library functions.
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
53
urlplugin/dllmain.cpp
Normal file
53
urlplugin/dllmain.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*************************************************************************
|
||||
* UrBackup - Client/Server backup system
|
||||
* Copyright (C) 2011 Martin Raiber
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
**************************************************************************/
|
||||
|
||||
#include "../vld.h"
|
||||
#ifdef _WIN32
|
||||
#define DLLEXPORT extern "C" __declspec (dllexport)
|
||||
#else
|
||||
#define DLLEXPORT extern "C"
|
||||
#endif
|
||||
|
||||
|
||||
#define DEF_SERVER
|
||||
#include "../Interface/Server.h"
|
||||
#include "../Interface/Action.h"
|
||||
#include "../stringtools.h"
|
||||
|
||||
#include "pluginmgr.h"
|
||||
#include "IUrlFactory.h"
|
||||
|
||||
IServer *Server;
|
||||
|
||||
CUrlPluginMgr *urlpluginmgr=NULL;
|
||||
|
||||
|
||||
DLLEXPORT void LoadActions(IServer* pServer)
|
||||
{
|
||||
Server=pServer;
|
||||
|
||||
urlpluginmgr=new CUrlPluginMgr;
|
||||
|
||||
Server->RegisterPluginThreadsafeModel( urlpluginmgr, "url");
|
||||
|
||||
Server->Log("Loaded -url- plugin", LL_INFO);
|
||||
}
|
||||
|
||||
DLLEXPORT void UnloadActions(void)
|
||||
{
|
||||
}
|
||||
250
urlplugin/m4/libcurl.m4
Normal file
250
urlplugin/m4/libcurl.m4
Normal file
@ -0,0 +1,250 @@
|
||||
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
|
||||
# [ACTION-IF-YES], [ACTION-IF-NO])
|
||||
# ----------------------------------------------------------
|
||||
# David Shaw <dshaw@jabberwocky.com> May-09-2006
|
||||
#
|
||||
# Checks for libcurl. DEFAULT-ACTION is the string yes or no to
|
||||
# specify whether to default to --with-libcurl or --without-libcurl.
|
||||
# If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the
|
||||
# minimum version of libcurl to accept. Pass the version as a regular
|
||||
# version number like 7.10.1. If not supplied, any version is
|
||||
# accepted. ACTION-IF-YES is a list of shell commands to run if
|
||||
# libcurl was successfully found and passed the various tests.
|
||||
# ACTION-IF-NO is a list of shell commands that are run otherwise.
|
||||
# Note that using --without-libcurl does run ACTION-IF-NO.
|
||||
#
|
||||
# This macro #defines HAVE_LIBCURL if a working libcurl setup is
|
||||
# found, and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary
|
||||
# values. Other useful defines are LIBCURL_FEATURE_xxx where xxx are
|
||||
# the various features supported by libcurl, and LIBCURL_PROTOCOL_yyy
|
||||
# where yyy are the various protocols supported by libcurl. Both xxx
|
||||
# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of
|
||||
# the macro for the complete list of possible defines. Shell
|
||||
# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also
|
||||
# defined to 'yes' for those features and protocols that were found.
|
||||
# Note that xxx and yyy keep the same capitalization as in the
|
||||
# curl-config list (e.g. it's "HTTP" and not "http").
|
||||
#
|
||||
# Users may override the detected values by doing something like:
|
||||
# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure
|
||||
#
|
||||
# For the sake of sanity, this macro assumes that any libcurl that is
|
||||
# found is after version 7.7.2, the first version that included the
|
||||
# curl-config script. Note that it is very important for people
|
||||
# packaging binary versions of libcurl to include this script!
|
||||
# Without curl-config, we can only guess what protocols are available,
|
||||
# or use curl_version_info to figure it out at runtime.
|
||||
|
||||
AC_DEFUN([LIBCURL_CHECK_CONFIG],
|
||||
[
|
||||
AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL])
|
||||
AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4])
|
||||
AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6])
|
||||
AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz])
|
||||
AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS])
|
||||
AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN])
|
||||
AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI])
|
||||
AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM])
|
||||
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_RTSP],[Defined if libcurl supports RTSP])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_POP3],[Defined if libcurl supports POP3])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_IMAP],[Defined if libcurl supports IMAP])
|
||||
AH_TEMPLATE([LIBCURL_PROTOCOL_SMTP],[Defined if libcurl supports SMTP])
|
||||
|
||||
AC_ARG_WITH(libcurl,
|
||||
AC_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]),
|
||||
[_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])])
|
||||
|
||||
if test "$_libcurl_with" != "no" ; then
|
||||
|
||||
AC_PROG_AWK
|
||||
|
||||
_libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'"
|
||||
|
||||
_libcurl_try_link=yes
|
||||
|
||||
if test -d "$_libcurl_with" ; then
|
||||
LIBCURL_CPPFLAGS="-I$withval/include"
|
||||
_libcurl_ldflags="-L$withval/lib"
|
||||
AC_PATH_PROG([_libcurl_config],[curl-config],[],
|
||||
["$withval/bin"])
|
||||
else
|
||||
AC_PATH_PROG([_libcurl_config],[curl-config],[],[$PATH])
|
||||
fi
|
||||
|
||||
if test x$_libcurl_config != "x" ; then
|
||||
AC_CACHE_CHECK([for the version of libcurl],
|
||||
[libcurl_cv_lib_curl_version],
|
||||
[libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`])
|
||||
|
||||
_libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse`
|
||||
_libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse`
|
||||
|
||||
if test $_libcurl_wanted -gt 0 ; then
|
||||
AC_CACHE_CHECK([for libcurl >= version $2],
|
||||
[libcurl_cv_lib_version_ok],
|
||||
[
|
||||
if test $_libcurl_version -ge $_libcurl_wanted ; then
|
||||
libcurl_cv_lib_version_ok=yes
|
||||
else
|
||||
libcurl_cv_lib_version_ok=no
|
||||
fi
|
||||
])
|
||||
fi
|
||||
|
||||
if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then
|
||||
if test x"$LIBCURL_CPPFLAGS" = "x" ; then
|
||||
LIBCURL_CPPFLAGS=`$_libcurl_config --cflags`
|
||||
fi
|
||||
if test x"$LIBCURL" = "x" ; then
|
||||
LIBCURL=`$_libcurl_config --libs`
|
||||
|
||||
# This is so silly, but Apple actually has a bug in their
|
||||
# curl-config script. Fixed in Tiger, but there are still
|
||||
# lots of Panther installs around.
|
||||
case "${host}" in
|
||||
powerpc-apple-darwin7*)
|
||||
LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'`
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# All curl-config scripts support --feature
|
||||
_libcurl_features=`$_libcurl_config --feature`
|
||||
|
||||
# Is it modern enough to have --protocols? (7.12.4)
|
||||
if test $_libcurl_version -ge 461828 ; then
|
||||
_libcurl_protocols=`$_libcurl_config --protocols`
|
||||
fi
|
||||
else
|
||||
_libcurl_try_link=no
|
||||
fi
|
||||
|
||||
unset _libcurl_wanted
|
||||
fi
|
||||
|
||||
if test $_libcurl_try_link = yes ; then
|
||||
|
||||
# we didn't find curl-config, so let's see if the user-supplied
|
||||
# link line (or failing that, "-lcurl") is enough.
|
||||
LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"}
|
||||
|
||||
AC_CACHE_CHECK([whether libcurl is usable],
|
||||
[libcurl_cv_lib_curl_usable],
|
||||
[
|
||||
_libcurl_save_cppflags=$CPPFLAGS
|
||||
CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS"
|
||||
_libcurl_save_libs=$LIBS
|
||||
LIBS="$LIBCURL $LIBS"
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <curl/curl.h>],[
|
||||
/* Try and use a few common options to force a failure if we are
|
||||
missing symbols or can't link. */
|
||||
int x;
|
||||
curl_easy_setopt(NULL,CURLOPT_URL,NULL);
|
||||
x=CURL_ERROR_SIZE;
|
||||
x=CURLOPT_WRITEFUNCTION;
|
||||
x=CURLOPT_FILE;
|
||||
x=CURLOPT_ERRORBUFFER;
|
||||
x=CURLOPT_STDERR;
|
||||
x=CURLOPT_VERBOSE;
|
||||
])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
|
||||
|
||||
CPPFLAGS=$_libcurl_save_cppflags
|
||||
LIBS=$_libcurl_save_libs
|
||||
unset _libcurl_save_cppflags
|
||||
unset _libcurl_save_libs
|
||||
])
|
||||
|
||||
if test $libcurl_cv_lib_curl_usable = yes ; then
|
||||
|
||||
# Does curl_free() exist in this version of libcurl?
|
||||
# If not, fake it with free()
|
||||
|
||||
_libcurl_save_cppflags=$CPPFLAGS
|
||||
CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS"
|
||||
_libcurl_save_libs=$LIBS
|
||||
LIBS="$LIBS $LIBCURL"
|
||||
|
||||
AC_CHECK_FUNC(curl_free,,
|
||||
AC_DEFINE(curl_free,free,
|
||||
[Define curl_free() as free() if our version of curl lacks curl_free.]))
|
||||
|
||||
CPPFLAGS=$_libcurl_save_cppflags
|
||||
LIBS=$_libcurl_save_libs
|
||||
unset _libcurl_save_cppflags
|
||||
unset _libcurl_save_libs
|
||||
|
||||
AC_DEFINE(HAVE_LIBCURL,1,
|
||||
[Define to 1 if you have a functional curl library.])
|
||||
AC_SUBST(LIBCURL_CPPFLAGS)
|
||||
AC_SUBST(LIBCURL)
|
||||
|
||||
for _libcurl_feature in $_libcurl_features ; do
|
||||
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1])
|
||||
eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes
|
||||
done
|
||||
|
||||
if test "x$_libcurl_protocols" = "x" ; then
|
||||
|
||||
# We don't have --protocols, so just assume that all
|
||||
# protocols are available
|
||||
_libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT TFTP"
|
||||
|
||||
if test x$libcurl_feature_SSL = xyes ; then
|
||||
_libcurl_protocols="$_libcurl_protocols HTTPS"
|
||||
|
||||
# FTPS wasn't standards-compliant until version
|
||||
# 7.11.0 (0x070b00 == 461568)
|
||||
if test $_libcurl_version -ge 461568; then
|
||||
_libcurl_protocols="$_libcurl_protocols FTPS"
|
||||
fi
|
||||
fi
|
||||
|
||||
# RTSP, IMAP, POP3 and SMTP were added in
|
||||
# 7.20.0 (0x071400 == 463872)
|
||||
if test $_libcurl_version -ge 463872; then
|
||||
_libcurl_protocols="$_libcurl_protocols RTSP IMAP POP3 SMTP"
|
||||
fi
|
||||
fi
|
||||
|
||||
for _libcurl_protocol in $_libcurl_protocols ; do
|
||||
AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1])
|
||||
eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes
|
||||
done
|
||||
else
|
||||
unset LIBCURL
|
||||
unset LIBCURL_CPPFLAGS
|
||||
fi
|
||||
fi
|
||||
|
||||
unset _libcurl_try_link
|
||||
unset _libcurl_version_parse
|
||||
unset _libcurl_config
|
||||
unset _libcurl_feature
|
||||
unset _libcurl_features
|
||||
unset _libcurl_protocol
|
||||
unset _libcurl_protocols
|
||||
unset _libcurl_version
|
||||
unset _libcurl_ldflags
|
||||
fi
|
||||
|
||||
if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then
|
||||
# This is the IF-NO path
|
||||
ifelse([$4],,:,[$4])
|
||||
else
|
||||
# This is the IF-YES path
|
||||
ifelse([$3],,:,[$3])
|
||||
fi
|
||||
|
||||
unset _libcurl_with
|
||||
])dnl
|
||||
33
urlplugin/pluginmgr.cpp
Normal file
33
urlplugin/pluginmgr.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*************************************************************************
|
||||
* UrBackup - Client/Server backup system
|
||||
* Copyright (C) 2011 Martin Raiber
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
**************************************************************************/
|
||||
|
||||
#include "../vld.h"
|
||||
#include "pluginmgr.h"
|
||||
#include "UrlFactory.h"
|
||||
|
||||
IPlugin *CUrlPluginMgr::createPluginInstance(str_map ¶ms)
|
||||
{
|
||||
return new UrlFactory();
|
||||
}
|
||||
|
||||
void CUrlPluginMgr::destroyPluginInstance(IPlugin *plugin)
|
||||
{
|
||||
UrlFactory *s=(UrlFactory*)plugin;
|
||||
delete s;
|
||||
}
|
||||
|
||||
8
urlplugin/pluginmgr.h
Normal file
8
urlplugin/pluginmgr.h
Normal file
@ -0,0 +1,8 @@
|
||||
#include "../Interface/PluginMgr.h"
|
||||
|
||||
class CUrlPluginMgr : public IPluginMgr
|
||||
{
|
||||
public:
|
||||
IPlugin *createPluginInstance(str_map ¶ms);
|
||||
void destroyPluginInstance(IPlugin *plugin);
|
||||
};
|
||||
154
urlplugin/urlplugin.vcxproj
Normal file
154
urlplugin/urlplugin.vcxproj
Normal file
@ -0,0 +1,154 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{3E6BBB51-77D4-4DC7-BF09-FC6F21CA04D5}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>urlplugin</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>./lib64/inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>./lib64</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>libcurl.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="IUrlFactory.h" />
|
||||
<ClInclude Include="pluginmgr.h" />
|
||||
<ClInclude Include="UrlFactory.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\stringtools.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="pluginmgr.cpp" />
|
||||
<ClCompile Include="UrlFactory.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
42
urlplugin/urlplugin.vcxproj.filters
Normal file
42
urlplugin/urlplugin.vcxproj.filters
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="IUrlFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pluginmgr.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UrlFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pluginmgr.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UrlFactory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\stringtools.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Reference in New Issue
Block a user