diff --git a/src/common/beaglequeuecache.cpp b/src/common/beaglequeuecache.cpp index 939368d1..99b165b5 100644 --- a/src/common/beaglequeuecache.cpp +++ b/src/common/beaglequeuecache.cpp @@ -35,7 +35,7 @@ BeagleQueueCache::BeagleQueueCache(RclConfig *cnf) ccdir = "webcache"; ccdir = path_tildexpand(ccdir); // If not an absolute path, compute relative to config dir - if (ccdir.at(0) != '/') + if (!path_isabsolute(ccdir)) ccdir = path_cat(cnf->getConfDir(), ccdir); int maxmbs = 40; diff --git a/src/common/rclconfig.cpp b/src/common/rclconfig.cpp index 50ede075..6636c389 100644 --- a/src/common/rclconfig.cpp +++ b/src/common/rclconfig.cpp @@ -150,7 +150,6 @@ RclConfig::RclConfig(const string *argcnf) // Compute our data dir name, typically /usr/local/share/recoll m_datadir = path_sharedatadir(); - fprintf(stderr, "RclConfig::RclConfig:: datadir: [%s]\n", m_datadir.c_str()); // We only do the automatic configuration creation thing for the default // config dir, not if it was specified through -c or RECOLL_CONFDIR bool autoconfdir = false; @@ -172,7 +171,6 @@ RclConfig::RclConfig(const string *argcnf) m_confdir = path_cat(path_homedata(), path_defaultrecollconfsubdir()); } } - fprintf(stderr, "RclConfig::RclConfig:: confdir: [%s]\n", m_confdir.c_str()); // Note: autoconfdir and isDefaultConfig() are normally the same. We just // want to avoid the imperfect test in isDefaultConfig() if we actually know diff --git a/src/common/rclinit.cpp b/src/common/rclinit.cpp index 0184dda8..5d17c9b1 100644 --- a/src/common/rclinit.cpp +++ b/src/common/rclinit.cpp @@ -112,7 +112,7 @@ RclConfig *recollinit(RclInitFlags flags, if (!logfilename.empty()) { logfilename = path_tildexpand(logfilename); // If not an absolute path or , compute relative to config dir - if (logfilename.at(0) != '/' && + if (!path_isabsolute(logfilename) && !DebugLog::DebugLog::isspecialname(logfilename.c_str())) { logfilename = path_cat(config->getConfDir(), logfilename); } diff --git a/src/index/fsindexer.cpp b/src/index/fsindexer.cpp index 43031fae..b6ad0513 100644 --- a/src/index/fsindexer.cpp +++ b/src/index/fsindexer.cpp @@ -258,7 +258,7 @@ static bool matchesSkipped(const vector& tdl, string canonpath = path_canon(path); string mpath = canonpath; string topdir; - while (mpath.length() > 1) { + while (!path_isroot(mpath)) { // we assume root not in skipped paths. for (vector::const_iterator it = tdl.begin(); it != tdl.end(); it++) { // the topdirs members are already canonized. @@ -280,7 +280,7 @@ static bool matchesSkipped(const vector& tdl, mpath = path_getfather(mpath); // getfather normally returns a path ending with /, canonic // paths don't (except for '/' itself). - if (!mpath.empty() && mpath[mpath.size()-1] == '/') + if (!path_isroot(mpath) && mpath[mpath.size()-1] == '/') mpath.erase(mpath.size()-1); // should not be necessary, but lets be prudent. If the // path did not shorten, something is seriously amiss diff --git a/src/index/rclmonrcv.cpp b/src/index/rclmonrcv.cpp index 1465fcac..1d616d75 100644 --- a/src/index/rclmonrcv.cpp +++ b/src/index/rclmonrcv.cpp @@ -469,7 +469,7 @@ bool RclFAM::getEvent(RclMonEvent& ev, int msecs) MONDEB(("RclFAM::getEvent: FAMNextEvent returned\n")); map::const_iterator it; - if ((fe.filename[0] != '/') && + if ((!path_isabsolute(fe.filename)) && (it = m_idtopath.find(fe.fr.reqnum)) != m_idtopath.end()) { ev.m_path = path_cat(it->second, fe.filename); } else { diff --git a/src/internfile/mh_mbox.cpp b/src/internfile/mh_mbox.cpp index b79c480d..d646cbef 100644 --- a/src/internfile/mh_mbox.cpp +++ b/src/internfile/mh_mbox.cpp @@ -196,7 +196,7 @@ public: m_dir = "mboxcache"; m_dir = path_tildexpand(m_dir); // If not an absolute path, compute relative to config dir - if (m_dir.at(0) != '/') + if (!path_isabsolute(m_dir)) m_dir = path_cat(config->getConfDir(), m_dir); m_ok = true; } diff --git a/src/rcldb/searchdatatox.cpp b/src/rcldb/searchdatatox.cpp index 0da1d770..fefbf1bd 100644 --- a/src/rcldb/searchdatatox.cpp +++ b/src/rcldb/searchdatatox.cpp @@ -961,7 +961,7 @@ bool SearchDataClausePath::toNativeQuery(Rcl::Db &db, void *p) vector orqueries; - if (m_text[0] == '/') + if (path_isabsolute(m_text)) orqueries.push_back(Xapian::Query(wrap_prefix(pathelt_prefix))); else m_text = path_tildexpand(m_text); diff --git a/src/utils/conftree.cpp b/src/utils/conftree.cpp index dcde3a5e..97956d87 100644 --- a/src/utils/conftree.cpp +++ b/src/utils/conftree.cpp @@ -574,8 +574,8 @@ bool ConfSimple::hasNameAnywhere(const string& nm) const int ConfTree::get(const std::string &name, string &value, const string &sk) const { - if (sk.empty() || sk[0] != '/') { - // LOGDEB((stderr, "ConfTree::get: looking in global space\n")); + if (sk.empty() || !path_isabsolute(sk) ) { + // LOGDEB((stderr, "ConfTree::get: looking in global space for sk [%s]\n", sk.c_str())); return ConfSimple::get(name, value, sk); } @@ -588,15 +588,21 @@ int ConfTree::get(const std::string &name, string &value, const string &sk) // Look in subkey and up its parents until root ('') for (;;) { - // LOGDEB((stderr,"ConfTree::get: looking for '%s' in '%s'\n", - // name.c_str(), msk.c_str())); + LOGDEB((stderr,"ConfTree::get: looking for '%s' in '%s'\n", + name.c_str(), msk.c_str())); if (ConfSimple::get(name, value, msk)) return 1; string::size_type pos = msk.rfind("/"); if (pos != string::npos) { msk.replace(pos, string::npos, string()); - } else + } else { +#ifdef _WIN32 + if (msk.size() == 2 && isalpha(msk[0]) && msk[1] == ':') + msk.clear(); + else +#endif break; + } } return 0; } diff --git a/src/utils/debuglog.cpp b/src/utils/debuglog.cpp index eb9c4ae2..da29ab6c 100644 --- a/src/utils/debuglog.cpp +++ b/src/utils/debuglog.cpp @@ -75,7 +75,7 @@ class DLFWImpl { } else { fp = fopen(filename, (truncate) ? "w" : "a"); if (fp) { - setvbuf(fp, 0, _IOLBF, 0); + setvbuf(fp, 0, _IOLBF, BUFSIZ); #ifdef O_APPEND { int flgs = 0; @@ -83,7 +83,10 @@ class DLFWImpl { fcntl(fileno(fp), F_SETFL, flgs|O_APPEND); } #endif - } + } else { + fprintf(stderr, "Debuglog: could not open [%s] errno %d\n", + filename, errno); + } } return; } diff --git a/src/utils/pathut.cpp b/src/utils/pathut.cpp index 493723d9..93b7eeff 100644 --- a/src/utils/pathut.cpp +++ b/src/utils/pathut.cpp @@ -380,10 +380,11 @@ string path_getfather(const string &s) { if (father.empty()) return "./"; + if (path_isroot(father)) + return father; + if (father[father.length() - 1] == '/') { - // Input ends with /. Strip it, handle special case for root - if (father.length() == 1) - return father; + // Input ends with /. Strip it, root special case was tested above father.erase(father.length()-1); } @@ -514,6 +515,17 @@ string path_tildexpand(const string &s) return o; } +bool path_isroot(const string& path) +{ + if (path.size() == 1 && path[0] == '/') + return true; +#ifdef _WIN32 + if (path.size == 3 && isalpha(path[0]) && path[1] == ':' && path[2] == '/') + return true; +#endif + return false; +} + bool path_isabsolute(const string &path) { if (!path.empty() && (path[0] == '/' diff --git a/src/utils/pathut.h b/src/utils/pathut.h index d4ebc15c..4fd6f1a6 100644 --- a/src/utils/pathut.h +++ b/src/utils/pathut.h @@ -111,6 +111,9 @@ extern const std::string& path_sharedatadir(); /// Test if path is absolute extern bool path_isabsolute(const std::string& s); +/// Test if path is root (x:/). root is defined by root/.. == root +extern bool path_isroot(const std::string& p); + /// Temporary file class class TempFileInternal { public: diff --git a/src/utils/readfile.cpp b/src/utils/readfile.cpp index a018ac9c..ce0721f6 100644 --- a/src/utils/readfile.cpp +++ b/src/utils/readfile.cpp @@ -78,6 +78,11 @@ const int RDBUFSZ = 8192; bool file_scan(const string &fn, FileScanDo* doer, off_t startoffs, size_t cnttoread, string *reason) { + if (startoffs < 0) { + *reason += " file_scan: negative startoffs not allowed"; + return false; + } + bool ret = false; bool noclosing = true; int fd = 0;