diff --git a/DBSettingsReader.cpp b/DBSettingsReader.cpp index a880885d..0ba4ab97 100644 --- a/DBSettingsReader.cpp +++ b/DBSettingsReader.cpp @@ -48,6 +48,11 @@ CDBSettingsReader::CDBSettingsReader(IDatabase *pDB, const std::string &pTable, bool CDBSettingsReader::getValue(std::string key, std::string *value) { + if(query==NULL) + { + return false; + } + query->Bind(key); db_nresults res=query->ReadN(); query->Reset(); @@ -63,6 +68,11 @@ bool CDBSettingsReader::getValue(std::string key, std::string *value) bool CDBSettingsReader::getValue(std::wstring key, std::wstring *value) { + if(query==NULL) + { + return false; + } + query->Bind(key); db_results res=query->Read(); query->Reset(); diff --git a/Database.cpp b/Database.cpp index 12c172b7..b0f2d9a0 100644 --- a/Database.cpp +++ b/Database.cpp @@ -233,7 +233,7 @@ IQuery* CDatabase::Prepare(std::string pQuery, bool autodestroy) if(!WaitForUnlock()) Server->Log("DATABASE DEADLOCKED in CDatabase::Prepare", LL_ERROR); } - } + } else { if(transaction_lock==false) @@ -260,6 +260,16 @@ IQuery* CDatabase::Prepare(std::string pQuery, bool autodestroy) if( err!=SQLITE_OK ) { Server->Log("Error preparing Query ["+pQuery+"]: "+sqlite3_errmsg(db),LL_ERROR); + + if(err==SQLITE_IOERR) + { + Server->setFailBit(IServer::FAIL_DATABASE_IOERR); + } + if(err==SQLITE_CORRUPT) + { + Server->setFailBit(IServer::FAIL_DATABASE_CORRUPTED); + } + return NULL; } CQuery *q=new CQuery(pQuery, prepared_statement, this); diff --git a/DatabaseCursor.cpp b/DatabaseCursor.cpp index 37f8d2ef..fd60537d 100644 --- a/DatabaseCursor.cpp +++ b/DatabaseCursor.cpp @@ -4,7 +4,7 @@ #include "Server.h" DatabaseCursor::DatabaseCursor(CQuery *query, int *timeoutms) - : query(query), transaction_lock(false), tries(60), timeoutms(timeoutms), lastErr(0), _has_error(false) + : query(query), transaction_lock(false), tries(60), timeoutms(timeoutms), lastErr(SQLITE_OK), _has_error(false) { query->setupStepping(timeoutms); } @@ -17,18 +17,17 @@ DatabaseCursor::~DatabaseCursor(void) bool DatabaseCursor::next(db_single_result &res) { res.clear(); - int rc; do { - rc=query->step(res, timeoutms, tries, transaction_lock); - if(rc==SQLITE_ROW) + lastErr=query->step(res, timeoutms, tries, transaction_lock); + if(lastErr==SQLITE_ROW) { return true; } } - while(query->resultOkay(rc)); + while(query->resultOkay(lastErr)); - if(rc!=SQLITE_OK && rc!=SQLITE_DONE) + if(lastErr!=SQLITE_DONE) { Server->Log("SQL Error: "+query->getErrMsg()+ " Stmt: ["+query->getStatement()+"]", LL_ERROR); _has_error=true; diff --git a/Interface/Server.h b/Interface/Server.h index 80cf224a..a4beb87a 100644 --- a/Interface/Server.h +++ b/Interface/Server.h @@ -168,6 +168,13 @@ public: virtual unsigned int getSecureRandomNumber(void)=0; virtual std::vector getSecureRandomNumbers(size_t n)=0; virtual void secureRandomFill(char *buf, size_t blen)=0; + + static const size_t FAIL_DATABASE_CORRUPTED=1; + static const size_t FAIL_DATABASE_IOERR=2; + + virtual void setFailBit(size_t failbit)=0; + virtual void clearFailBit(size_t failbit)=0; + virtual size_t getFailBits(void)=0; }; #ifndef NO_INTERFACE diff --git a/Query.cpp b/Query.cpp index 0ffa1636..594fc370 100644 --- a/Query.cpp +++ b/Query.cpp @@ -50,6 +50,11 @@ CQuery::~CQuery() if( err!=SQLITE_OK && err!=SQLITE_BUSY && err!=SQLITE_IOERR_BLOCKED ) Server->Log("SQL: "+(std::string)sqlite3_errmsg(db->getDatabase())+ " Stmt: ["+stmt_str+"]", LL_ERROR); + if( err==SQLITE_IOERR ) + { + Server->setFailBit(IServer::FAIL_DATABASE_IOERR); + } + delete cursor; } @@ -219,6 +224,15 @@ bool CQuery::Execute(int timeoutms) return false; } + if( err==SQLITE_IOERR ) + { + Server->setFailBit(IServer::FAIL_DATABASE_IOERR); + } + if(err==SQLITE_CORRUPT) + { + Server->setFailBit(IServer::FAIL_DATABASE_CORRUPTED); + } + return true; } @@ -249,6 +263,15 @@ void CQuery::shutdownStepping(int err, int *timeoutms, bool& transaction_lock) sqlite3_busy_timeout(db->getDatabase(), 50); db->UnlockForTransaction(); } + + if(err==SQLITE_IOERR) + { + Server->setFailBit(IServer::FAIL_DATABASE_IOERR); + } + if(err==SQLITE_CORRUPT) + { + Server->setFailBit(IServer::FAIL_DATABASE_CORRUPTED); + } } db_nresults CQuery::ReadN(int *timeoutms) diff --git a/Server.cpp b/Server.cpp index c96e91b8..c13c0973 100644 --- a/Server.cpp +++ b/Server.cpp @@ -98,6 +98,7 @@ CServer::CServer() circular_log_buffer_id=0; circular_log_buffer_idx=0; has_circular_log_buffer=false; + failbits=0; startup_complete=false; @@ -1719,4 +1720,19 @@ void CServer::logToCircularBuffer(const std::string& msg, int loglevel) entry.time=Server->getTimeSeconds(); circular_log_buffer_idx=(circular_log_buffer_idx+1)%circular_log_buffer.size(); +} + +void CServer::setFailBit(size_t failbit) +{ + failbits=failbits|failbit; +} + +void CServer::clearFailBit(size_t failbit) +{ + failbits=failbit & (~failbit); +} + +size_t CServer::getFailBits(void) +{ + return failbits; } \ No newline at end of file diff --git a/Server.h b/Server.h index e1e000cd..783eb4ae 100644 --- a/Server.h +++ b/Server.h @@ -169,6 +169,11 @@ public: virtual unsigned int getSecureRandomNumber(void); virtual std::vector getSecureRandomNumbers(size_t n); virtual void secureRandomFill(char *buf, size_t blen); + + virtual void setFailBit(size_t failbit); + virtual void clearFailBit(size_t failbit); + virtual size_t getFailBits(void); + private: void logToCircularBuffer(const std::string& msg, int loglevel); @@ -255,6 +260,8 @@ private: size_t circular_log_buffer_idx; bool has_circular_log_buffer; + + size_t failbits; }; #ifndef DEF_SERVER diff --git a/urbackupclient/ClientServiceCMD.cpp b/urbackupclient/ClientServiceCMD.cpp index bd26e142..f7624662 100644 --- a/urbackupclient/ClientServiceCMD.cpp +++ b/urbackupclient/ClientServiceCMD.cpp @@ -1074,7 +1074,7 @@ void ClientConnector::CMD_CAPA(const std::string &cmd) #else std::string os_version_str="not Windows"; tcpstack.Send(pipe, "FILE=2&FILESRV=2&SET_SETTINGS=1&CLIENTUPDATE=1" - "&CLIENT_VERSION_STR="+EscapeParamString(client_version_str)+"&OS_VERSION_STR="+EscapeParamString(client_version_str)); + "&CLIENT_VERSION_STR="+EscapeParamString(client_version_str)+"&OS_VERSION_STR="+EscapeParamString(os_version_str)); #endif } diff --git a/urbackupserver/FileCache.h b/urbackupserver/FileCache.h index 6bf2ec09..7eba5f2e 100644 --- a/urbackupserver/FileCache.h +++ b/urbackupserver/FileCache.h @@ -10,7 +10,7 @@ class FileCache : public IThread { public: - typedef db_results(*get_data_callback_t)(void *userdata); + typedef db_results(*get_data_callback_t)(int, void *userdata); struct SCacheValue { diff --git a/urbackupserver/MDBFileCache.cpp b/urbackupserver/MDBFileCache.cpp index d1eda9e3..cca7111f 100644 --- a/urbackupserver/MDBFileCache.cpp +++ b/urbackupserver/MDBFileCache.cpp @@ -90,7 +90,7 @@ void MDBFileCache::create(get_data_callback_t get_data_callback, void *userdata) db_results res; do { - res=get_data_callback(userdata); + res=get_data_callback(n_done, userdata); for(size_t i=0;igetDatabase(Server->getThreadID(), URBACKUPDB_SERVER); IQuery *q=db->Prepare("UPDATE misc SET tvalue=? WHERE tkey='files_cache'"); - - q->Bind(new_type); - q->Write(); + if(q!=NULL) + { + q->Bind(new_type); + q->Write(); + } } struct SCallbackData { IDatabaseCursor* cur; int64 pos; + SStartupStatus* status; }; -db_results create_callback(void *userdata) +db_results create_callback(int n_done, void *userdata) { SCallbackData *data=(SCallbackData*)userdata; + data->status->processed_file_entries=n_done; db_results ret; db_single_result res; @@ -54,7 +59,7 @@ db_results create_callback(void *userdata) return ret; } -bool create_files_cache_common(FileCache& filecache) +bool create_files_cache_common(FileCache& filecache, SStartupStatus& status) { IDatabase *db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER); @@ -65,6 +70,7 @@ bool create_files_cache_common(FileCache& filecache) db->Write("PRAGMA cache_size = -"+nconvert(500*1024)); } + status.creating_filescache=true; Server->Log("Creating file entry cache. This might take a while...", LL_WARNING); IQuery *q_read=db->Prepare("SELECT shahash, filesize, fullpath, hashpath FROM files ORDER BY shahash ASC, filesize ASC, created DESC"); @@ -72,6 +78,7 @@ bool create_files_cache_common(FileCache& filecache) SCallbackData data; data.cur=q_read->Cursor(); data.pos=0; + data.status=&status; filecache.create(create_callback, &data); @@ -81,6 +88,8 @@ bool create_files_cache_common(FileCache& filecache) db->Write("PRAGMA shrink_memory"); } + status.creating_filescache=false; + if(data.cur->has_error()) { return false; @@ -89,7 +98,7 @@ bool create_files_cache_common(FileCache& filecache) return true; } -bool setup_lmdb_files_cache(size_t map_size) +bool setup_lmdb_files_cache(size_t map_size, SStartupStatus& status) { MDBFileCache filecache(map_size); if(filecache.has_error()) @@ -98,10 +107,10 @@ bool setup_lmdb_files_cache(size_t map_size) return false; } - return create_files_cache_common(filecache); + return create_files_cache_common(filecache, status); } -bool setup_sqlite_files_cache(void) +bool setup_sqlite_files_cache(SStartupStatus& status) { os_create_dir(L"urbackup/cache"); @@ -118,7 +127,7 @@ bool setup_sqlite_files_cache(void) SQLiteFileCache filecache; - return create_files_cache_common(filecache); + return create_files_cache_common(filecache, status); } } @@ -133,7 +142,7 @@ void delete_file_caches(void) } -void create_files_cache(void) +void create_files_cache(SStartupStatus& status) { IDatabase *db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER); ServerSettings settings(db); @@ -144,7 +153,7 @@ void create_files_cache(void) { delete_file_caches(); - if(!setup_lmdb_files_cache(static_cast(settings.getSettings()->filescache_size))) + if(!setup_lmdb_files_cache(static_cast(settings.getSettings()->filescache_size), status)) { Server->Log("Setting up files cache failed", LL_ERROR); } @@ -154,7 +163,7 @@ void create_files_cache(void) delete_file_caches(); update_files_cache_type("none"); - if(!setup_lmdb_files_cache(static_cast(settings.getSettings()->filescache_size))) + if(!setup_lmdb_files_cache(static_cast(settings.getSettings()->filescache_size), status)) { Server->Log("Setting up files cache failed", LL_ERROR); } @@ -169,7 +178,7 @@ void create_files_cache(void) { delete_file_caches(); - if(!setup_sqlite_files_cache()) + if(!setup_sqlite_files_cache(status)) { Server->Log("Setting up files cache failed", LL_ERROR); has_error=true; @@ -180,7 +189,7 @@ void create_files_cache(void) delete_file_caches(); update_files_cache_type("none"); - if(!setup_sqlite_files_cache()) + if(!setup_sqlite_files_cache(status)) { Server->Log("Setting up files cache failed", LL_ERROR); has_error=true; diff --git a/urbackupserver/create_files_cache.h b/urbackupserver/create_files_cache.h index ea0a1766..79449b4b 100644 --- a/urbackupserver/create_files_cache.h +++ b/urbackupserver/create_files_cache.h @@ -1,6 +1,7 @@ class FileCache; +struct SStartupStatus; -void create_files_cache(void); +void create_files_cache(SStartupStatus& status); FileCache* create_lmdb_files_cache(void); diff --git a/urbackupserver/dllmain.cpp b/urbackupserver/dllmain.cpp index c5f1e0c7..f43cfde2 100644 --- a/urbackupserver/dllmain.cpp +++ b/urbackupserver/dllmain.cpp @@ -390,6 +390,7 @@ DLLEXPORT void LoadActions(IServer* pServer) ADD_ACTION(login); ADD_ACTION(google_chart); + ADD_ACTION(generate_templ); upgrade(); @@ -416,7 +417,7 @@ DLLEXPORT void LoadActions(IServer* pServer) } ServerUpdateStats::createFilesIndices(); - create_files_cache(); + create_files_cache(startup_status); { IScopedLock lock(startup_status.mutex); @@ -469,7 +470,6 @@ DLLEXPORT void LoadActions(IServer* pServer) ADD_ACTION(server_status); ADD_ACTION(progress); ADD_ACTION(salt); - ADD_ACTION(generate_templ); ADD_ACTION(lastacts); ADD_ACTION(piegraph); ADD_ACTION(usagegraph); @@ -996,6 +996,10 @@ void upgrade(void) db->Import("urbackup/backup_server.dat"); qp=db->Prepare("SELECT tvalue FROM misc WHERE tkey='db_version'"); } + if(qp==NULL) + { + return; + } db_results res_v=qp->Read(); if(res_v.empty()) return; diff --git a/urbackupserver/server.cpp b/urbackupserver/server.cpp index 17308fe0..cdb73b3c 100644 --- a/urbackupserver/server.cpp +++ b/urbackupserver/server.cpp @@ -155,25 +155,27 @@ void BackupServer::operator()(void) void BackupServer::findClients(FileClient &fc) { - db_results res=q_get_extra_hostnames->Read(); - q_get_extra_hostnames->Reset(); - std::vector addr_hints; - - for(size_t i=0;iConvertToUTF8(res[i][L"hostname"]), &dest); - if(b) - { - q_update_extra_ip->Bind((_i64)dest); - q_update_extra_ip->Bind(res[i][L"id"]); - q_update_extra_ip->Write(); - q_update_extra_ip->Reset(); + db_results res=q_get_extra_hostnames->Read(); + q_get_extra_hostnames->Reset(); - in_addr tmp; - tmp.s_addr=dest; - addr_hints.push_back(tmp); + for(size_t i=0;iConvertToUTF8(res[i][L"hostname"]), &dest); + if(b) + { + q_update_extra_ip->Bind((_i64)dest); + q_update_extra_ip->Bind(res[i][L"id"]); + q_update_extra_ip->Write(); + q_update_extra_ip->Reset(); + + in_addr tmp; + tmp.s_addr=dest; + addr_hints.push_back(tmp); + } } } diff --git a/urbackupserver/server_archive.cpp b/urbackupserver/server_archive.cpp index 6a841dd8..a04be3e9 100644 --- a/urbackupserver/server_archive.cpp +++ b/urbackupserver/server_archive.cpp @@ -31,10 +31,13 @@ void ServerAutomaticArchive::operator()(void) void ServerAutomaticArchive::archiveTimeout(void) { IQuery *q_timeout=db->Prepare("SELECT id FROM backups WHERE archived=1 AND archive_timeout<>0 AND archive_timeoutBind(Server->getTimeSeconds()); db_results res_timeout=q_timeout->Read(); IQuery *q_unarchive=db->Prepare("UPDATE backups SET archived=0 WHERE id=?"); + if(q_unarchive==NULL) return; for(size_t i=0;iBind(res_timeout[i][L"id"]); diff --git a/urbackupserver/server_cleanup.cpp b/urbackupserver/server_cleanup.cpp index aef35ba4..2138efd7 100644 --- a/urbackupserver/server_cleanup.cpp +++ b/urbackupserver/server_cleanup.cpp @@ -1152,28 +1152,39 @@ void ServerCleanupThread::backup_database(void) if(settings.getSettings()->backup_database) { - std::wstring bfolder=settings.getSettings()->backupfolder+os_file_sep()+L"urbackup"; - if(!os_directory_exists(bfolder) ) - { - os_create_dir(bfolder); - } - else - { - rename(Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server.db").c_str(), Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server.db~").c_str() ); - rename(Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server_settings.db").c_str(), Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server_settings.db~").c_str() ); - } + db_results res = db->Read("PRAGMA integrity_check"); - Server->Log("Starting database backup...", LL_INFO); - bool b=db->Backup(Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server.db")); - Server->Log("Database backup done.", LL_INFO); - if(!b) + Server->Log("Checking database integrity...", LL_INFO); + if(!res.empty() && res[0][L"integrity_check"]==L"ok") { - Server->Log("Backing up database failed", LL_ERROR); + std::wstring bfolder=settings.getSettings()->backupfolder+os_file_sep()+L"urbackup"; + if(!os_directory_exists(bfolder) ) + { + os_create_dir(bfolder); + } + else + { + rename(Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server.db").c_str(), Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server.db~").c_str() ); + rename(Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server_settings.db").c_str(), Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server_settings.db~").c_str() ); + } + + Server->Log("Starting database backup...", LL_INFO); + bool b=db->Backup(Server->ConvertToUTF8(bfolder+os_file_sep()+L"backup_server.db")); + Server->Log("Database backup done.", LL_INFO); + if(!b) + { + Server->Log("Backing up database failed", LL_ERROR); + } + else + { + Server->deleteFile(bfolder+os_file_sep()+L"backup_server.db~"); + Server->deleteFile(bfolder+os_file_sep()+L"backup_server_settings.db~"); + } } else { - Server->deleteFile(bfolder+os_file_sep()+L"backup_server.db~"); - Server->deleteFile(bfolder+os_file_sep()+L"backup_server_settings.db~"); + Server->Log("Database integrity check failed. Skipping Database backup.", LL_ERROR); + Server->setFailBit(IServer::FAIL_DATABASE_CORRUPTED); } } } diff --git a/urbackupserver/server_get.cpp b/urbackupserver/server_get.cpp index dcf2442a..9d43b560 100644 --- a/urbackupserver/server_get.cpp +++ b/urbackupserver/server_get.cpp @@ -59,7 +59,8 @@ const unsigned int check_time_intervall=5*60*1000; const unsigned int status_update_intervall=1000; const size_t minfreespace_min=50*1024*1024; const unsigned int curr_image_version=1; -const unsigned int ident_err_retry_time=10*60*1000; +const unsigned int ident_err_retry_time=1*60*1000; +const unsigned int ident_err_retry_time_retok=10*60*1000; const unsigned int c_filesrv_connect_timeout=10000; const unsigned int c_internet_fileclient_timeout=30*60*1000; @@ -181,14 +182,25 @@ void BackupServerGet::operator ()(void) while(c) { c=false; - bool b=sendClientMessage("ADD IDENTITY", "OK", L"Sending Identity to client \""+clientname+L"\" failed. Retrying in 10min...", 10000, false, LL_INFO); + bool retok_err=false; + bool b=sendClientMessage("ADD IDENTITY", "OK", L"Sending Identity to client \""+clientname+L"\" failed. Retrying soon...", 10000, false, LL_INFO, &retok_err); if(!b) { - ServerStatus::setWrongIdent(clientname, true); + if(retok_err) + { + ServerStatus::setWrongIdent(clientname, true); + } + + unsigned int retry_time=ident_err_retry_time; + + if(retok_err) + { + retry_time=ident_err_retry_time_retok; + } c=true; std::string msg; - pipe->Read(&msg, ident_err_retry_time); + pipe->Read(&msg, retry_time); if(msg=="exit" || msg=="exitnow") { pipe->Write("ok"); @@ -199,6 +211,10 @@ void BackupServerGet::operator ()(void) return; } } + else + { + ServerStatus::setWrongIdent(clientname, false); + } } } @@ -854,6 +870,8 @@ int BackupServerGet::getClientID(IDatabase *db, const std::wstring &clientname, *new_client=false; IQuery *q=db->Prepare("SELECT id FROM clients WHERE name=?",false); + if(q==NULL) return -1; + q->Bind(clientname); db_results res=q->Read(); db->destroyQuery(q); @@ -2771,7 +2789,7 @@ std::string BackupServerGet::sendClientMessage(const std::string &msg, const std return ""; } -bool BackupServerGet::sendClientMessage(const std::string &msg, const std::string &retok, const std::wstring &errmsg, unsigned int timeout, bool logerr, int max_loglevel) +bool BackupServerGet::sendClientMessage(const std::string &msg, const std::string &retok, const std::wstring &errmsg, unsigned int timeout, bool logerr, int max_loglevel, bool *retok_err) { CTCPStack tcpstack(internet_connection); IPipe *cc=getClientCommandConnection(10000); @@ -2816,6 +2834,10 @@ bool BackupServerGet::sendClientMessage(const std::string &msg, const std::strin ServerLogger::Log(clientid, errmsg, max_loglevel); else Server->Log(errmsg, max_loglevel); + + if(retok_err!=NULL) + *retok_err=true; + break; } else @@ -3014,6 +3036,12 @@ bool BackupServerGet::getClientSettings(void) { std::wstring &key=setting_names[i]; std::wstring value; + + if(internet_connection && key==L"computername") + { + continue; + } + if(sr->getValue(key, &value) ) { bool b=updateClientSetting(key, value); diff --git a/urbackupserver/server_get.h b/urbackupserver/server_get.h index 7b1ed3ce..6ba6eb6a 100644 --- a/urbackupserver/server_get.h +++ b/urbackupserver/server_get.h @@ -40,7 +40,7 @@ public: void operator()(void); - bool sendClientMessage(const std::string &msg, const std::string &retok, const std::wstring &errmsg, unsigned int timeout, bool logerr=true, int max_loglevel=LL_ERROR); + bool sendClientMessage(const std::string &msg, const std::string &retok, const std::wstring &errmsg, unsigned int timeout, bool logerr=true, int max_loglevel=LL_ERROR, bool *retok_err=NULL); std::string sendClientMessage(const std::string &msg, const std::wstring &errmsg, unsigned int timeout, bool logerr=true, int max_loglevel=LL_ERROR); void sendToPipe(const std::string &msg); int getPCDone(void); diff --git a/urbackupserver/server_settings.cpp b/urbackupserver/server_settings.cpp index ef19b83d..ac5fdc3c 100644 --- a/urbackupserver/server_settings.cpp +++ b/urbackupserver/server_settings.cpp @@ -146,7 +146,7 @@ void ServerSettings::readSettingsDefault(void) settings.backupfolder=trim(settings_default->getValue(L"backupfolder", L"C:\\urbackup")); settings.backupfolder_uncompr=trim(settings_default->getValue(L"backupfolder_uncompr", settings.backupfolder)); settings.client_overwrite=true; - settings.autoshutdown=false; + settings.autoshutdown=(settings_default->getValue("autoshutdown", "false")=="true");; settings.startup_backup_delay=settings_default->getValue("startup_backup_delay", 0); settings.download_client=(settings_default->getValue("download_client", "true")=="true"); settings.autoupdate_clients=(settings_default->getValue("autoupdate_clients", "true")=="true"); diff --git a/urbackupserver/serverinterface/helper.h b/urbackupserver/serverinterface/helper.h index 12f01c0e..3d0fefc7 100644 --- a/urbackupserver/serverinterface/helper.h +++ b/urbackupserver/serverinterface/helper.h @@ -54,11 +54,15 @@ private: struct SStartupStatus { SStartupStatus(void) - : upgrading_database(false) {} + : upgrading_database(false), + creating_filescache(false) {} bool upgrading_database; int curr_db_version; int target_db_version; + bool creating_filescache; + size_t processed_file_entries; + IMutex *mutex; }; \ No newline at end of file diff --git a/urbackupserver/serverinterface/login.cpp b/urbackupserver/serverinterface/login.cpp index 95c9650f..9f376149 100644 --- a/urbackupserver/serverinterface/login.cpp +++ b/urbackupserver/serverinterface/login.cpp @@ -26,7 +26,16 @@ ACTION_IMPL(login) { IScopedLock lock(startup_status.mutex); - if(startup_status.upgrading_database) + if(startup_status.creating_filescache) + { + Helper helper(tid, &GET, &PARAMS); + ret.set("lang", helper.getLanguage()); + ret.set("creating_filescache", startup_status.creating_filescache); + ret.set("processed_file_entries", startup_status.processed_file_entries); + Server->Write( tid, ret.get(false) ); + return; + } + else if(startup_status.upgrading_database) { Helper helper(tid, &GET, &PARAMS); ret.set("lang", helper.getLanguage()); @@ -97,7 +106,7 @@ ACTION_IMPL(login) { ret.set("lang", helper.getLanguage()); db_results res=db->Read("SELECT count(*) AS c FROM settings_db.si_users"); - if(watoi(res[0][L"c"])>0) + if(!res.empty() && watoi(res[0][L"c"])>0) { ret.set("success", JSON::Value(false) ); } diff --git a/urbackupserver/serverinterface/status.cpp b/urbackupserver/serverinterface/status.cpp index 27b52d16..6adbb2db 100644 --- a/urbackupserver/serverinterface/status.cpp +++ b/urbackupserver/serverinterface/status.cpp @@ -148,6 +148,12 @@ ACTION_IMPL(status) { ret.set("nospc_fatal" ,true); } + + if( (Server->getFailBits() & IServer::FAIL_DATABASE_CORRUPTED) || + (Server->getFailBits() & IServer::FAIL_DATABASE_IOERR) ) + { + ret.set("database_error", true); + } } bool details=false; @@ -175,7 +181,7 @@ ACTION_IMPL(status) q->Reset(); } } - if(GET.find(L"clientname")!=GET.end()) + if(GET.find(L"clientname")!=GET.end() && helper.getRights("add_client")=="all" ) { bool new_client=false; int id=BackupServerGet::getClientID(db, GET[L"clientname"], NULL, &new_client); diff --git a/urbackupserver/serverinterface/templ.cpp b/urbackupserver/serverinterface/templ.cpp index d10effc1..107d4c5b 100644 --- a/urbackupserver/serverinterface/templ.cpp +++ b/urbackupserver/serverinterface/templ.cpp @@ -102,6 +102,8 @@ ACTION_IMPL(generate_templ) templates.push_back("new_version_available"); templates.push_back("live_log"); templates.push_back("live_log_row"); + templates.push_back("database_error"); + templates.push_back("file_cache_error"); IFile *out=Server->openFile("urbackupserver/www/templates.js", MODE_WRITE); if(out==NULL) diff --git a/urbackupserver/www/templates.js b/urbackupserver/www/templates.js index 3a69614a..b117136d 100644 --- a/urbackupserver/www/templates.js +++ b/urbackupserver/www/templates.js @@ -9,7 +9,7 @@ tmpls.lastacts_row=new Template("\r\n\t#{id}\r\n tmpls.stat_general=new Template("

#{tStorage allocation}

\r\n\r\n
#{tLoading}...

\r\n\r\n\r\n\t\t\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\r\n#{rows}\r\n\r\n\t\r\n\r\n\r\n\t\r\n\t\r\n\t\r\n\t\r\n\r\n
#{tComputer name}#{tImages}#{tFiles}#{tAll}
#{tSum}#{images_total}#{files_total}#{used_total}
\r\n\r\n
\r\n\r\n\r\n

#{tStorage usage}

\r\n\r\n
#{tLoading}...
"); tmpls.stat_general_row=new Template("\r\n\t#{name}\r\n\t#{images}\r\n\t#{files}\r\n\t#{used}\r\n"); tmpls.stat_user=new Template("

#{tStorage usage of} #{clientname}

\r\n\r\n
#{tLoading}...
"); -tmpls.status=new Template("\r\n

#{tBackup status}

\r\n\r\n#{nospc_fatal}\r\n#{nospc_stalled}\r\n#{dir_error}\r\n#{tmpdir_error}\r\n\r\n#{modify_clients_top}\r\n#{dtl_c1_top}\r\n| #{tShow details}

\r\n#{dtl_c2_top}\r\n\r\n\t\t\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t#{dlt_mod_start}\r\n\t\r\n\t#{dlt_mod_end}\r\n\r\n#{rows}\r\n
#{tComputer name}#{tLast seen}#{tLast file backup}#{tLast image backup}#{tFile backup status}#{tImage backup status} 
\r\n
\r\n#{modify_clients}\r\n#{dtl_c1}\r\n| #{tShow details}\r\n#{dtl_c2}\r\n#{status_client_download}"); +tmpls.status=new Template("\r\n

#{tBackup status}

\r\n\r\n#{nospc_fatal}\r\n#{nospc_stalled}\r\n#{dir_error}\r\n#{tmpdir_error}\r\n#{database_error}\r\n\r\n#{modify_clients_top}\r\n#{dtl_c1_top}\r\n| #{tShow details}

\r\n#{dtl_c2_top}\r\n\r\n\t\t\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t#{dlt_mod_start}\r\n\t\r\n\t#{dlt_mod_end}\r\n\r\n#{rows}\r\n
#{tComputer name}#{tLast seen}#{tLast file backup}#{tLast image backup}#{tFile backup status}#{tImage backup status} 
\r\n
\r\n#{modify_clients}\r\n#{dtl_c1}\r\n| #{tShow details}\r\n#{dtl_c2}\r\n#{status_client_download}"); tmpls.status_row=new Template("\r\n\t#{name}\r\n\t#{lastseen}\r\n\t#{lastbackup}#{start_file_backup}\r\n\t#{lastbackup_image}#{start_image_backup}\r\n\t
#{file_ok_t}
\r\n\t
#{image_ok_t}
\r\n\t#{dtl_c1}\r\n\t\r\n\t#{dtl_c2}\r\n"); tmpls.backups_clients=new Template("#{tClients}

\r\n\r\n\r\n\r\n\t\r\n\t\r\n\t\r\n\r\n#{rows}\r\n
 #{tComputer name}#{tLast file backup}
"); tmpls.backups_clients_row=new Template("\r\n\t \r\n\t#{name}\r\n\t#{lastbackup}\r\n"); @@ -39,9 +39,9 @@ tmpls.log_single_none=new Template("\n\t\n\t\n\t\n\t\n"); tmpls.logs_filter=new Template(""); tmpls.logs_none=new Template("\r\n\t#{tNo entries for this filter}\r\n"); -tmpls.dir_error=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
\r\n
"); -tmpls.tmpdir_error=new Template("
#{tdir_error_text}#{ext_text}
\r\n\t\t\t\r\n\t\r\n\r\n
#{ttmpdir_error_text}
\r\n
\r\n
"); -tmpls.status_detail=new Template("\r\n

#{tBackup status}

\r\n\r\n#{dir_error}\r\n#{tmpdir_error}\r\n\r\n\r\n\t\t\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n#{Actions_start}\r\n\t\r\n#{rows}\r\n
#{tComputer name}#{tOnline}#{tStatus}#{tLast seen}#{tLast file backup}#{tLast image backup}#{tFile backup status}#{tImage backup status}#{tIP}#{tClient version}#{tOperating System} \r\n#{Actions_end}\r\n
\r\n
\r\n#{modify_clients}\r\n
\r\n#{status_client_download}\r\n

#{tExtra clients}

\r\n\r\n\r\n\t\t\t\r\n\t\r\n\t\r\n\t\r\n\r\n#{extra_clients_rows}\r\n
#{tHostname/IP}#{tOnline}#{tActions}
\r\n\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n
#{tHostname/IP}:
\r\n
\n
\r\n

#{tInternet clients}

\r\n
\r\n#{internet_client_added}\r\n#{tAdd additional internet clients}:\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n
#{tClient name}:
\r\n
\n

#{tServer identity}

\n#{server_identity}\n
"); +tmpls.dir_error=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
\r\n
"); +tmpls.tmpdir_error=new Template("
#{dir_error_text}#{ext_text}
\r\n\t\t\t\r\n\t\r\n\r\n
#{tmpdir_error_text}
\r\n
\r\n
"); +tmpls.status_detail=new Template("\r\n

#{tBackup status}

\r\n\r\n#{nospc_fatal}\r\n#{nospc_stalled}\r\n#{dir_error}\r\n#{tmpdir_error}\r\n#{database_error}\r\n\r\n\r\n\t\t\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n#{Actions_start}\r\n\t\r\n#{rows}\r\n
#{tComputer name}#{tOnline}#{tStatus}#{tLast seen}#{tLast file backup}#{tLast image backup}#{tFile backup status}#{tImage backup status}#{tIP}#{tClient version}#{tOperating System} \r\n#{Actions_end}\r\n
\r\n
\r\n#{modify_clients}\r\n
\r\n#{status_client_download}\r\n

#{tExtra clients}

\r\n\r\n\r\n\t\t\t\r\n\t\r\n\t\r\n\t\r\n\r\n#{extra_clients_rows}\r\n
#{tHostname/IP}#{tOnline}#{tActions}
\r\n\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n
#{tHostname/IP}:
\r\n
\n
\r\n

#{tInternet clients}

\r\n
\r\n#{internet_client_added}\r\n#{tAdd additional internet clients}:\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n
#{tClient name}:
\r\n
\n

#{tServer identity}

\n#{server_identity}\n
"); tmpls.status_detail_extra_empty=new Template("\r\n\t#{tNo extra clients}\r\n"); tmpls.status_detail_extra_row=new Template("\r\n\t#{hostname}\r\n\t#{online}\r\n\t\r\n"); tmpls.status_detail_row=new Template("\r\n\t#{name}\r\n\t#{online}\r\n\t#{status}\r\n\t#{lastseen}\r\n\t#{lastbackup}#{start_file_backup}\r\n\t#{lastbackup_image}#{start_image_backup}\r\n\t
#{file_ok_t}
\r\n\t
#{image_ok_t}
\r\n\t#{ip}\r\n\t#{client_version_string}\r\n\t#{os_version_string}\r\n#{dtl_c1}\r\n\t\r\n#{dtl_c2}\r\n"); @@ -49,17 +49,19 @@ tmpls.status_row_delete_pending=new Template("\n\t#{n tmpls.settings_mail=new Template("
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
#{tMail server name}:
#{tMail server port}:
#{tMail server username (empty for none)}:
#{tMail server password}:
#{tSender E-Mail Address}:
#{tSend mails only with SSL/TLS}:
#{tCheck SSL/TLS certificate}:
#{tServer admin mail address}:
\r\n
\r\n
\r\n\r\n
\r\n#{tSend test mail to this email address after saving the settings (leave empty to not send a test mail)}:
\r\n\r\n"); tmpls.settings_mail_test_ok=new Template("
\r\n
\r\n#{tTest Mail sent successfully}."); tmpls.settings_mail_test_failed=new Template("
\r\n
\r\n#{tSending test mail failed. Error:} #{mail_err}"); -tmpls.upgrade_error=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
\r\n\t#{tupgrade_error_text}
\r\n\t#{tCurrent version}: #{curr_db_version}
\r\n\t#{tTarget version}: #{target_db_version}\r\n\t
\r\n
\r\n
"); +tmpls.upgrade_error=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
\r\n\t#{upgrade_error_text}
\r\n\t#{tCurrent version}: #{curr_db_version}
\r\n\t#{tTarget version}: #{target_db_version}\r\n\t
\r\n
\r\n
"); tmpls.logs_report_mail=new Template("#{report_single_mail}[-], "); tmpls.settings_archive_row=new Template("\r\n\r\n\r\n\r\n#{archive_every}\r\n\r\n\r\n\r\n\r\n#{archive_for}\r\n\r\n\r\n\r\n#{archive_window}\r\n\r\n\r\n#{archive_backup_type_str}\r\n\r\n#{next_start}\r\n\r\n #{archive_timeleft}\r\n\r\n#{next_end}\r\n"); tmpls.status_modify_clients=new Template("#{tSelect all} | \r\n#{tSelect none} | \r\n#{rem_start}\r\n#{tRemove selected} | \r\n#{rem_stop}\r\n\r\n\t#{tStart for selected}"); tmpls.change_pw=new Template("
\r\n
\r\n#{tChange password}\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
#{tOld password}:
#{tNew password}:
#{tRepeat new password}:
\r\n
\r\n
\r\n\r\n
"); tmpls.change_pw_ok=new Template("
\r\n#{tChanged password successfully}"); tmpls.change_pw_fail=new Template("
\r\n#{tChanging password failed:}
\r\n#{fail_reason}"); -tmpls.nospc_stalled=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
#{tnospc_stalled_text}
\r\n
\r\n
"); -tmpls.nospc_fatal=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
#{tnospc_fatal_text}
\r\n
\r\n
"); +tmpls.nospc_stalled=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
#{nospc_stalled_text}
\r\n
\r\n
"); +tmpls.nospc_fatal=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
#{nospc_fatal_text}
\r\n
\r\n
"); tmpls.status_percent_done=new Template("
\r\n\t
\r\n\t
\r\n
"); tmpls.status_client_download=new Template("

#{tClient download}

\r\n\r\n\r\n"); tmpls.new_version_available=new Template("#{tThere is a new version of UrBackup server available} (#{new_version_number}). Download it here.

"); tmpls.live_log=new Template("\r\n\r\n#{tUrBackup live log:} #{clientname}\r\n\r\n\r\n\r\n\r\n\r\n\r\n
 
\r\n\r\n\r\n
\r\n\r\n\r\n "); tmpls.live_log_row=new Template("\r\n\t#{time}  \r\n\t#{loglevel}  \r\n\t#{message}\r\n"); +tmpls.database_error=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
#{database_error_text}
\r\n
\r\n
"); +tmpls.file_cache_error=new Template("\r\n\t\t\t\r\n\t\r\n\r\n
\r\n\t#{creating_filescache_text}
\r\n\t#{tNumber of file entries processed}: #{processed_file_entries}\r\n\t
\r\n
\r\n
"); diff --git a/urbackupserver/www/templates/database_error.htm b/urbackupserver/www/templates/database_error.htm new file mode 100644 index 00000000..88beb8b1 --- /dev/null +++ b/urbackupserver/www/templates/database_error.htm @@ -0,0 +1,7 @@ + + + + +
#{database_error_text}
+
+
\ No newline at end of file diff --git a/urbackupserver/www/templates/dir_error.htm b/urbackupserver/www/templates/dir_error.htm index 5bc1bd30..c280db8b 100644 --- a/urbackupserver/www/templates/dir_error.htm +++ b/urbackupserver/www/templates/dir_error.htm @@ -1,6 +1,6 @@ - +

\ No newline at end of file diff --git a/urbackupserver/www/templates/file_cache_error.htm b/urbackupserver/www/templates/file_cache_error.htm new file mode 100644 index 00000000..02d96868 --- /dev/null +++ b/urbackupserver/www/templates/file_cache_error.htm @@ -0,0 +1,10 @@ +
#{tdir_error_text}#{ext_text}#{dir_error_text}#{ext_text}
+ + + +
+ #{creating_filescache_text}
+ #{tNumber of file entries processed}: #{processed_file_entries} +
+
+
\ No newline at end of file diff --git a/urbackupserver/www/templates/nospc_fatal.htm b/urbackupserver/www/templates/nospc_fatal.htm index 9f2f4fb0..0d5df3a2 100644 --- a/urbackupserver/www/templates/nospc_fatal.htm +++ b/urbackupserver/www/templates/nospc_fatal.htm @@ -1,6 +1,6 @@ - +
#{tnospc_fatal_text}#{nospc_fatal_text}

diff --git a/urbackupserver/www/templates/nospc_stalled.htm b/urbackupserver/www/templates/nospc_stalled.htm index 91917f40..f8c30103 100644 --- a/urbackupserver/www/templates/nospc_stalled.htm +++ b/urbackupserver/www/templates/nospc_stalled.htm @@ -1,6 +1,6 @@ - +
#{tnospc_stalled_text}#{nospc_stalled_text}

diff --git a/urbackupserver/www/templates/status.htm b/urbackupserver/www/templates/status.htm index 485ed333..9dfebff2 100644 --- a/urbackupserver/www/templates/status.htm +++ b/urbackupserver/www/templates/status.htm @@ -5,6 +5,7 @@ #{nospc_stalled} #{dir_error} #{tmpdir_error} +#{database_error} #{modify_clients_top} #{dtl_c1_top} diff --git a/urbackupserver/www/templates/status_detail.htm b/urbackupserver/www/templates/status_detail.htm index b9e88917..e7834af8 100644 --- a/urbackupserver/www/templates/status_detail.htm +++ b/urbackupserver/www/templates/status_detail.htm @@ -1,8 +1,11 @@

#{tBackup status}

+#{nospc_fatal} +#{nospc_stalled} #{dir_error} #{tmpdir_error} +#{database_error} diff --git a/urbackupserver/www/templates/tmpdir_error.htm b/urbackupserver/www/templates/tmpdir_error.htm index 99de1d4e..101cc2ba 100644 --- a/urbackupserver/www/templates/tmpdir_error.htm +++ b/urbackupserver/www/templates/tmpdir_error.htm @@ -1,6 +1,6 @@
- +
#{ttmpdir_error_text}#{tmpdir_error_text}

diff --git a/urbackupserver/www/templates/upgrade_error.htm b/urbackupserver/www/templates/upgrade_error.htm index ef934884..97b6b02e 100644 --- a/urbackupserver/www/templates/upgrade_error.htm +++ b/urbackupserver/www/templates/upgrade_error.htm @@ -1,7 +1,7 @@ diff --git a/urbackupserver/www/translation.js b/urbackupserver/www/translation.js index 6878d4c1..93a7e167 100644 --- a/urbackupserver/www/translation.js +++ b/urbackupserver/www/translation.js @@ -44,8 +44,8 @@ translations.en={ "loglevel_0": "Info", "loglevel_1": "Warnings", "loglevel_2": "Errors", -"tdir_error_text": "The directory where UrBackup will save backups is inaccessible. Please fix that by modifying this folder in 'Settings' or by giving UrBackup rights to access this directory.", -"ttmpdir_error_text": "The directory where UrBackup will save temporary files is inaccessible. Please fix that by modifying this folder in 'Settings' or by giving UrBackup rights to access this directory.", +"dir_error_text": "The directory where UrBackup will save backups is inaccessible. Please fix that by modifying this folder in 'Settings' or by giving UrBackup rights to access this directory.", +"tmpdir_error_text": "The directory where UrBackup will save temporary files is inaccessible. Please fix that by modifying this folder in 'Settings' or by giving UrBackup rights to access this directory.", "starting": "Starting", "ident_err": "Server rejected", "enter_hostname": "Please enter a hostname or IP address", @@ -81,7 +81,7 @@ translations.en={ "storage_usage_bar_graph_colname2": "Storage usage", "validate_err_notregexp_cleanup_window": "Format for cleanup window wrong", "mail_settings": "Mail", -"tupgrade_error_text": "UrBackup is upgrading its internal database. This may take a while. The server is inaccessible and will not do any backups during this upgrade.", +"upgrade_error_text": "UrBackup is upgrading its internal database. This may take a while. The server is inaccessible and will not do any backups during this upgrade.", "file_backup": "File backup", "hours": "hours", "days": "days", @@ -117,9 +117,11 @@ translations.en={ "internet_client_added": "Added new client. You can see the client's auth key (or password) in the settings.", "change_pw": "Change password", "old_pw_wrong": "Old password is wrong", -"tnospc_stalled_text": "There is currently not enough free space in the backup folder. UrBackup is deleting old image and file backups to free space, within the limits defined by the settings. During this process the backup performance is descreased and backups are stalled.", -"tnospc_fatal_text": "There is currently not enough free space in the backup folder. UrBackup tried to delete old image and file backups but is now not allowed to delete more. Please change the settings to store less backups or increase the storage amount to allow UrBackup to continue to perform backups", -"really_recalculate": "Do you really want to recalculate all statistics? This might take a long time!" +"nospc_stalled_text": "There is currently not enough free space in the backup folder. UrBackup is deleting old image and file backups to free space, within the limits defined by the settings. During this process the backup performance is descreased and backups are stalled.", +"nospc_fatal_text": "There is currently not enough free space in the backup folder. UrBackup tried to delete old image and file backups but is now not allowed to delete more. Please change the settings to store less backups or increase the storage amount to allow UrBackup to continue to perform backups", +"really_recalculate": "Do you really want to recalculate all statistics? This might take a long time!", +"database_error_text": "An error occured while accessing or checking UrBackup's internal database. This means this database is probably damaged or there is not enough free space. If this error persists, please restore the database (the files urbackup_server.db and urbackup_server_settings.db) from a backup. See log file for details.", +"creating_filescache_text": "UrBackup is creating the file entry chache. This might take a while." } translations.de={ "action_1": "Inkrementelles Datei Backup", @@ -251,8 +253,8 @@ translations.de={ "tBackup storage path": "Speicherort für Backups", "tDo not do image backups": "Keine Imagebackups ausführen", "tAutomatically shut down server": "Server automatisch herunterfahren", -"tdir_error_text": "Auf das Verzeichnis in dem UrBackup die Backups speichern soll kann nicht zugegriffen werden. Bitte verändern Sie in den Einstellungen das Verzeichnis oder geben Sie UrBackup Zugriffsrechte.", -"ttmpdir_error_text": "Auf das Verzeichnis in dem UrBackup die temporären Dateien speichern soll kann nicht zugegriffen werden. Bitte verändern Sie in den Einstellungen das Verzeichnis oder geben Sie UrBackup Zugriffsrechte.", +"dir_error_text": "Auf das Verzeichnis in dem UrBackup die Backups speichern soll kann nicht zugegriffen werden. Bitte verändern Sie in den Einstellungen das Verzeichnis oder geben Sie UrBackup Zugriffsrechte.", +"tmpdir_error_text": "Auf das Verzeichnis in dem UrBackup die temporären Dateien speichern soll kann nicht zugegriffen werden. Bitte verändern Sie in den Einstellungen das Verzeichnis oder geben Sie UrBackup Zugriffsrechte.", "starting": "Starte", "ident_err": "Server abgelehnt", "tNo extra clients": "Keine zusätzlichen Clients", @@ -328,7 +330,7 @@ translations.de={ "tAllow client-side pausing of backups": "Clients erlauben Backups zu pausieren", "tAutomatically backup UrBackup database": "Automatisch UrBackup Datenbank sichern", "tDo not do file backups": "Keine Dateibackups ausführen", -"tupgrade_error_text": "UrBackup aktualisiert seine interne Datenbank. Das könnte eine Weile dauern. Während der Aktualisierung ist das Webinterface nicht erreichbar und keine Backups werden durchgeführt.", +"upgrade_error_text": "UrBackup aktualisiert seine interne Datenbank. Das könnte eine Weile dauern. Während der Aktualisierung ist das Webinterface nicht erreichbar und keine Backups werden durchgeführt.", "tCurrent version": "Momentane version", "tTarget version": "Zielversion", "tVolumes to backup": "Zu sichernde Laufwerke", @@ -412,8 +414,8 @@ translations.de={ "tClients are removed during the cleanup time window, if they are offline.": "Clients werden in dem Aufräumzeitfenster gelöscht, falls sie nicht mehr online sind.", "tPerform autoupdates silently": "Autoupdates im Hintergrund ausführen", "tArchived": "Archiviert", -"tnospc_stalled_text": "Es is momentan nicht genügend Speicherplatz für Backups vorhanden. UrBackup löscht gerade alte Datei- und Image-Backups, innerhalb der Grenzen die in den Einstellungen festgelegt sind. Wärend dieses Vorgangs ist die Performanz des Backupservers eventuell eingeschränkt; Lauftende Backups sind eventuell pausiert.", -"tnospc_fatal_text": "Es is momentan nicht genügend Speicherplatz für Backups vorhanden. UrBackup hat versucht alte Datei- und Image-Backups zu löschen, kann aber jetzt nicht weiteren Speicherplatz freimachen. Bitte ändern Sie die Einstellungen insofern, dass weniger Backups gespeichert werden, oder fügen Sie weiteren Backupspeicher hinzu, so dass UrBackup weiterhin Backups durchführen kann." +"nospc_stalled_text": "Es is momentan nicht genügend Speicherplatz für Backups vorhanden. UrBackup löscht gerade alte Datei- und Image-Backups, innerhalb der Grenzen die in den Einstellungen festgelegt sind. Wärend dieses Vorgangs ist die Performanz des Backupservers eventuell eingeschränkt; Lauftende Backups sind eventuell pausiert.", +"nospc_fatal_text": "Es is momentan nicht genügend Speicherplatz für Backups vorhanden. UrBackup hat versucht alte Datei- und Image-Backups zu löschen, kann aber jetzt nicht weiteren Speicherplatz freimachen. Bitte ändern Sie die Einstellungen insofern, dass weniger Backups gespeichert werden, oder fügen Sie weiteren Backupspeicher hinzu, so dass UrBackup weiterhin Backups durchführen kann." } translations.ru={ "action_1": "Добавочный файловый бэкап", @@ -474,8 +476,8 @@ translations.ru={ "loglevel_0": "Инфо", "loglevel_1": "Предупреждения", "loglevel_2": "Ошибки", -"tdir_error_text": "Каталог, где UrBackup будет сохранять резервные копии недоступен. Пожалуйста исправьте это изменив путь в 'Настройках', либо путем придания UrBackup прав на доступ к этой папке.", -"ttmpdir_error_text": "Каталог, где UrBackup будет сохранять временные файлы недоступен. Пожалуйста исправьте это изменив путь в 'Настройках', либо путем придания UrBackup прав на доступ к этой папке.", +"dir_error_text": "Каталог, где UrBackup будет сохранять резервные копии недоступен. Пожалуйста исправьте это изменив путь в 'Настройках', либо путем придания UrBackup прав на доступ к этой папке.", +"tmpdir_error_text": "Каталог, где UrBackup будет сохранять временные файлы недоступен. Пожалуйста исправьте это изменив путь в 'Настройках', либо путем придания UrBackup прав на доступ к этой папке.", "starting": "Запуск", "ident_err": "Отклонено сервером", "enter_hostname": "Пожалуйста введите Имя компьютера или IP адрес", @@ -514,7 +516,7 @@ translations.ru={ "tSum": "Итого", "validate_err_notregexp_cleanup_window": "Формат расписания очистки неверен", "mail_settings": "Почта", -"tupgrade_error_text": "UrBackup обновляет свою базу данных. Это может занять некоторое время. Сервер недоступен и не будет делать никаких резервных копий во время обновления.", +"upgrade_error_text": "UrBackup обновляет свою базу данных. Это может занять некоторое время. Сервер недоступен и не будет делать никаких резервных копий во время обновления.", "tActivities": "В работе", "tAction": "Действие", "tProgress": "Прогресс", @@ -684,8 +686,8 @@ translations.es={ "loglevel_0": "Informativos", "loglevel_1": "Avisos", "loglevel_2": "Errores", -"tdir_error_text": "La carpeta designada para guardar las copias no está accesible. Por favor, solucione este problema modificando la carpeta en 'Ajustes' o garantizando a UrBackup privilegios de escritura en esa carpeta.", -"ttmpdir_error_text": "La carpeta en la que se guardan los archivos temporales no está accesible. Por favor, solucione este problema modificando la carpeta en 'Ajustes' o garantizando a UrBackup privilegios de escritura en esa carpeta.", +"dir_error_text": "La carpeta designada para guardar las copias no está accesible. Por favor, solucione este problema modificando la carpeta en 'Ajustes' o garantizando a UrBackup privilegios de escritura en esa carpeta.", +"tmpdir_error_text": "La carpeta en la que se guardan los archivos temporales no está accesible. Por favor, solucione este problema modificando la carpeta en 'Ajustes' o garantizando a UrBackup privilegios de escritura en esa carpeta.", "starting": "Comenzando", "ident_err": "Servidor rechazado", "enter_hostname": "Introduzca un nombre de nodo o una dirección IP", @@ -721,7 +723,7 @@ translations.es={ "storage_usage_bar_graph_colname2": "Uso de almacenamiento", "validate_err_notregexp_cleanup_window": "Formato de la ventana de limpieza erróneo", "mail_settings": "Correo-e", -"tupgrade_error_text": "UrBackup está actualizando su base de datos interna. Esto puede llevar cierto tiempo. El servidor estará inaccesible y sin hacer copias durante la actualización.", +"upgrade_error_text": "UrBackup está actualizando su base de datos interna. Esto puede llevar cierto tiempo. El servidor estará inaccesible y sin hacer copias durante la actualización.", "file_backup": "Copia de ficheros", "hours": "horas", "days": "días", @@ -842,8 +844,8 @@ translations.es={ "tBackup storage path": "Ruta de almacenamiento de las copias", "tDo not do image backups": "No haga copiaas imagen", "tAutomatically shut down server": "Apague automáticamente el servidor", -"tdir_error_text": "No se encuentra la carpeta de copias o no tiene permiso de escritura sobre ella.", -"ttmpdir_error_text": "No se encuentra la carpeta tempopral o no tiene permiso de escritura sobre ella.", +"dir_error_text": "No se encuentra la carpeta de copias o no tiene permiso de escritura sobre ella.", +"tmpdir_error_text": "No se encuentra la carpeta tempopral o no tiene permiso de escritura sobre ella.", "tNo extra clients": "No hay clientes extra", "tShow details": "Ver detalles", "tAutoupdate clients": "Actualizar los clientes automáticamente", @@ -881,7 +883,7 @@ translations.es={ "tAllow client-side pausing of backups": "Permitir al cliente pausar una copia", "tAutomatically backup UrBackup database": "Copiar automáticamente la base de datos de UrBackup", "tDo not do file backups": "No hacer copia de ficheros", -"tupgrade_error_text": "UrBackup aktualisiert seine interne Datenbank. Das könnte eine Weile dauern. Während der Aktualisierung ist das Webinterface nicht erreichbar und keine Backups werden durchgeführt.", +"upgrade_error_text": "UrBackup aktualisiert seine interne Datenbank. Das könnte eine Weile dauern. Während der Aktualisierung ist das Webinterface nicht erreichbar und keine Backups werden durchgeführt.", "tCurrent version": "Versión actual", "tTarget version": "Versión objetivo", "tVolumes to backup": "Volúmenes a copiar", @@ -977,8 +979,8 @@ translations.es={ "loglevel_0": "信息", "loglevel_1": "警告", "loglevel_2": "错误", -"tdir_error_text": "无法访问UrBackup保存备份的文件夹。在“设置”中修改此文件夹的位置,或赋予UrBackup对此文件夹的访问权限可解决此问题。", -"ttmpdir_error_text": "无法访问UrBackup保存临时文件的文件夹。在“设置”中修改此文件夹的位置,或赋予UrBackup对此文件夹的访问权限可解决此问题。", +"dir_error_text": "无法访问UrBackup保存备份的文件夹。在“设置”中修改此文件夹的位置,或赋予UrBackup对此文件夹的访问权限可解决此问题。", +"tmpdir_error_text": "无法访问UrBackup保存临时文件的文件夹。在“设置”中修改此文件夹的位置,或赋予UrBackup对此文件夹的访问权限可解决此问题。", "starting": "启动中", "ident_err": "服务器拒绝", "enter_hostname": "请输入主机名或IP地址", @@ -1014,7 +1016,7 @@ translations.es={ "storage_usage_bar_graph_colname2": "存储空间使用情况", "validate_err_notregexp_cleanup_window": "清理窗口格式错误", "mail_settings": "邮件", -"tupgrade_error_text": "UrBackup正在升级内部数据库并需要一些时间。升级期间服务器无法访问并暂停全部备份任务。", +"upgrade_error_text": "UrBackup正在升级内部数据库并需要一些时间。升级期间服务器无法访问并暂停全部备份任务。", "file_backup": "文件备份", "hours": "小时", "days": "天", @@ -1050,8 +1052,8 @@ translations.es={ "internet_client_added": "新客户端已添加,身份验证密钥或密码请参见“设置”。", "change_pw": "更改密码", "old_pw_wrong": "旧密码错误", -"tnospc_stalled_text": "备份文件夹空间不足,UrBackup正根据设置值删除旧的磁盘映像和文件备份数据。此期间的备份性能降低,备份数据被隔离。", -"tnospc_fatal_text": "备份文件夹空间不足,UrBackup已根据设置值删除了旧的磁盘映像和文件备份数据,但当前设置值已不允许继续删除。通过更改“设置”保存更少的备份数或增加备份存储空间后UrBackup方可继续执行备份任务。" +"nospc_stalled_text": "备份文件夹空间不足,UrBackup正根据设置值删除旧的磁盘映像和文件备份数据。此期间的备份性能降低,备份数据被隔离。", +"nospc_fatal_text": "备份文件夹空间不足,UrBackup已根据设置值删除了旧的磁盘映像和文件备份数据,但当前设置值已不允许继续删除。通过更改“设置”保存更少的备份数或增加备份存储空间后UrBackup方可继续执行备份任务。" } translations.zh_TW={ @@ -1099,8 +1101,8 @@ translations.zh_TW={ "loglevel_0": "情報", "loglevel_1": "警告", "loglevel_2": "錯誤", -"tdir_error_text": "無法訪問UrBackup保存備份的資料夾。在“設定”中修改此資料夾的位置,或賦予UrBackup對此資料夾的訪問權限可解決此問題。", -"ttmpdir_error_text": "無法訪問UrBackup保存臨時檔案的資料夾。在“設定”中修改此資料夾的位置,或賦予UrBackup對此資料夾的訪問權限可解決此問題。", +"dir_error_text": "無法訪問UrBackup保存備份的資料夾。在“設定”中修改此資料夾的位置,或賦予UrBackup對此資料夾的訪問權限可解決此問題。", +"tmpdir_error_text": "無法訪問UrBackup保存臨時檔案的資料夾。在“設定”中修改此資料夾的位置,或賦予UrBackup對此資料夾的訪問權限可解決此問題。", "starting": "啓動中", "ident_err": "伺服器拒絕", "enter_hostname": "請鍵入主機名或IP地址", @@ -1136,7 +1138,7 @@ translations.zh_TW={ "storage_usage_bar_graph_colname2": "儲存空間使用情況", "validate_err_notregexp_cleanup_window": "清理視窗格式錯誤", "mail_settings": "郵件", -"tupgrade_error_text": "UrBackup正在升級內部數據庫並需要一些時間。升級期間伺服器無法訪問並暫停全部備份任務。", +"upgrade_error_text": "UrBackup正在升級內部數據庫並需要一些時間。升級期間伺服器無法訪問並暫停全部備份任務。", "file_backup": "檔案備份", "hours": "小時", "days": "天", @@ -1172,8 +1174,8 @@ translations.zh_TW={ "internet_client_added": "新用戶端已添加,身份驗證密鑰或口令請參見“設定”。", "change_pw": "更改口令", "old_pw_wrong": "舊口令錯誤", -"tnospc_stalled_text": "備份資料夾空間不足,UrBackup正根據設定值移除舊的磁碟鏡像和檔案備份數據。此期間的備份性能降低,備份數據被隔離。", -"tnospc_fatal_text": "備份資料夾空間不足,UrBackup已根據設定值移除了舊的磁碟鏡像和檔案備份數據,但當前設定值已不允許繼續移除。通過更改“設定”保存更少的備份數或增加備份儲存空間後UrBackup方可繼續執行備份任務。" +"nospc_stalled_text": "備份資料夾空間不足,UrBackup正根據設定值移除舊的磁碟鏡像和檔案備份數據。此期間的備份性能降低,備份數據被隔離。", +"nospc_fatal_text": "備份資料夾空間不足,UrBackup已根據設定值移除了舊的磁碟鏡像和檔案備份數據,但當前設定值已不允許繼續移除。通過更改“設定”保存更少的備份數或增加備份儲存空間後UrBackup方可繼續執行備份任務。" } translations.fr={ "action_1": "Sauvegarde incrémentielle", @@ -1305,8 +1307,8 @@ translations.fr={ "tBackup storage path": "Chemin du répertoire de sauvegarde", "tDo not do image backups": "Désactiver la sauvegarde Image ", "tAutomatically shut down server": "Eteindre automatiquement le serveur", -"tdir_error_text": "Le dossier de sauvegarde UrBackup est inaccessible. Merci de changer le chemin dans 'Réglages' ou en donnant à UrBackup les droits d'accès à ce répertoire.", -"ttmpdir_error_text": "Le dossier de sauvegarde temporaire UrBackup est inaccessible. Merci de changer le chemin dans 'Réglages' ou en donnant à UrBackup les droits d'accès à ce répertoire.", +"dir_error_text": "Le dossier de sauvegarde UrBackup est inaccessible. Merci de changer le chemin dans 'Réglages' ou en donnant à UrBackup les droits d'accès à ce répertoire.", +"tmpdir_error_text": "Le dossier de sauvegarde temporaire UrBackup est inaccessible. Merci de changer le chemin dans 'Réglages' ou en donnant à UrBackup les droits d'accès à ce répertoire.", "starting": "Démarrage", "ident_err": "Serveur rejeté", "enter_hostname": "Merci d'entrer un nom d'hôte ou une adresse IP.", @@ -1378,7 +1380,7 @@ translations.fr={ "tAllow client-side pausing of backups": "Permettre au client de mettre en pause les sauvegardes", "tAutomatically backup UrBackup database": "Sauvegarder automatiquement la base de données du serveur", "tDo not do file backups": "Désactiver la sauvegarde de fichiers", -"tupgrade_error_text": "UrBackup met à jour sa base interne. Cela peut prendre du temps. Le serveur est ainsi inaccessible et ne fera aucune sauvegarde durant cet intervalle .", +"upgrade_error_text": "UrBackup met à jour sa base interne. Cela peut prendre du temps. Le serveur est ainsi inaccessible et ne fera aucune sauvegarde durant cet intervalle .", "tCurrent version": "Version actuelle", "tTarget version": "Version cible", "tVolumes to backup": "Volumes à sauvegarder", @@ -1466,6 +1468,6 @@ translations.fr={ "tClients are removed during the cleanup time window, if they are offline.": "Les clients seront supprimés durant l'intervalle de purge, si ils ne sont pas en ligne.", "tPerform autoupdates silently": "Appliquer les mises à jour automatiques en silence", "tArchived": "Archivés", -"tnospc_stalled_text": "Il n' y a plus d'espace disponible dans le répertoire de sauvegarde. UrBackup efface les anciennes sauvegardes de fichiers et image pour faire de l'espace, selon les paramètres définis dans Réglages. Pendant cette phase, les performances de la sauvegarde diminuent, et les sauvegardes sont stoppées .", -"tnospc_fatal_text": "Il n' y a plus d'espace disponible dans le répertoire de sauvegarde. UrBackup a tenté de purger les anciennes sauvegardes mais ne peut en effacer plus à cause des paramètres définis. Merci de changer ces paramètres à la baisse ou d'augmenter l'espace de stockage alloué afin de permettre à UrBackup de poursuivre." +"nospc_stalled_text": "Il n' y a plus d'espace disponible dans le répertoire de sauvegarde. UrBackup efface les anciennes sauvegardes de fichiers et image pour faire de l'espace, selon les paramètres définis dans Réglages. Pendant cette phase, les performances de la sauvegarde diminuent, et les sauvegardes sont stoppées .", +"nospc_fatal_text": "Il n' y a plus d'espace disponible dans le répertoire de sauvegarde. UrBackup a tenté de purger les anciennes sauvegardes mais ne peut en effacer plus à cause des paramètres définis. Merci de changer ces paramètres à la baisse ou d'augmenter l'espace de stockage alloué afin de permettre à UrBackup de poursuivre." } diff --git a/urbackupserver/www/urbackup.js b/urbackupserver/www/urbackup.js index 69c7943e..c64a0ae8 100644 --- a/urbackupserver/www/urbackup.js +++ b/urbackupserver/www/urbackup.js @@ -125,6 +125,7 @@ function try_anonymous_login(data) if(data.upgrading_database) { + data.upgrade_error_text=trans("upgrade_error_text"); var ndata=tmpls.upgrade_error.evaluate(data); if(g.data_f!=ndata) { @@ -134,6 +135,18 @@ function try_anonymous_login(data) return; } + if(data.creating_filescache) + { + data.creating_filescache_text=trans("creating_filescache_text"); + var ndata=tmpls.file_cache_error.evaluate(data); + if(g.data_f!=ndata) + { + I('data_f').innerHTML=ndata; + g.data_f=ndata; + } + return; + } + if(data.success) { g.session=data.session; @@ -683,25 +696,31 @@ function show_status2(data) { var ext_text=""; if(data.dir_error_ext) ext_text="("+data.dir_error_ext+")"; - dir_error=tmpls.dir_error.evaluate({ext_text: ext_text}); + dir_error=tmpls.dir_error.evaluate({ext_text: ext_text, dir_error_text: trans("dir_error_text")}); } var tmpdir_error=""; if(data.tmpdir_error) { - tmpdir_error=tmpls.tmpdir_error.evaluate(); + tmpdir_error=tmpls.tmpdir_error.evaluate({tmpdir_error_text: trans("tmpdir_error_text")}); } var nospc_stalled=""; if(data.nospc_stalled) { - nospc_stalled=tmpls.nospc_stalled.evaluate(); + nospc_stalled=tmpls.nospc_stalled.evaluate({nospc_stalled_text: trans("nospc_stalled_text")}); + } + + var database_error=""; + if(data.database_error) + { + database_error=tmpls.database_error.evaluate({database_error_text: trans("database_error_text")}); } var nospc_fatal=""; if(data.nospc_fatal) { - nospc_fatal=tmpls.nospc_fatal.evaluate(); + nospc_fatal=tmpls.nospc_fatal.evaluate({nospc_fatal_text: trans("nospc_fatal_text")}); } var dlt_mod_start="
- #{tupgrade_error_text}
+ #{upgrade_error_text}
#{tCurrent version}: #{curr_db_version}
#{tTarget version}: #{target_db_version}