lib/index/scanner: tidy up a bit

Use strcmp instead of hand-optimized. Avoid tmp/ directories.
This commit is contained in:
Dirk-Jan C. Binnema 2021-10-21 19:15:48 +03:00
parent f3e3cc9ca2
commit e46347aa54
2 changed files with 17 additions and 26 deletions

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2020-2021 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This program is free software; you can redistribute it and/or modify it ** 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 ** under the terms of the GNU General Public License as published by the
@ -58,43 +58,34 @@ struct Scanner::Private {
}; };
static bool static bool
is_special_dir(const struct dirent* dentry) is_special_dir(const char* d_name)
{ {
const auto d_name{dentry->d_name};
return d_name[0] == '\0' || (d_name[1] == '\0' && d_name[0] == '.') || return d_name[0] == '\0' || (d_name[1] == '\0' && d_name[0] == '.') ||
(d_name[2] == '\0' && d_name[0] == '.' && d_name[1] == '.'); (d_name[2] == '\0' && d_name[0] == '.' && d_name[1] == '.');
} }
static bool
is_new_cur(const char* dirname)
{
if (dirname[0] == 'c' && dirname[1] == 'u' && dirname[2] == 'r' && dirname[3] == '\0')
return true;
if (dirname[0] == 'n' && dirname[1] == 'e' && dirname[2] == 'w' && dirname[3] == '\0')
return true;
return false;
}
bool bool
Scanner::Private::process_dentry(const std::string& path, struct dirent* dentry, bool is_maildir) Scanner::Private::process_dentry(const std::string& path, struct dirent* dentry, bool is_maildir)
{ {
if (is_special_dir(dentry)) const auto d_name{dentry->d_name};
if (is_special_dir(d_name) || std::strcmp(d_name, "tmp") == 0)
return true; // ignore. return true; // ignore.
const auto fullpath{path + "/" + dentry->d_name}; const auto fullpath{path + "/" + d_name};
struct stat statbuf; struct stat statbuf {
};
if (::stat(fullpath.c_str(), &statbuf) != 0) { if (::stat(fullpath.c_str(), &statbuf) != 0) {
g_warning("failed to stat %s: %s", fullpath.c_str(), g_strerror(errno)); g_warning("failed to stat %s: %s", fullpath.c_str(), g_strerror(errno));
return false; return false;
} }
if (S_ISDIR(statbuf.st_mode)) { if (S_ISDIR(statbuf.st_mode)) {
const auto new_cur = is_new_cur(dentry->d_name); const auto new_cur =
const auto htype = new_cur ? Scanner::HandleType::EnterNewCur std::strcmp(d_name, "cur") == 0 || std::strcmp(d_name, "new") == 0;
: Scanner::HandleType::EnterDir; const auto htype = new_cur ? Scanner::HandleType::EnterNewCur
const auto res = handler_(fullpath, &statbuf, htype); : Scanner::HandleType::EnterDir;
const auto res = handler_(fullpath, &statbuf, htype);
if (!res) if (!res)
return true; // skip return true; // skip

View File

@ -35,13 +35,13 @@ namespace Mu {
/// Scans maildir (trees) recursively, and calls the Handler callback for /// Scans maildir (trees) recursively, and calls the Handler callback for
/// directories & files. /// directories & files.
/// ///
/// It filters out (i.e., does call the handler for): /// It filters out (i.e., does *not* call the handler for):
/// - files starting with '.' /// - files starting with '.'
/// - files that do not live in a cur / new leaf maildir /// - files that do not live in a cur / new leaf maildir
/// - directories '.' and '..' /// - directories '.' and '..' and 'tmp'
/// ///
class Scanner { class Scanner {
public: public:
enum struct HandleType { enum struct HandleType {
File, File,
EnterNewCur, /* cur/ or new/ */ EnterNewCur, /* cur/ or new/ */
@ -90,7 +90,7 @@ class Scanner {
*/ */
bool is_running() const; bool is_running() const;
private: private:
struct Private; struct Private;
std::unique_ptr<Private> priv_; std::unique_ptr<Private> priv_;
}; };