From 34d23589a26674a7a39eba54ae5369f163411e03 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Tue, 31 Mar 2020 11:17:07 +0200 Subject: [PATCH] remove struct stat from interfaces --- src/index/fetcher.h | 4 +-- src/index/fsfetcher.cpp | 7 ++-- src/index/fsindexer.cpp | 30 ++++++++-------- src/index/fsindexer.h | 9 ++--- src/index/indexer.cpp | 5 ++- src/index/mimetype.cpp | 59 +++--------------------------- src/index/mimetype.h | 4 +-- src/index/rclmonrcv.cpp | 10 ++---- src/index/recollindex.cpp | 5 ++- src/index/webqueue.cpp | 21 ++++++----- src/index/webqueue.h | 12 +++---- src/internfile/internfile.cpp | 21 ++++++----- src/internfile/internfile.h | 6 ++-- src/qtgui/i18n/recoll_ko.qm | Bin 97003 -> 96695 bytes src/qtgui/i18n/recoll_ko.ts | 9 +++-- src/testmains/Makefile.am | 5 ++- src/testmains/trfstreewalk.cpp | 63 +++++++++++++++++---------------- src/testmains/trmimetype.cpp | 38 ++++++++++++++++++++ src/utils/appformime.cpp | 7 ++-- src/utils/fstreewalk.cpp | 27 +++++++------- src/utils/fstreewalk.h | 42 ++++++++++------------ src/utils/pathut.cpp | 49 +++++++++++++++++-------- src/utils/pathut.h | 23 ++++++++---- 23 files changed, 233 insertions(+), 223 deletions(-) create mode 100644 src/testmains/trmimetype.cpp diff --git a/src/index/fetcher.h b/src/index/fetcher.h index 92cf38d9..2ac1bfef 100644 --- a/src/index/fetcher.h +++ b/src/index/fetcher.h @@ -17,11 +17,11 @@ #ifndef _FETCHER_H_INCLUDED_ #define _FETCHER_H_INCLUDED_ -#include "safesysstat.h" #include #include #include "rcldoc.h" +#include "pathut.h" class RclConfig; @@ -51,7 +51,7 @@ public: enum RawDocKind {RDK_FILENAME, RDK_DATA, RDK_DATADIRECT}; RawDocKind kind; std::string data; // Doc data or file name - struct stat st; // Only used if RDK_FILENAME + struct PathStat st; // Only used if RDK_FILENAME }; /** diff --git a/src/index/fsfetcher.cpp b/src/index/fsfetcher.cpp index 667d1780..e9d6cd6e 100644 --- a/src/index/fsfetcher.cpp +++ b/src/index/fsfetcher.cpp @@ -17,7 +17,6 @@ #include "autoconfig.h" #include -#include "safesysstat.h" #include "log.h" #include "cstr.h" @@ -29,7 +28,7 @@ using std::string; static DocFetcher::Reason urltopath(RclConfig* cnf, const Rcl::Doc& idoc, - string& fn, struct stat& st) + string& fn, struct PathStat& st) { // The url has to be like file:// fn = fileurltolocalpath(idoc.url); @@ -62,7 +61,7 @@ bool FSDocFetcher::fetch(RclConfig* cnf, const Rcl::Doc& idoc, RawDoc& out) bool FSDocFetcher::makesig(RclConfig* cnf, const Rcl::Doc& idoc, string& sig) { string fn; - struct stat st; + struct PathStat st; if (urltopath(cnf, idoc, fn, st) != DocFetcher::FetchOk) return false; FsIndexer::makesig(&st, sig); @@ -72,7 +71,7 @@ bool FSDocFetcher::makesig(RclConfig* cnf, const Rcl::Doc& idoc, string& sig) DocFetcher::Reason FSDocFetcher::testAccess(RclConfig* cnf, const Rcl::Doc& idoc) { string fn; - struct stat st; + struct PathStat st; DocFetcher::Reason reason = urltopath(cnf, idoc, fn, st); if (reason != DocFetcher::FetchOk) { return reason; diff --git a/src/index/fsindexer.cpp b/src/index/fsindexer.cpp index a1f23f80..526e07ea 100644 --- a/src/index/fsindexer.cpp +++ b/src/index/fsindexer.cpp @@ -21,7 +21,6 @@ #include #include #include -#include "safesysstat.h" #include #include @@ -69,14 +68,14 @@ extern void *FsIndexerDbUpdWorker(void*); class InternfileTask { public: // Take some care to avoid sharing string data (if string impl is cow) - InternfileTask(const std::string &f, const struct stat *i_stp, + InternfileTask(const std::string &f, const struct PathStat *i_stp, map lfields) : fn(f.begin(), f.end()), statbuf(*i_stp) { map_ss_cp_noshr(lfields, &localfields); } string fn; - struct stat statbuf; + struct PathStat statbuf; map localfields; }; extern void *FsIndexerInternfileWorker(void*); @@ -369,7 +368,7 @@ bool FsIndexer::indexFiles(list& files, int flags) continue; } - struct stat stb; + struct PathStat stb; int ststat = path_fileprops(*it, &stb, follow); if (ststat != 0) { LOGERR("FsIndexer::indexFiles: (l)stat " << *it << ": " << @@ -378,7 +377,8 @@ bool FsIndexer::indexFiles(list& files, int flags) continue; } if (!(flags & ConfIndexer::IxFIgnoreSkip) && - (S_ISREG(stb.st_mode) || S_ISLNK(stb.st_mode))) { + (stb.pst_type == PathStat::PST_REGULAR || + stb.pst_type == PathStat::PST_SYMLINK)) { if (!walker.inOnlyNames(path_getsimple(*it))) { it++; continue; @@ -499,10 +499,10 @@ void FsIndexer::setlocalfields(const map& fields, Rcl::Doc& doc) } } -void FsIndexer::makesig(const struct stat *stp, string& out) +void FsIndexer::makesig(const struct PathStat *stp, string& out) { - out = lltodecstr(stp->st_size) + - lltodecstr(o_uptodate_test_use_mtime ? stp->st_mtime : stp->st_ctime); + out = lltodecstr(stp->pst_size) + + lltodecstr(o_uptodate_test_use_mtime ? stp->pst_mtime : stp->pst_ctime); } #ifdef IDX_THREADS @@ -572,7 +572,7 @@ void *FsIndexerInternfileWorker(void * fsp) /// the actual indexing work. The Rcl::Doc created by internfile() /// mostly contains pretty raw utf8 data. FsTreeWalker::Status -FsIndexer::processone(const std::string &fn, const struct stat *stp, +FsIndexer::processone(const std::string &fn, const struct PathStat *stp, FsTreeWalker::CbFlag flg) { if (m_updater) { @@ -633,7 +633,7 @@ bool FsIndexer::launchAddOrUpdate(const string& udi, const string& parent_udi, FsTreeWalker::Status FsIndexer::processonefile(RclConfig *config, - const std::string &fn, const struct stat *stp, + const std::string &fn, const struct PathStat *stp, const map& localfields) { //////////////////// @@ -671,7 +671,7 @@ FsIndexer::processonefile(RclConfig *config, // miss the data update. We would have to store both the mtime and // the ctime to avoid this bool xattronly = m_detectxattronly && !m_db->inFullReset() && - existingDoc && needupdate && (stp->st_mtime < stp->st_ctime); + existingDoc && needupdate && (stp->pst_mtime < stp->pst_ctime); LOGDEB("processone: needupdate " << needupdate << " noretry " << m_noretryfailed << " existing " << existingDoc << " oldsig [" << @@ -708,7 +708,7 @@ FsIndexer::processonefile(RclConfig *config, } LOGDEB0("processone: processing: [" << - displayableBytes(stp->st_size) << "] " << fn << "\n"); + displayableBytes(stp->pst_size) << "] " << fn << "\n"); // Note that we used to do the full path here, but I ended up // believing that it made more sense to use only the file name @@ -720,7 +720,7 @@ FsIndexer::processonefile(RclConfig *config, Rcl::Doc doc; char ascdate[30]; - sprintf(ascdate, "%ld", long(stp->st_mtime)); + sprintf(ascdate, "%ld", long(stp->pst_mtime)); bool hadNullIpath = false; string mimetype; @@ -789,7 +789,7 @@ FsIndexer::processonefile(RclConfig *config, // Set container file name for all docs, top or subdoc doc.meta[Rcl::Doc::keytcfn] = utf8fn; - doc.pcbytes = lltodecstr(stp->st_size); + doc.pcbytes = lltodecstr(stp->pst_size); // Document signature for up to date checks. All subdocs inherit the // file's. doc.sig = sig; @@ -880,7 +880,7 @@ FsIndexer::processonefile(RclConfig *config, fileDoc.url = path_pathtofileurl(fn); if (m_havelocalfields) setlocalfields(localfields, fileDoc); - fileDoc.pcbytes = lltodecstr(stp->st_size); + fileDoc.pcbytes = lltodecstr(stp->pst_size); } fileDoc.sig = sig; diff --git a/src/index/fsindexer.h b/src/index/fsindexer.h index 6f42da86..a237ea18 100644 --- a/src/index/fsindexer.h +++ b/src/index/fsindexer.h @@ -28,7 +28,7 @@ class DbIxStatusUpdater; class FIMissingStore; -struct stat; +struct PathStat; class DbUpdTask; class InternfileTask; @@ -75,10 +75,10 @@ public: /** Tree walker callback method */ FsTreeWalker::Status - processone(const string &fn, const struct stat *, FsTreeWalker::CbFlag); + processone(const string &fn, const struct PathStat *, FsTreeWalker::CbFlag); /** Make signature for file up to date checks */ - static void makesig(const struct stat *stp, string& out); + static void makesig(const struct PathStat *stp, string& out); private: @@ -160,7 +160,8 @@ private: string getDbDir() {return m_config->getDbDir();} FsTreeWalker::Status processonefile(RclConfig *config, const string &fn, - const struct stat *, const map& localfields); + const struct PathStat *, + const map& localfields); }; #endif /* _fsindexer_h_included_ */ diff --git a/src/index/indexer.cpp b/src/index/indexer.cpp index ffa210d8..26f6b900 100644 --- a/src/index/indexer.cpp +++ b/src/index/indexer.cpp @@ -33,7 +33,6 @@ #include "pathut.h" #include "idxstatus.h" #include "execmd.h" -#include "safesysstat.h" #ifdef RCL_USE_ASPELL #include "rclaspell.h" @@ -86,9 +85,9 @@ bool runWebFilesMoverScript(RclConfig *config) /* Arrange to not actually run the script if the directory did not change */ static time_t dirmtime; time_t ndirmtime = 0; - struct stat st; + struct PathStat st; if (path_fileprops(downloadsdir.c_str(), &st) == 0) { - ndirmtime = st.st_mtime; + ndirmtime = st.pst_mtime; } /* If stat fails, presumably Downloads does not exist or is not accessible, dirmtime and mdirmtime stay at 0, and we never diff --git a/src/index/mimetype.cpp b/src/index/mimetype.cpp index 57b62f7a..321303c6 100644 --- a/src/index/mimetype.cpp +++ b/src/index/mimetype.cpp @@ -15,11 +15,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef TEST_MIMETYPE #include "autoconfig.h" -#include "safesysstat.h" - #include #include #include @@ -139,7 +136,7 @@ static string mimetypefromdata(RclConfig *cfg, const string &fn, bool usfc) /// Guess mime type, first from suffix, then from file data. We also /// have a list of suffixes that we don't touch at all. -string mimetype(const string &fn, const struct stat *stp, +string mimetype(const string &fn, const struct PathStat *stp, RclConfig *cfg, bool usfc) { // Use stat data if available to check for non regular files @@ -149,14 +146,14 @@ string mimetype(const string &fn, const struct stat *stp, // comes from bsd. Thos may surprise a user trying to use a // 'mime:' filter with the query language, but it's not work // changing (would force a reindex). - if (S_ISDIR(stp->st_mode)) + if (stp->pst_type == PathStat::PST_DIR) return "inode/directory"; - if (S_ISLNK(stp->st_mode)) + if (stp->pst_type == PathStat::PST_SYMLINK) return "inode/symlink"; - if (!S_ISREG(stp->st_mode)) + if (stp->pst_type != PathStat::PST_REGULAR) return "inode/x-fsspecial"; // Empty files are just this: avoid further errors with actual filters. - if (stp->st_size == 0) + if (stp->pst_size == 0) return "inode/x-empty"; } @@ -203,49 +200,3 @@ string mimetype(const string &fn, const struct stat *stp, return mtype; } - - -#else // TEST-> - -#include -#include "safesysstat.h" - -#include -#include - -#include "log.h" - -#include "rclconfig.h" -#include "rclinit.h" -#include "mimetype.h" - -using namespace std; -int main(int argc, const char **argv) -{ - string reason; - RclConfig *config = recollinit(0, 0, 0, reason); - - if (config == 0 || !config->ok()) { - string str = "Configuration problem: "; - str += reason; - fprintf(stderr, "%s\n", str.c_str()); - exit(1); - } - - while (--argc > 0) { - string filename = *++argv; - struct stat st; - if (lstat(filename.c_str(), &st)) { - fprintf(stderr, "Can't stat %s\n", filename.c_str()); - continue; - } - cout << filename << " -> " << - mimetype(filename, &st, config, true) << endl; - - } - return 0; -} - - -#endif // TEST - diff --git a/src/index/mimetype.h b/src/index/mimetype.h index e657e878..419c95fd 100644 --- a/src/index/mimetype.h +++ b/src/index/mimetype.h @@ -17,10 +17,10 @@ #ifndef _MIMETYPE_H_INCLUDED_ #define _MIMETYPE_H_INCLUDED_ -#include "safesysstat.h" #include class RclConfig; +struct PathStat; /** * Try to determine a mime type for file. @@ -32,7 +32,7 @@ class RclConfig; * @param cfg recoll config * @param usfc Use system's 'file' command as last resort (or not) */ -std::string mimetype(const std::string &filename, const struct stat *stp, +std::string mimetype(const std::string &filename, const struct PathStat *stp, RclConfig *cfg, bool usfc); diff --git a/src/index/rclmonrcv.cpp b/src/index/rclmonrcv.cpp index ac6bad5d..2882c703 100644 --- a/src/index/rclmonrcv.cpp +++ b/src/index/rclmonrcv.cpp @@ -21,7 +21,6 @@ #include #include #include -#include "safesysstat.h" #include "safeunistd.h" #include "log.h" @@ -74,7 +73,7 @@ public: virtual ~WalkCB() {} virtual FsTreeWalker::Status - processone(const string &fn, const struct stat *st, + processone(const string &fn, const struct PathStat *st, FsTreeWalker::CbFlag flg) { MONDEB("rclMonRcvRun: processone " << fn << " m_mon " << m_mon << " m_mon->ok " << (m_mon ? m_mon->ok() : false) << std::endl); @@ -182,12 +181,7 @@ void *rclMonRcvRun(void *q) } // We have to special-case regular files which are part of the topdirs // list because we the tree walker only adds watches for directories - struct stat st; - if (path_fileprops(*it, &st, follow) != 0) { - LOGERR("rclMonRcvRun: stat failed for " << *it << "\n"); - continue; - } - if (S_ISDIR(st.st_mode)) { + if (path_isdir(*it, follow)) { LOGDEB("rclMonRcvRun: walking " << *it << "\n"); if (walker.walk(*it, walkcb) != FsTreeWalker::FtwOk) { LOGERR("rclMonRcvRun: tree walk failed\n"); diff --git a/src/index/recollindex.cpp b/src/index/recollindex.cpp index b54bcc9e..0ecd1d44 100644 --- a/src/index/recollindex.cpp +++ b/src/index/recollindex.cpp @@ -26,7 +26,6 @@ #else #include #endif -#include "safesysstat.h" #include "safefcntl.h" #include "safeunistd.h" @@ -264,8 +263,8 @@ public: { } virtual FsTreeWalker::Status - processone(const string& fn, const struct stat *, FsTreeWalker::CbFlag flg) - { + processone(const string& fn, const struct PathStat *, + FsTreeWalker::CbFlag flg) { if (flg== FsTreeWalker::FtwDirEnter || flg == FsTreeWalker::FtwRegular){ if (m_pats.empty()) { cerr << "Selecting " << fn << endl; diff --git a/src/index/webqueue.cpp b/src/index/webqueue.cpp index 0bf4495b..808326f4 100644 --- a/src/index/webqueue.cpp +++ b/src/index/webqueue.cpp @@ -20,7 +20,6 @@ #include #include -#include "safesysstat.h" #include "safeunistd.h" #include "cstr.h" @@ -322,13 +321,13 @@ bool WebQueueIndexer::indexFiles(list& files) LOGERR("WebQueueIndexer::indexfiles no db??\n"); return false; } - for (list::iterator it = files.begin(); it != files.end();) { + for (auto it = files.begin(); it != files.end();) { if (it->empty()) {//?? it++; continue; } string father = path_getfather(*it); if (father.compare(m_queuedir)) { - LOGDEB("WebQueueIndexer::indexfiles: skipping [" << *it << "] (nq)\n"); + LOGDEB("WebQueueIndexer::indexfiles: skipping ["<<*it << "] (nq)\n"); it++; continue; } // Pb: we are often called with the dot file, before the @@ -342,12 +341,12 @@ bool WebQueueIndexer::indexFiles(list& files) if (fn.empty() || fn.at(0) == '.') { it++; continue; } - struct stat st; + struct PathStat st; if (path_fileprops(*it, &st) != 0) { LOGERR("WebQueueIndexer::indexfiles: cant stat [" << *it << "]\n"); it++; continue; } - if (!S_ISREG(st.st_mode)) { + if (st.pst_type != PathStat::PST_REGULAR) { LOGDEB("WebQueueIndexer::indexfiles: skipping [" << *it << "] (nr)\n"); it++; continue; @@ -364,14 +363,15 @@ bool WebQueueIndexer::indexFiles(list& files) FsTreeWalker::Status WebQueueIndexer::processone(const string &path, - const struct stat *stp, + const struct PathStat *stp, FsTreeWalker::CbFlag flg) { if (!m_db) //?? return FsTreeWalker::FtwError; bool dounlink = false; - + string ascdate; + if (flg != FsTreeWalker::FtwRegular) return FsTreeWalker::FtwOk; @@ -392,8 +392,7 @@ WebQueueIndexer::processone(const string &path, make_udi(udipath, cstr_null, udi); LOGDEB("WebQueueIndexer: prc1: udi [" << udi << "]\n"); - char ascdate[30]; - sprintf(ascdate, "%ld", long(stp->st_mtime)); + ascdate = lltodecstr(stp->pst_mtime); if (!stringlowercmp("bookmark", dotdoc.meta[Rcl::Doc::keybght])) { // For bookmarks, we just index the doc that was built from the @@ -401,7 +400,7 @@ WebQueueIndexer::processone(const string &path, if (dotdoc.fmtime.empty()) dotdoc.fmtime = ascdate; - dotdoc.pcbytes = lltodecstr(stp->st_size); + dotdoc.pcbytes = lltodecstr(stp->pst_size); // Document signature for up to date checks: none. dotdoc.sig.clear(); @@ -439,7 +438,7 @@ WebQueueIndexer::processone(const string &path, doc.fmtime = ascdate; dotdoc.fmtime = doc.fmtime; - doc.pcbytes = lltodecstr(stp->st_size); + doc.pcbytes = lltodecstr(stp->pst_size); // Document signature for up to date checks: none. doc.sig.clear(); doc.url = dotdoc.url; diff --git a/src/index/webqueue.h b/src/index/webqueue.h index 2ac0a347..56573085 100644 --- a/src/index/webqueue.h +++ b/src/index/webqueue.h @@ -50,7 +50,7 @@ public: /** Called when we fstreewalk the queue dir */ FsTreeWalker::Status - processone(const string &, const struct stat *, FsTreeWalker::CbFlag); + processone(const std::string &, const struct PathStat *, FsTreeWalker::CbFlag); /** Index a list of files. No db cleaning or stemdb updating. * Used by the real time monitor */ @@ -62,18 +62,18 @@ public: /** Called when indexing data from the cache, and from internfile for * search result preview */ - bool getFromCache(const string& udi, Rcl::Doc &doc, string& data, - string *hittype = 0); + bool getFromCache(const std::string& udi, Rcl::Doc &doc, std::string& data, + std::string *hittype = 0); private: RclConfig *m_config; Rcl::Db *m_db; WebStore *m_cache; - string m_queuedir; + std::string m_queuedir; DbIxStatusUpdater *m_updater; bool m_nocacheindex; - bool indexFromCache(const string& udi); - void updstatus(const string& udi); + bool indexFromCache(const std::string& udi); + void updstatus(const std::string& udi); }; #endif /* _webqueue_h_included_ */ diff --git a/src/internfile/internfile.cpp b/src/internfile/internfile.cpp index df7442be..03ff75e4 100644 --- a/src/internfile/internfile.cpp +++ b/src/internfile/internfile.cpp @@ -22,7 +22,6 @@ #include #include "safefcntl.h" #include -#include "safesysstat.h" #include "safeunistd.h" #include @@ -117,7 +116,7 @@ bool FileInterner::ipathContains(const string& parent, const string& child) // Empty handler on return says that we're in error, this will be // processed by the first call to internfile(). // Split into "constructor calls init()" to allow use from other constructor -FileInterner::FileInterner(const string &fn, const struct stat *stp, +FileInterner::FileInterner(const string &fn, const struct PathStat *stp, RclConfig *cnf, int flags, const string *imime) { LOGDEB0("FileInterner::FileInterner(fn=" << fn << ")\n"); @@ -137,8 +136,8 @@ FileInterner::FileInterner(const string &fn, const struct stat *stp, // used to not be the case, and was changed because this was the // simplest way to solve the retry issues (simpler than changing the // caller in e.g. fsindexer). -void FileInterner::init(const string &f, const struct stat *stp, RclConfig *cnf, - int flags, const string *imime) +void FileInterner::init(const string &f, const struct PathStat *stp, + RclConfig *cnf, int flags, const string *imime) { if (f.empty()) { LOGERR("FileInterner::init: empty file name!\n"); @@ -185,7 +184,7 @@ void FileInterner::init(const string &f, const struct stat *stp, RclConfig *cnf, l_mime = *imime; } - int64_t docsize = stp->st_size; + int64_t docsize = stp->pst_size; if (!l_mime.empty()) { // Has mime: check for a compressed file. If so, create a @@ -196,7 +195,7 @@ void FileInterner::init(const string &f, const struct stat *stp, RclConfig *cnf, // Check for compressed size limit int maxkbs = -1; if (!m_cfg->getConfParam("compressedfilemaxkbs", &maxkbs) || - maxkbs < 0 || !stp || int(stp->st_size / 1024) < maxkbs) { + maxkbs < 0 || !stp || int(stp->pst_size / 1024) < maxkbs) { if (!m_uncomp->uncompressfile(m_fn, ucmd, m_tfile)) { m_ok = true; return; @@ -204,14 +203,14 @@ void FileInterner::init(const string &f, const struct stat *stp, RclConfig *cnf, LOGDEB1("FileInterner:: after ucomp: tfile " << m_tfile <<"\n"); m_fn = m_tfile; // Stat the uncompressed file, mainly to get the size - struct stat ucstat; + struct PathStat ucstat; if (path_fileprops(m_fn, &ucstat) != 0) { LOGERR("FileInterner: can't stat the uncompressed file[" << m_fn << "] errno " << errno << "\n"); m_ok = true; return; } else { - docsize = ucstat.st_size; + docsize = ucstat.pst_size; } l_mime = mimetype(m_fn, &ucstat, m_cfg, usfci); if (l_mime.empty() && imime) @@ -1096,7 +1095,7 @@ bool FileInterner::interntofile(TempFile& otemp, const string& tofile, bool FileInterner::isCompressed(const string& fn, RclConfig *cnf) { LOGDEB("FileInterner::isCompressed: [" << fn << "]\n"); - struct stat st; + struct PathStat st; if (path_fileprops(fn, &st) < 0) { LOGERR("FileInterner::isCompressed: can't stat [" << fn << "]\n"); return false; @@ -1120,7 +1119,7 @@ bool FileInterner::maybeUncompressToTemp(TempFile& temp, const string& fn, RclConfig *cnf, const Rcl::Doc& doc) { LOGDEB("FileInterner::maybeUncompressToTemp: [" << fn << "]\n"); - struct stat st; + struct PathStat st; if (path_fileprops(fn.c_str(), &st) < 0) { LOGERR("FileInterner::maybeUncompressToTemp: can't stat [" <getConfParam("compressedfilemaxkbs", &maxkbs) && - maxkbs >= 0 && int(st.st_size / 1024) > maxkbs) { + maxkbs >= 0 && int(st.pst_size / 1024) > maxkbs) { LOGINFO("FileInterner:: " << fn << " over size limit " << maxkbs << " kbs\n"); return false; diff --git a/src/internfile/internfile.h b/src/internfile/internfile.h index 21543125..4f494692 100644 --- a/src/internfile/internfile.h +++ b/src/internfile/internfile.h @@ -37,7 +37,7 @@ class Doc; } class Uncomp; -struct stat; +struct PathStat; /** Storage for missing helper program info. We want to keep this out of the * FileInterner class, because the data will typically be accumulated by several @@ -114,7 +114,7 @@ public: * @param mtype mime type if known. For a compressed file this is the * mime type for the uncompressed version. */ - FileInterner(const string &fn, const struct stat *stp, + FileInterner(const string &fn, const struct PathStat *stp, RclConfig *cnf, int flags, const string *mtype = 0); /** @@ -290,7 +290,7 @@ private: bool m_direct; // External app did the extraction // Pseudo-constructors - void init(const string &fn, const struct stat *stp, + void init(const string &fn, const struct PathStat *stp, RclConfig *cnf, int flags, const string *mtype = 0); void init(const string &data, RclConfig *cnf, int flags, const string& mtype); diff --git a/src/qtgui/i18n/recoll_ko.qm b/src/qtgui/i18n/recoll_ko.qm index e225f5addae2caa57de7c694ca8e1cb1c9b134fd..16f2a315e1be254ba0f08b8e028dd85bbed80bad 100644 GIT binary patch delta 5721 zcmX9?c|eWn8$Iv6-*?yVe%DAUOZHt^lCouAhcpxsF|ungb_O>~ge+s^lA!3e=9>#!Jjw;qQWAecW2=7a$smMke>n!3+K5e z;FnRr`@@jrA;8n8ko18(uN|bVn_v^w{s$>?F0lFwq=N^5yh2Fv-GMVckgjzDjQNo6 ztOmjjknRr$OpcIEe?inpf$VG#;r7^C5;;M&0Bs5QZse(CaxfPD8`PeBJFe8kc_WL0>d}-5mHwizcN3 zE<1uIV{MFN`yMp8dJ%Y-k7h@`fEy)fAwH4%DQKHH8o1jAod>NUWxt@yF=vQ&%h5CR z7Q~=i==qp|X4OEi)`bw&dJ>C?Gtj5WVjygB845KGeOhk<3`@&UG_yzFZ7fMr0s7gb zc@Py}z-RnH;7tGquH4E4E@R-yQxFZ8!#CEQufM_Ib-uuw#~6I+HgIth{L@k)1~0(S z=1U+31Y_uo7Nqnh0?f=be>(!kx-k(QhAlZk=8j=ZbR}SgigB~ah#?UZ19{*1sjvl? zMslYQe$h}ccPnE0>30<1?Q*;ugjt>&fJ>(^D>|8!H!8=wahP{C4$xFZNXR~jE-qL) z(GfTtjW9QF;F}M^Yn1@)E@R97;}9-u5Yc=mP%|768H*sAWMlu>L%_*!8xHr;Qe^Rn z{woU@FcC3h2SPOci1_pZ9ykT3V@uy(h!pVs!dRp}TLGlI;@amW417u%in^L|Y`Psc zC;I_0HF5KImhyWAWJgQ}+BCqoaWjBhW+B>cB4fvdd|L+0wjILI{RD7*m-t~aMUh)s zRNNc_WE2R8WLF4Rji`EqR6cnrYB=-#mzPAt$3}>n=S7niYk;kZqIuI$X67T@Z}Y+v zl|{Rg(;;ei7hbMGz~)M#+mx2Tx!S^ewHVk(=B+vf+*>U|zLJ>-r^M=B z+jw!P_#%D|?BOfxRJ2RmJxo$Z(Z-@%>&XgmZ!h-xdP(uWL*%?b-jEM{1lp z>Veotnjf{>A-c<&pnyCG^8-y#qBrp0OU+b=I)KhmGb=|+zgR##0K87t%r?6di_1_L zUzcNr#I*XWJctQ1Y~wI{4Cv0=4N|SOS!kah5UD@yr+rk^7oyWv?Tg|}pu$$|>p9gZ$|UXQKI0&I_}jGq zbqFH$OSL7P_X4ke*Osh2Kt^|Kzt>`htD9)Q*Q0^d3)Ft^Ov)C*1sC|x4}7I5|FYI+4@tAe-v(Mb zOS3EaLe!6yLb5q>|MZta8}f6_ReH6`_dtE8AEgDI*G zO$bm`lDoVf$m!@KPm0gteh?#12_r*46w1>&HsX}am#6J= z0*=PZ^NV;O#>q>*PleE3mX}V-0d@?QSN{Gtr=W|xDv}#hPGx!3!vfxOO%9)s2_Y$R z_(fZL_H~rJX6ix+p_A9#ilt+P%j;^h9Rot;9bp{D)_vtzDO=v%bOx|%haA~?ARRMT zKAb|)US2Fmc|B))ev}gqS{T5#a;#ThPAFpFMgPf(I|s1s8p#*;vgSKG$#;7P($XE} zd$xsLNzr^c%eD(*lvd9D_YxNaS$>u6MU{uh1>q;S+1%4fQ(21Yg*x5HIN zcKhApK2V^GG*VP(p^H2;nJZN*UE~L9M3byLc!b?>^B-OGM>6W`po{mAsEN_K)3>H` zrE}0FFACu%wO5yVo(!m0ZMxJu+;~$y>C!fD;5@&eOZVpm7BAhkrb$42v@UOQH(Kx# zUBT=|)Itrtu$2JK@9T9DT{-2_^af{MgaP_WEp|~0Z}qiiG1JC{`X*G zpXfbGDSxm)-#(0=uj{YxI*|!qu$|KP7))w^=&A1!;|-aupM!!u@6Y<2YESGRCDHP)|NL`L2=)o(jr zNTaEy-|;An7a8;syBT1jn?7>;agJ?8f2=@Z|L$%Vuz9c!!OPd z{rc#i4fmu!?9^xPA#*iy_1R}tZr7{yuhy`XFRtp}t**lTzgBgFxjQekk1^D1&j9pp zhQ`zRf5%iq(+_ijYF`X3%+U~Xk)iF(e29T{44uExdb0)?x>?(DhpTAleSxA2^EdQK zW;e`8G4%OH1}d&I{PdDr^(M1nNO&eUpaX^l3&`NcR6|I+?(B;0hK=txu>S*N3ab#Nm@%byLgQV^}Vvmri;BK>);A=S>F?KshJsZ$CUi8hAx_}jEv zvmyPQmLmLQNKeTolXnbP-o$agzh}tM65sh5?n<$AJSW4wO-x|eYQv+445US*;rUKm z5S^=s;ra0cq_mbHx4#!NRSo$a&jNq&{7jS>9(M4)VZD@@iXG?QSFM9_vriz6 z>7{Y^IXd1hFXO&nxi2_RG#**PuE}d{JQ|S?v>j%Q-WfwNdm4{9v;jOS8dG-g9=A|q z${8l;_r#c8IgO>hVzfQiGQu-6jJad>@!?Sz-{cfSbm(LJZ^A1eqJqh|mw~mMZ?ZP_ zrY~$WSu;-2N~26pZ5c?tbW_!bWKjRe)L1uw51cNh#{V0^-S3R4N&AgJo!X|>d$`&q zoH2O~3S~*_nR>b|WLGsZ4g6yy+ttlx8dSH0L*$MrVCx$?pQmZ$I*!rgSkuUt42Z?~ zIe}t%9BT?H!{?^ao)RA@Mw>=o%izIzrnwbmu2kDi8_Zd}FweBL_fBrPH%3LZ zP5Y-O0qbv=4n(k-j7v<>gM3-im8N5PWF*2i-4qvT=9as{l#-uK1FB(4Rfz=&rmGv* zKvW4gJs!@b)cc6(*^8G9q?74IF)`~;vlPveJlaP5OuT27Z-p}4(`Gq0kR_dMHqITx zDVb%i;Y*EZKA3B)c>pXon(Mt{X?yoKH=VPD{omr5xkD`#m|4sGu- zlgp=9M{_|}is?&7Mbj|}qHi-r-h7Fovns|xqgkSviqeWAOw3V~w_n(%_Z4+W6*6Y0 z*uC3CKQSu}u5BeVHIyc!y7GHh71wn7!@v8LW(U}QDYKMT+bh}lOm<6YebE_06R))K zNMVr@l{RTC*2N^HPd#R0bW!>?mbk0AEB(IkNya=?@wu~&;`vP(z{hgj$WVOk>u^h6 zt_=FhgKHmAhE3>7AF)%0zhG%00Q+BPMm z))2n%dpW*4qbwdwMqUn8md)pQ-I=7U)X025siK6xCG{^IlpXuHhPSV;>J%A-%OIhK1X&*wR_1Yea`TNcuI4lBh+y}6_&DIb=d<*fME zqW;3#zFB6m+m}UcbhbE`Zo%TQrOs#iLeox`1_LP8U*j!JSM&YUM;4ddB5KUh;_*`n zH56&Fc{-JF9>2Eq(4OOV+tt#)J4H72p~au`SvU-}3<>t)WAt^)a6UL-gmW2+=FXPD zXb0|c{mW2P>1UbwzBz}=TFcyoN*upaEptyT1hf+^zr`f+`C*V{@t^b=-5pElr9*rk zaI-Ae&ZJ0vY~_D6@U*P(;ekiZ<#>CSWvx3Y{>k66fBRDYQjuzjT1g8X8esYBn+LEs z%W~0v0>^Hy<>Gs0?6t#^uJXdn?UwZ0>pAttTW;Ifc7_+0e|~bOCY&rEevRf271J#L zCGR7{^;Pq)Jnz2kvua;0g#CC-wZG0ttG`j5ej_7pf2!5(iy(r$)OwF51ADrwrRo)K zUTU+GuFR~N>gGqSx*62gVOu!Q iHIPYt1RNGWyd*$>}+gD&b#>|aIo)lrN` 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 Index flush megabytes interval - <p> 이것은 기본적으로 모든 분음 부호를 제거하고 정식 분해를 수행하는 unac 메커니즘에 대한 예외를 설정합니다. 언어에 따라 일부 문자의 강조를 무시, 추가, 분해를 지정할 수 있습니다(예 : 합자의 경우. 공백으로 구분된 각 항목에서 첫 번째 문자는 원본이고 나머지는 번역입니다). + 색인 정비 간격(MB) This value adjust the amount of data which is indexed between flushes to disk.<br>This helps control the indexer memory usage. Default 10MB @@ -1219,7 +1219,7 @@ Do you want to start the preferences dialog ? Query in progress.<br>Due to limitations of the indexing library,<br>cancelling will exit the program - 검색어 요청이 진행중입니다.<br> 색인 작업 보관용량의 제한으로 인해<br> 프로그램은 취소되고 종료될 것입니다. + 검색어 요청이 진행중입니다.<br>취소되면 색인 작업 보관용량의 제한 때문에<br>프로그램이 종료될 것입니다. Error @@ -2407,7 +2407,7 @@ Use <b>Show Query</b> link when in doubt about result and see manual terms may be missing. Try using a longer root. - 용어가 아마 누락된 것 같습니다. 더 긴 root를 사용하여 시도하십시오. + 용어가 아마 누락된 것 같습니다. 더 긴 어근을 사용하여 시도하십시오. Show index statistics @@ -2864,8 +2864,7 @@ This will help searching very big text files (ie: log files). Index flush megabytes interval - 격증:flush - <p> 이것은 기본적으로 모든 분음 부호를 제거하고 정식 분해를 수행하는 unac 메커니즘에 대한 예외를 설정합니다. 언어에 따라 일부 문자의 강조를 무시, 추가, 분해를 지정할 수 있습니다(예 : 합자의 경우. 공백으로 구분된 각 항목에서 첫 번째 문자는 원본이고 나머지는 번역입니다). + 색인 정비 간격(MB) This value adjust the amount of data which is indexed between flushes to disk.<br>This helps control the indexer memory usage. Default 10MB diff --git a/src/testmains/Makefile.am b/src/testmains/Makefile.am index f13f6a53..0c22e234 100644 --- a/src/testmains/Makefile.am +++ b/src/testmains/Makefile.am @@ -38,11 +38,14 @@ AM_CPPFLAGS = -Wall -Wno-unused -std=c++11 \ $(DEFS) noinst_PROGRAMS = textsplit utf8iter fstreewalk rclconfig hldata unac mbox \ - circache wipedir + circache wipedir mimetype textsplit_SOURCES = trtextsplit.cpp textsplit_LDADD = ../librecoll.la +mimetype_SOURCES = trmimetype.cpp +mimetype_LDADD = ../librecoll.la + utf8iter_SOURCES = trutf8iter.cpp utf8iter_LDADD = ../librecoll.la diff --git a/src/testmains/trfstreewalk.cpp b/src/testmains/trfstreewalk.cpp index 0c749e46..0562f558 100644 --- a/src/testmains/trfstreewalk.cpp +++ b/src/testmains/trfstreewalk.cpp @@ -24,6 +24,7 @@ #include "rclinit.h" #include "rclconfig.h" +#include "pathut.h" using namespace std; @@ -47,25 +48,25 @@ static int op_flags; class myCB : public FsTreeWalkerCB { public: FsTreeWalker::Status processone(const string &path, - const struct stat *st, + const struct PathStat *st, FsTreeWalker::CbFlag flg) { - if (flg == FsTreeWalker::FtwDirEnter) { - if (op_flags & OPT_r) { - cout << path << endl; - } else { - if (!(op_flags&OPT_s)) { - cout << "[Entering " << path << "]" << endl; - } - } - } else if (flg == FsTreeWalker::FtwDirReturn) { - if (!(op_flags&OPT_s)) { - cout << "[Returning to " << path << "]" << endl; - } - } else if (flg == FsTreeWalker::FtwRegular) { + if (flg == FsTreeWalker::FtwDirEnter) { + if (op_flags & OPT_r) { cout << path << endl; + } else { + if (!(op_flags&OPT_s)) { + cout << "[Entering " << path << "]" << endl; + } } - return FsTreeWalker::FtwOk; + } else if (flg == FsTreeWalker::FtwDirReturn) { + if (!(op_flags&OPT_s)) { + cout << "[Returning to " << path << "]" << endl; + } + } else if (flg == FsTreeWalker::FtwRegular) { + cout << path << endl; } + return FsTreeWalker::FtwOk; + } }; static const char *thisprog; @@ -89,22 +90,22 @@ static const char *thisprog; // real 17m10.585s user 0m4.532s sys 0m35.033s static char usage [] = -"trfstreewalk [-p pattern] [-P ignpath] [-r] [-c] [-L] topdir\n" -" -D : skip dotfiles\n" -" -L : follow symbolic links\n" -" -M : limit depth (works with -b/m/d)\n" -" -P : add skippedPaths entry\n" -" -p : add skippedNames entry\n" -" -b : use breadth first walk\n" -" -c : no path canonification\n" -" -d : use almost depth first (dir files, then subdirs)\n" -" -k : like du\n" -" -m : use breadth up to 4 deep then switch to -d\n" -" -r : norecurse\n" -" -s : don't print dir change info\n" -" -w : unset default FNM_PATHNAME when using fnmatch() to match skipped paths\n" -" -y : add onlyNames entry\n" -; + "trfstreewalk [-p pattern] [-P ignpath] [-r] [-c] [-L] topdir\n" + " -D : skip dotfiles\n" + " -L : follow symbolic links\n" + " -M : limit depth (works with -b/m/d)\n" + " -P : add skippedPaths entry\n" + " -p : add skippedNames entry\n" + " -b : use breadth first walk\n" + " -c : no path canonification\n" + " -d : use almost depth first (dir files, then subdirs)\n" + " -k : like du\n" + " -m : use breadth up to 4 deep then switch to -d\n" + " -r : norecurse\n" + " -s : don't print dir change info\n" + " -w : unset default FNM_PATHNAME when using fnmatch() to match skipped paths\n" + " -y : add onlyNames entry\n" + ; static void Usage(void) { diff --git a/src/testmains/trmimetype.cpp b/src/testmains/trmimetype.cpp new file mode 100644 index 00000000..e613e542 --- /dev/null +++ b/src/testmains/trmimetype.cpp @@ -0,0 +1,38 @@ +#include "mimetype.h" + +#include + +#include +#include + +#include "log.h" +#include "rclconfig.h" +#include "rclinit.h" +#include "pathut.h" + +using namespace std; +int main(int argc, const char **argv) +{ + string reason; + RclConfig *config = recollinit(0, 0, 0, reason); + + if (config == 0 || !config->ok()) { + string str = "Configuration problem: "; + str += reason; + fprintf(stderr, "%s\n", str.c_str()); + exit(1); + } + + while (--argc > 0) { + string filename = *++argv; + struct PathStat st; + if (path_fileprops(filename, &st)) { + fprintf(stderr, "Can't stat %s\n", filename.c_str()); + continue; + } + cout << filename << " -> " << + mimetype(filename, &st, config, true) << endl; + + } + return 0; +} diff --git a/src/utils/appformime.cpp b/src/utils/appformime.cpp index 80a2230c..14747371 100644 --- a/src/utils/appformime.cpp +++ b/src/utils/appformime.cpp @@ -37,12 +37,13 @@ public: { } virtual FsTreeWalker::Status - processone(const string &, const struct stat *, FsTreeWalker::CbFlag); + processone(const string &, const struct PathStat *, FsTreeWalker::CbFlag); DesktopDb::AppMap *m_appdefs; }; -FsTreeWalker::Status FstCb::processone(const string& fn, const struct stat *, - FsTreeWalker::CbFlag flg) +struct PathStat; +FsTreeWalker::Status FstCb::processone( + const string& fn, const struct PathStat*, FsTreeWalker::CbFlag flg) { if (flg != FsTreeWalker::FtwRegular) return FsTreeWalker::FtwOk; diff --git a/src/utils/fstreewalk.cpp b/src/utils/fstreewalk.cpp index bbd5aaa5..e3bf03f7 100644 --- a/src/utils/fstreewalk.cpp +++ b/src/utils/fstreewalk.cpp @@ -21,7 +21,6 @@ #include #include #include -#include "safesysstat.h" #include #include @@ -228,8 +227,7 @@ static inline int slashcount(const string& p) return n; } -FsTreeWalker::Status FsTreeWalker::walk(const string& _top, - FsTreeWalkerCB& cb) +FsTreeWalker::Status FsTreeWalker::walk(const string& _top, FsTreeWalkerCB& cb) { string top = (data->options & FtwNoCanon) ? _top : path_canon(_top); @@ -238,7 +236,7 @@ FsTreeWalker::Status FsTreeWalker::walk(const string& _top, } data->basedepth = slashcount(top); // Only used for breadthxx - struct stat st; + struct PathStat st; // We always follow symlinks at this point. Makes more sense. if (path_fileprops(top, &st) == -1) { // Note that we do not return an error if the stat call @@ -343,19 +341,19 @@ FsTreeWalker::Status FsTreeWalker::walk(const string& _top, // This means that we always go into the top 'walk()' parameter if it is a // directory, even if norecurse is set. Bug or Feature ? FsTreeWalker::Status FsTreeWalker::iwalk(const string &top, - struct stat *stp, + struct PathStat *stp, FsTreeWalkerCB& cb) { Status status = FtwOk; bool nullpush = false; // Tell user to process the top entry itself - if (S_ISDIR(stp->st_mode)) { + if (stp->pst_type == PathStat::PST_DIR) { if ((status = cb.processone(top, stp, FtwDirEnter)) & (FtwStop|FtwError)) { return status; } - } else if (S_ISREG(stp->st_mode)) { + } else if (stp->pst_type == PathStat::PST_REGULAR) { return cb.processone(top, stp, FtwRegular); } else { return status; @@ -377,7 +375,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top, // For now, we'll ignore the "other kind of cycle" part and only monitor // this is FtwFollow is set if (data->options & FtwFollow) { - DirId dirid(stp->st_dev, stp->st_ino); + DirId dirid(stp->pst_dev, stp->pst_ino); if (data->donedirs.find(dirid) != data->donedirs.end()) { LOGINFO("Not processing [" << top << "] (already seen as other path)\n"); @@ -420,7 +418,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top, struct DIRENT *ent; while (errno = 0, ((ent = READDIR(d)) != 0)) { string fn; - struct stat st; + struct PathStat st; #ifdef _WIN32 string sdname; if (!wchartoutf8(ent->d_name, sdname)) { @@ -468,7 +466,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top, continue; } - if (S_ISDIR(st.st_mode)) { + if (st.pst_type == PathStat::PST_DIR) { if (!o_nowalkfn.empty() && path_exists(path_cat(fn, o_nowalkfn))) { continue; } @@ -498,7 +496,8 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top, if ((status = cb.processone(top, &st, FtwDirReturn)) & (FtwStop|FtwError)) goto out; - } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { + } else if (st.pst_type == PathStat::PST_REGULAR || + st.pst_type == PathStat::PST_SYMLINK) { // Filtering patterns match ? if (!data->onlyNames.empty()) { if (!inOnlyNames(dname)) @@ -536,14 +535,14 @@ int64_t fsTreeBytes(const string& topdir) class bytesCB : public FsTreeWalkerCB { public: FsTreeWalker::Status processone(const string &path, - const struct stat *st, + const struct PathStat *st, FsTreeWalker::CbFlag flg) { if (flg == FsTreeWalker::FtwDirEnter || flg == FsTreeWalker::FtwRegular) { #ifdef _WIN32 - totalbytes += st->st_size; + totalbytes += st->pst_size; #else - totalbytes += st->st_blocks * 512; + totalbytes += st->pst_blocks * 512; #endif } return FsTreeWalker::FtwOk; diff --git a/src/utils/fstreewalk.h b/src/utils/fstreewalk.h index 35fa7172..d02f7ae6 100644 --- a/src/utils/fstreewalk.h +++ b/src/utils/fstreewalk.h @@ -19,13 +19,10 @@ #include #include -#ifndef NO_NAMESPACES -using std::string; -using std::vector; -#endif + +struct PathStat; class FsTreeWalkerCB; -struct stat; /** * Class implementing a unix directory recursive walk. @@ -44,8 +41,7 @@ class FsTreeWalker { // to not use the flag, which can be set from rclconfig by adding // a value to the config file (skippedPathsNoFnmPathname) static bool o_useFnmPathname; - static void setNoFnmPathname() - { + static void setNoFnmPathname() { o_useFnmPathname = false; } @@ -53,8 +49,7 @@ class FsTreeWalker { // directories as if they were in skippedPaths) if the file exists // inside the directory. static std::string o_nowalkfn; - static void setNoWalkFn(const std::string& nowalkfn) - { + static void setNoWalkFn(const std::string& nowalkfn) { o_nowalkfn = nowalkfn; } @@ -97,34 +92,35 @@ class FsTreeWalker { * @param cb the function object that will be called back for every * file-system object (called both at entry and exit for directories). */ - Status walk(const string &dir, FsTreeWalkerCB& cb); + Status walk(const std::string &dir, FsTreeWalkerCB& cb); /** Get explanation for error */ - string getReason(); + std::string getReason(); int getErrCnt(); /** * Add a pattern (file or dir) to be ignored (ie: #* , *~) */ - bool addSkippedName(const string &pattern); + bool addSkippedName(const std::string &pattern); /** Set the ignored patterns set */ - bool setSkippedNames(const vector &patterns); + bool setSkippedNames(const std::vector &patterns); /** Set the exclusive patterns set */ - bool setOnlyNames(const vector &patterns); + bool setOnlyNames(const std::vector &patterns); /** Same for skipped paths: this are paths, not names, under which we do not descend (ie: /home/me/.recoll) */ - bool addSkippedPath(const string &path); + bool addSkippedPath(const std::string &path); /** Set the ignored paths list */ - bool setSkippedPaths(const vector &patterns); + bool setSkippedPaths(const std::vector &patterns); /** Test if path/name should be skipped. This can be used independently of * an actual tree walk */ - bool inSkippedPaths(const string& path, bool ckparents = false); - bool inSkippedNames(const string& name); - bool inOnlyNames(const string& name); + bool inSkippedPaths(const std::string& path, bool ckparents = false); + bool inSkippedNames(const std::string& name); + bool inOnlyNames(const std::string& name); private: - Status iwalk(const string &dir, struct stat *stp, FsTreeWalkerCB& cb); + Status iwalk(const std::string &dir, struct PathStat *stp, + FsTreeWalkerCB& cb); class Internal; Internal *data; }; @@ -134,11 +130,11 @@ class FsTreeWalkerCB { virtual ~FsTreeWalkerCB() {} // Only st_mtime, st_ctime, st_size, st_mode (filetype bits: dir/reg/lnk), virtual FsTreeWalker::Status - processone(const string &, const struct stat *, FsTreeWalker::CbFlag) - = 0; + processone(const std::string&, const struct PathStat *, + FsTreeWalker::CbFlag) = 0; }; // Utility function. Somewhat like du. -int64_t fsTreeBytes(const string& topdir); +int64_t fsTreeBytes(const std::string& topdir); #endif /* _FSTREEWALK_H_INCLUDED_ */ diff --git a/src/utils/pathut.cpp b/src/utils/pathut.cpp index f52bdd98..4e21e6e7 100644 --- a/src/utils/pathut.cpp +++ b/src/utils/pathut.cpp @@ -684,11 +684,12 @@ bool path_makepath(const string& ipath, int mode) return true; } -bool path_isdir(const string& path) +bool path_isdir(const string& path, bool follow) { struct STATBUF st; SYSPATH(path, syspath); - if (LSTAT(syspath, &st) < 0) { + int ret = follow ? STAT(syspath, &st) : LSTAT(syspath, &st); + if (ret < 0) { return false; } if (S_ISDIR(st.st_mode)) { @@ -697,6 +698,20 @@ bool path_isdir(const string& path) return false; } +bool path_isfile(const string& path, bool follow) +{ + struct STATBUF st; + SYSPATH(path, syspath); + int ret = follow ? STAT(syspath, &st) : LSTAT(syspath, &st); + if (ret < 0) { + return false; + } + if (S_ISREG(st.st_mode)) { + return true; + } + return false; +} + long long path_filesize(const string& path) { struct STATBUF st; @@ -707,30 +722,36 @@ long long path_filesize(const string& path) return (long long)st.st_size; } -int path_fileprops(const std::string path, struct stat *stp, bool follow) +int path_fileprops(const std::string path, struct PathStat *stp, bool follow) { - if (!stp) { + if (nullptr == stp) { return -1; } - memset(stp, 0, sizeof(struct stat)); + memset(stp, 0, sizeof(struct PathStat)); struct STATBUF mst; SYSPATH(path, syspath); int ret = follow ? STAT(syspath, &mst) : LSTAT(syspath, &mst); if (ret != 0) { return ret; } - stp->st_size = mst.st_size; - stp->st_mode = mst.st_mode; - stp->st_mtime = mst.st_mtime; + stp->pst_size = mst.st_size; + stp->pst_mode = mst.st_mode; + stp->pst_mtime = mst.st_mtime; #ifdef _WIN32 - stp->st_ctime = mst.st_mtime; + stp->pst_ctime = mst.st_mtime; #else - stp->st_ino = mst.st_ino; - stp->st_dev = mst.st_dev; - stp->st_ctime = mst.st_ctime; - stp->st_blocks = mst.st_blocks; - stp->st_blksize = mst.st_blksize; + stp->pst_ino = mst.st_ino; + stp->pst_dev = mst.st_dev; + stp->pst_ctime = mst.st_ctime; + stp->pst_blocks = mst.st_blocks; + stp->pst_blksize = mst.st_blksize; #endif + switch (mst.st_mode & S_IFMT) { + case S_IFDIR: stp->pst_type = PathStat::PST_DIR;break; + case S_IFLNK: stp->pst_type = PathStat::PST_SYMLINK;break; + case S_IFREG: stp->pst_type = PathStat::PST_REGULAR;break; + default: stp->pst_type = PathStat::PST_OTHER;break; + } return 0; } diff --git a/src/utils/pathut.h b/src/utils/pathut.h index eccaef43..91b48e40 100644 --- a/src/utils/pathut.h +++ b/src/utils/pathut.h @@ -20,6 +20,7 @@ #include #include #include +#include // Must be called in main thread before starting other threads extern void pathut_init_mt(); @@ -66,7 +67,9 @@ extern std::string url_parentfolder(const std::string& url); extern std::string url_gpath(const std::string& url); /// Stat parameter and check if it's a directory -extern bool path_isdir(const std::string& path); +extern bool path_isdir(const std::string& path, bool follow = false); +/// Stat parameter and check if it's a regular file +extern bool path_isfile(const std::string& path, bool follow = false); /// Retrieve file size extern long long path_filesize(const std::string& path); @@ -79,8 +82,19 @@ extern long long path_filesize(const std::string& path); /// all systems. st_dev and st_ino are set for special posix usage. /// The rest is zeroed. /// @ret 0 for success -struct stat; -extern int path_fileprops(const std::string path, struct stat *stp, +struct PathStat { + enum PstType {PST_REGULAR, PST_SYMLINK, PST_DIR, PST_OTHER}; + PstType pst_type; + int64_t pst_size; + uint64_t pst_mode; + int64_t pst_mtime; + int64_t pst_ctime; + uint64_t pst_ino; + uint64_t pst_dev; + uint64_t pst_blocks; + uint64_t pst_blksize; +}; +extern int path_fileprops(const std::string path, struct PathStat *stp, bool follow = true); /// Check that path is traversable and last element exists @@ -150,9 +164,6 @@ public: /// Convert \ separators to / void path_slashize(std::string& s); void path_backslashize(std::string& s); -#include "safeunistd.h" -#else -#include #endif /// Lock/pid file class. This is quite close to the pidfile_xxx