#include <string>
#include <utility>
#include <algorithm>
+#include <ctime>
#include <climits>
#include "common/audit/logger.h"
#include "common/exception.h"
#include "service/type-converter.h"
#include "service/file-system.h"
+#include "service/access-control.h"
#include "ui/askuser.h"
#include "csr/error.h"
namespace Csr {
-Logic::Logic() :
+Logic::Logic(ThreadPool &pool) :
+ m_workqueue(pool),
m_cs(new CsLoader(CS_ENGINE_PATH)),
m_wp(new WpLoader(WP_ENGINE_PATH)),
m_db(new Db::Manager(RW_DBSPACE "/.csr.db", RO_DBSPACE))
return BinaryQueue::Serialize(CSR_ERROR_NONE, history).pop();
}
-RawBuffer Logic::getScannableFiles(const std::string &dir)
+RawBuffer Logic::getScannableFiles(const Credential &cred, const std::string &dir)
{
auto lastScanTime = m_db->getLastScanTime(dir, m_csDataVersion);
- StrSet fileset;
+ StrSet filesetForClient;
+ auto filesetForServer = std::make_shared<StrSet>();
try {
auto visitor = FsVisitor::create(dir, lastScanTime);
while (auto file = visitor->next()) {
DEBUG("In dir[" << dir << "], Scannable file[" << file->getPath() << "]");
- fileset.insert(file->getPath());
+ if (hasPermToRemove(cred, file->getPath()))
+ filesetForClient.insert(file->getPath());
+ else
+ filesetForServer->insert(file->getPath());
}
} catch (const FileDoNotExist &) {
WARN("Directory isn't exist: " << dir << " return success with empty file set "
if (lastScanTime != -1) {
// for case: scan history exist and not modified.
for (auto &row : m_db->getDetectedMalwares(dir))
- fileset.insert(row->targetName);
+ filesetForClient.insert(row->targetName);
}
- return BinaryQueue::Serialize(CSR_ERROR_NONE, fileset).pop();
+ // no fileset for server-only or dir is scanning in background already.. just skip
+ if (filesetForServer->empty() || m_scanningDirs.count(dir) != 0)
+ return BinaryQueue::Serialize(CSR_ERROR_NONE, filesetForClient).pop();
+
+ // update last scan time before start.
+ // to set scan time early is safe because file which is modified between
+ // scan start time and end time will be traversed by FsVisitor and re-scanned
+ // being compared to start time as modified since.
+ m_db->insertLastScanTime(dir, time(nullptr), m_csDataVersion);
+
+ m_workqueue.submit([this, dir, filesetForServer]() {
+ {
+ std::lock_guard<std::mutex> l(this->m_mutex);
+ this->m_scanningDirs.insert(dir);
+ }
+
+ // TODO: how to set default option of scan on cloud?
+ // ask user -> not ask user
+ // message -> none because not ask user
+ // core usage -> default
+ CsContext context;
+
+ for (auto file : *filesetForServer) {
+ // results are registered to db automatically
+ // so need not to handle returned data
+ this->scanFileHelper(context, file);
+ }
+
+ {
+ std::lock_guard<std::mutex> l(this->m_mutex);
+ this->m_scanningDirs.erase(dir);
+ }
+ });
+
+ return BinaryQueue::Serialize(CSR_ERROR_NONE, filesetForClient).pop();
}
RawBuffer Logic::judgeStatus(const std::string &filepath, csr_cs_action_e action)
#include <string>
#include <utility>
#include <memory>
+#include <mutex>
#include "common/types.h"
+#include "common/credential.h"
#include "common/cs-context.h"
#include "common/wp-context.h"
#include "common/cs-detected.h"
#include "common/wp-result.h"
#include "db/manager.h"
+#include "service/thread-pool.h"
#include "service/cs-loader.h"
#include "service/wp-loader.h"
class Logic {
public:
- Logic();
+ Logic(ThreadPool &);
virtual ~Logic();
+ void submit(std::function<void()> &&task);
+
RawBuffer scanData(const CsContext &context, const RawBuffer &data);
RawBuffer scanFile(const CsContext &context, const std::string &filepath);
- RawBuffer getScannableFiles(const std::string &dir);
+ RawBuffer getScannableFiles(const Credential &cred, const std::string &dir);
RawBuffer judgeStatus(const std::string &filepath, csr_cs_action_e action);
RawBuffer getDetected(const std::string &filepath);
RawBuffer getDetectedList(const StrSet &dirSet);
static csr_wp_user_response_e getUserResponse(const WpContext &,
const std::string &url, const WpResult &);
+ // internal task submit to thread pool for background scanning
+ ThreadPool &m_workqueue;
+ std::mutex m_mutex;
+ StrSet m_scanningDirs;
+
std::shared_ptr<CsLoader> m_cs;
std::shared_ptr<WpLoader> m_wp;
std::unique_ptr<Db::Manager> m_db;