36 #include <sys/types.h>
65 DirWrapper(
const string& fullDirPath)
67 , _fullPath(fullDirPath)
70 _pDir = opendir(fullDirPath.c_str());
96 std::string _fullPath;
102 , _basename(basename)
143 struct tm* pTM = gmtime(&_modTime);
146 strftime(buf, 128,
"%F %T", pTM);
153 if (_fullPath.empty())
155 _fullPath = _path +
"/" + _basename;
164 " isDir=" + ((
isDir())?(
"true"):(
"false")) +
171 const string DirectoryUtil::_sDebugChannel =
"agg_util";
177 , _filteringModTimes(false)
203 bool allowRelativePaths,
208 throw BESForbiddenError(
"can't use rootDir=" + origRootDir +
" since it has a relative path (../)", __FILE__, __LINE__);
212 _rootDir = origRootDir;
237 _pRegExp =
new libdap::Regex(regexp.c_str());
244 delete _pRegExp; _pRegExp = 0;
250 _newestModTime = newestModTime;
251 _filteringModTimes =
true;
256 std::vector<FileInfo>* pRegularFiles,
257 std::vector<FileInfo>* pDirectories)
259 string pathToUse(path);
262 BESDEBUG(_sDebugChannel,
"Attempting to get dir listing for path=\"" << pathToUse <<
"\"" << endl);
265 DirWrapper pDir(pathToUse);
268 throwErrorForOpendirFail(pathToUse);
273 struct dirent* pDirEnt = 0;
274 while ( (pDirEnt = readdir(pDir.get())) != 0)
276 string entryName = pDirEnt->d_name;
278 if (!entryName.empty() && entryName[0] ==
'.')
284 string pathToEntry = pathToUse +
"/" + entryName;
286 int statResult = stat(pathToEntry.c_str(), &statBuf);
296 if (pDirectories && S_ISDIR(statBuf.st_mode))
298 pDirectories->push_back(
FileInfo(path, entryName,
true, statBuf.st_mtime ));
300 else if (pRegularFiles && S_ISREG(statBuf.st_mode))
302 FileInfo theFile(path, entryName,
false, statBuf.st_mtime);
304 if (matchesAllFilters(theFile.
getFullPath(), statBuf.st_mtime ))
306 pRegularFiles->push_back(theFile);
314 std::vector<FileInfo>* pRegularFiles,
315 std::vector<FileInfo>* pDirectories)
318 string canonicalPath = path;
325 vector<FileInfo> dirs;
335 pDirectories->insert(pDirectories->end(), dirs.begin(), dirs.end());
339 for (vector<FileInfo>::const_iterator it = dirs.begin();
343 string subPath = canonicalPath +
"/" + it->basename();
344 BESDEBUG(_sDebugChannel,
"DirectoryUtil: recursing down to directory subtree=\"" <<
345 subPath <<
"\"..." << endl);
354 std::vector<FileInfo>& rRegularFiles)
361 DirectoryUtil::throwErrorForOpendirFail(
const string& fullPath)
367 string msg =
"Permission denied for some directory in path=\"" + fullPath +
"\"";
374 string msg =
"A symlink loop was detected in path=\"" + fullPath +
"\"";
381 string msg =
"A name in the path was too long. path=\"" + fullPath +
"\"";
388 string msg =
"Some part of the path was not found. path=\"" + fullPath +
"\"";
395 string msg =
"Some part of the path was not a directory. path=\"" + fullPath +
"\"";
402 string msg =
"Internal Error: Too many files are currently open!";
409 string msg =
"An unknown errno was found after opendir() was called on path=\"" + fullPath +
"\"";
416 DirectoryUtil::matchesAllFilters(
const std::string& path, time_t modTime)
const
426 if (matches && _pRegExp)
429 int numCharsMatching = _pRegExp->match(path.c_str(), path.size(), 0);
430 matches = (numCharsMatching > 0);
433 if (matches && _filteringModTimes)
435 matches = (modTime < _newestModTime);
444 return (path.find(
"..") != string::npos);
452 string::size_type pos = path.find_last_not_of(
"/");
453 if (pos != string::npos)
455 path = path.substr(0, pos+1);
465 string::size_type pos = path.find_first_not_of(
"/");
466 path = path.substr(pos, string::npos);
473 std::ostringstream oss;
475 BESDEBUG(_sDebugChannel, oss.str() << endl);
481 for (vector<FileInfo>::const_iterator it = listing.begin();
485 os << it->toString() << endl;
512 bool matches = (filename.find(suffix, filename.size() - suffix.size()) != string::npos);
error thrown if the resource requested cannot be found
Class to hold info on files as we get them.
FileInfo(const std::string &path, const std::string &basename, bool isDir, time_t modTime)
strips any trailing "/" on path.
void getListingOfRegularFilesRecursive(const std::string &path, std::vector< FileInfo > &rRegularFiles)
Get recursive listing of all regular files in the directory subtree.
const std::string & basename() const
const std::string & getFullPath() const
Get the path and basename as path + "/" + basename We cache this after first call to allow for a cons...
void setFilterRegExp(const std::string ®exp)
Set a (GNU style) regular expression to be used to match against the full filename (relative path und...
exception thrown if inernal error encountered
const std::string & path() const
does not include trailing "/"
string basename(const string &path)
void getListingForPath(const std::string &path, std::vector< FileInfo > *pRegularFiles, std::vector< FileInfo > *pDirectories)
Get a listing of all the regular files and directories in the given path, which is assumed relative t...
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...
static bool matchesSuffix(const std::string &filename, const std::string &suffix)
std::string toString() const
std::string getModTimeAsString() const
Get a human readable string for the modTime()
void setFilterSuffix(const std::string &suffix)
Set the filter to be used for the nexy getListingForPath() call.
static std::string getBESRootDir()
Gets the BES root directory by checking the bes.conf settings for BES.
static void removeTrailingSlashes(std::string &path)
mutate to remove all trailing "/"
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
error thrown if the BES is not allowed to access the resource requested
void setFilterModTimeOlderThan(time_t newestModTime)
Set a filter on the modification time of the files to be returned in a listing.
void clearRegExp()
Remove any filter using a regular expression.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
const std::string & getRootDir() const
get the current root dir
void setRootDir(const std::string &rootDir, bool allowRelativePaths=false, bool allowSymLinks=false)
Makes sure the directory exists and is readable or throws an exception exception. ...
static void check_path(const string &path, const string &root, bool follow_sym_links)
Check if the specified path is valid.
static BESKeys * TheKeys()
static void removePrecedingSlashes(std::string &path)
mutate to remove and preceding (in the front) "/"
void getListingForPathRecursive(const std::string &path, std::vector< FileInfo > *pRegularFiles, std::vector< FileInfo > *pDirectories)
Get the listing for the path recursing into every directory found until it bottoms out...
static void printFileInfoList(std::ostream &os, const std::vector< FileInfo > &listing)
Print the list of files to the stream.
static bool hasRelativePath(const std::string &path)
Is there a "../" in path?