/************************************************************************* * UrBackup - Client/Server backup system * Copyright (C) 2011-2014 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 . **************************************************************************/ #include "action_header.h" #include "../../urbackupcommon/os_functions.h" std::string constructFilter(const std::vector &clientid, std::string key) { std::string clientf="("; for(size_t i=0;igetThreadID(); Server->setContentType(tid, "application/octet-stream"); Server->addHeader(tid, "Content-Disposition: attachment; filename=\""+Server->ConvertToUTF8(ExtractFileName(filename))+"\""); IFile *in=Server->openFile(os_file_prefix(filename), MODE_READ); if(in!=NULL) { helper.releaseAll(); Server->addHeader(tid, "Content-Length: "+nconvert(in->Size()) ); char buf[4096]; _u32 r; do { r=in->Read(buf, 4096); Server->WriteRaw(tid, buf, r, false); } while(r>0); Server->destroy(in); return true; } else { Server->Log(L"Error opening file \""+filename+L"\"", LL_ERROR); return false; } } bool sendZip(Helper& helper, const std::wstring& foldername, const std::wstring& filter) { std::wstring zipname=ExtractFileName(foldername)+L".zip"; THREAD_ID tid = Server->getThreadID(); Server->setContentType(tid, "application/octet-stream"); Server->addHeader(tid, "Content-Disposition: attachment; filename=\""+Server->ConvertToUTF8(zipname)+"\""); helper.releaseAll(); return create_zip_to_output(foldername, filter); } } ACTION_IMPL(backups) { Helper helper(tid, &GET, &PARAMS); JSON::Object ret; SUser *session=helper.getSession(); if(session!=NULL && session->id==-1) return; std::wstring sa=GET[L"sa"]; std::string rights=helper.getRights("browse_backups"); std::string archive_rights=helper.getRights("manual_archive"); std::vector clientid=helper.getRightIDs(rights); std::vector clientid_archive=helper.getRightIDs(archive_rights); if(clientid.size()==1 && sa.empty() ) { sa=L"backups"; GET[L"clientid"]=convert(clientid[0]); } if(session!=NULL && rights!="none") { IDatabase *db=helper.getDatabase(); if(sa.empty()) { std::string qstr="SELECT id, name, strftime('"+helper.getTimeFormatString()+"', lastbackup, 'localtime') AS lastbackup FROM clients"; if(!clientid.empty()) qstr+=" WHERE "+constructFilter(clientid, "id"); qstr+=" ORDER BY name"; IQuery *q=db->Prepare(qstr); db_results res=q->Read(); q->Reset(); JSON::Array clients; for(size_t i=0;iPrepare("UPDATE backups SET archived=1, archive_timeout=0 WHERE id=?"); q->Bind(watoi(GET[L"archive"])); q->Write(); } else if(GET.find(L"unarchive")!=GET.end()) { IQuery *q=db->Prepare("UPDATE backups SET archived=0 WHERE id=?"); q->Bind(watoi(GET[L"unarchive"])); q->Write(); } } IQuery *q=db->Prepare("SELECT id, strftime('"+helper.getTimeFormatString()+"', backuptime, 'localtime') AS t_backuptime, incremental, size_bytes, archived, archive_timeout FROM backups WHERE complete=1 AND done=1 AND clientid=? ORDER BY backuptime DESC"); q->Bind(t_clientid); db_results res=q->Read(); JSON::Array backups; for(size_t i=0;igetTimeSeconds(); } } obj.set("archive_timeout", archive_timeout); backups.add(obj); } ret.set("backups", backups); ret.set("can_archive", archive_ok); q=db->Prepare("SELECT name FROM clients WHERE id=?"); q->Bind(t_clientid); res=q->Read(); q->Reset(); if(!res.empty()) { ret.set("clientname", res[0][L"name"]); ret.set("clientid", t_clientid); } } else { ret.set("error", 2); } } else if(sa==L"files" || sa==L"filesdl" || sa==L"zipdl" ) { int t_clientid=watoi(GET[L"clientid"]); bool r_ok=helper.hasRights(t_clientid, rights, clientid); if(r_ok) { int backupid=watoi(GET[L"backupid"]); std::wstring u_path=UnescapeHTML(GET[L"path"]); std::wstring path; std::vector t_path; Tokenize(u_path, t_path, L"/"); for(size_t i=0;iPrepare("SELECT name FROM clients WHERE id=?"); q->Bind(t_clientid); db_results res=q->Read(); q->Reset(); q=db->Prepare("SELECT value FROM settings_db.settings WHERE key='backupfolder'"); db_results res_bf=q->Read(); q->Reset(); if(!res.empty() && !res_bf.empty() ) { std::wstring backupfolder=res_bf[0][L"value"]; std::wstring clientname=res[0][L"name"]; ret.set("clientname", clientname); ret.set("clientid", t_clientid); ret.set("backupid", backupid); ret.set("path", u_path); q=db->Prepare("SELECT path,strftime('"+helper.getTimeFormatString()+"', backuptime, 'localtime') AS backuptime FROM backups WHERE id=?"); q->Bind(backupid); res=q->Read(); q->Reset(); if(!res.empty()) { std::wstring backuppath=res[0][L"path"]; ret.set("backuptime", res[0][L"backuptime"]); std::wstring currdir=backupfolder+os_file_sep()+clientname+os_file_sep()+backuppath+(path.empty()?L"":(os_file_sep()+path)); if(sa==L"filesdl") { sendFile(helper, currdir); return; } else if(sa==L"zipdl") { sendZip(helper, currdir, GET[L"filter"]); return; } std::vector tfiles=getFiles(os_file_prefix(currdir), NULL, true); JSON::Array files; for(size_t i=0;i