[cpp-sp] branch main updated: Port over directory iteration from xmltooling.
Scott Cantor
cantor.2 at osu.edu
Mon Jun 23 12:47:44 UTC 2025
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository cpp-sp.
View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=60adbbfe761c1144cf8a9c42e70b7330ee712656
The following commit(s) were added to refs/heads/main by this push:
new 60adbbfe Port over directory iteration from xmltooling.
60adbbfe is described below
commit 60adbbfe761c1144cf8a9c42e70b7330ee712656
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Jun 23 08:47:36 2025 -0400
Port over directory iteration from xmltooling.
---
Projects/vc22/shibsp.vcxproj | 2 +
Projects/vc22/shibsp.vcxproj.filters | 14 +++-
shibsp/Makefile.am | 4 +-
shibsp/util/DirectoryWalker.cpp | 138 +++++++++++++++++++++++++++++++++++
shibsp/util/DirectoryWalker.h | 95 ++++++++++++++++++++++++
5 files changed, 248 insertions(+), 5 deletions(-)
diff --git a/Projects/vc22/shibsp.vcxproj b/Projects/vc22/shibsp.vcxproj
index ffeeb6c1..ab32eb91 100644
--- a/Projects/vc22/shibsp.vcxproj
+++ b/Projects/vc22/shibsp.vcxproj
@@ -72,6 +72,7 @@
<ClInclude Include="..\..\shibsp\util\BoostPropertySet.h" />
<ClInclude Include="..\..\shibsp\util\CGIParser.h" />
<ClInclude Include="..\..\shibsp\util\Date.h" />
+ <ClInclude Include="..\..\shibsp\util\DirectoryWalker.h" />
<ClInclude Include="..\..\shibsp\util\IPRange.h" />
<ClInclude Include="..\..\shibsp\util\Lockable.h" />
<ClInclude Include="..\..\shibsp\util\Misc.h" />
@@ -192,6 +193,7 @@
<ClCompile Include="..\..\shibsp\session\impl\MemorySessionCache.cpp" />
<ClCompile Include="..\..\shibsp\util\BoostPropertySet.cpp" />
<ClCompile Include="..\..\shibsp\util\CGIParser.cpp" />
+ <ClCompile Include="..\..\shibsp\util\DirectoryWalker.cpp" />
<ClCompile Include="..\..\shibsp\util\IPRange.cpp" />
<ClCompile Include="..\..\shibsp\util\Misc.cpp" />
<ClCompile Include="..\..\shibsp\util\PathResolver.cpp" />
diff --git a/Projects/vc22/shibsp.vcxproj.filters b/Projects/vc22/shibsp.vcxproj.filters
index 8cae4aab..2fedd7ac 100644
--- a/Projects/vc22/shibsp.vcxproj.filters
+++ b/Projects/vc22/shibsp.vcxproj.filters
@@ -150,9 +150,6 @@
<ClInclude Include="..\..\shibsp\util\CGIParser.h">
<Filter>Header Files\Util</Filter>
</ClInclude>
- <ClInclude Include="..\..\shibsp\util\IPRange.h">
- <Filter>Header Files\Util</Filter>
- </ClInclude>
<ClInclude Include="..\..\shibsp\util\Lockable.h">
<Filter>Header Files\Util</Filter>
</ClInclude>
@@ -231,6 +228,12 @@
<ClInclude Include="..\..\shibsp\util\Date.h">
<Filter>Header Files\Impl</Filter>
</ClInclude>
+ <ClInclude Include="..\..\shibsp\util\DirectoryWalker.h">
+ <Filter>Header Files\Impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\shibsp\util\IPRange.h">
+ <Filter>Header Files\Util</Filter>
+ </ClInclude>
<ClInclude Include="..\..\shibsp\csprng\csprng.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -320,6 +323,9 @@
<ClCompile Include="..\..\shibsp\util\CGIParser.cpp">
<Filter>Source Files\Util</Filter>
</ClCompile>
+ <ClCompile Include="..\..\shibsp\util\DirectoryWalker.cpp">
+ <Filter>Source Files\Util</Filter>
+ </ClCompile>
<ClCompile Include="..\..\shibsp\util\IPRange.cpp">
<Filter>Source Files\Util</Filter>
</ClCompile>
@@ -418,4 +424,4 @@
<Filter>Resource Files</Filter>
</CustomBuild>
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index 2fcf4d6f..07d6884d 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -76,7 +76,6 @@ sessioninclude_HEADERS = \
utilinclude_HEADERS = \
util/BoostPropertySet.h \
util/CGIParser.h \
- util/IPRange.h \
util/Lockable.h \
util/PathResolver.h \
util/PluginManager.h \
@@ -96,6 +95,8 @@ noinst_HEADERS = \
remoting/impl/AbstractRemotingService.h \
remoting/impl/AbstractHTTPRemotingService.h \
util/Date.h \
+ util/DirectoryWalker.h \
+ util/IPRange.h \
util/Misc.h
libshibsp_la_SOURCES = \
@@ -146,6 +147,7 @@ libshibsp_la_SOURCES = \
session/impl/MemorySessionCache.cpp \
util/BoostPropertySet.cpp \
util/CGIParser.cpp \
+ util/DirectoryWalker.cpp \
util/IPRange.cpp \
util/Misc.cpp \
util/PathResolver.cpp \
diff --git a/shibsp/util/DirectoryWalker.cpp b/shibsp/util/DirectoryWalker.cpp
new file mode 100644
index 00000000..eda12b8a
--- /dev/null
+++ b/shibsp/util/DirectoryWalker.cpp
@@ -0,0 +1,138 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * util/DirectoryWalker.cpp
+ *
+ * Iterates over directory entries.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "util/DirectoryWalker.h"
+
+#ifdef WIN32
+# include <windows.h>
+#else
+# include <boost/algorithm/string.hpp>
+# if defined(HAVE_SYS_TYPES_H) && defined(HAVE_DIRENT_H)
+# include <dirent.h>
+# include <sys/types.h>
+# else
+# error Unsupported directory library headers.
+# endif
+#endif
+
+using namespace shibsp;
+using namespace std;
+
+DirectoryWalker::DirectoryWalker(Category& log, const char* path, bool recurse)
+ : m_log(log), m_path(path), m_recurse(recurse)
+{
+}
+
+DirectoryWalker::~DirectoryWalker()
+{
+}
+
+void DirectoryWalker::_walk(
+ const char* path, const DirectoryWalkerCallback& callback_fn, void* callback_data, const char* startsWith, const char* endsWith
+ ) const
+{
+#ifdef WIN32
+ string searchpath = string(path) + '/';
+ if (startsWith)
+ searchpath += startsWith;
+ searchpath += '*';
+ if (endsWith)
+ searchpath += endsWith;
+ m_log.debug("searching path (%s)", searchpath.c_str());
+
+ WIN32_FIND_DATA f;
+ HANDLE h = FindFirstFile(searchpath.c_str(), &f);
+ if (h == INVALID_HANDLE_VALUE) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ m_log.warn("Unable to open directory (%s)", path);
+ else
+ m_log.debug("no matching entries in directory (%s)", path);
+ return;
+ }
+ do {
+ if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ if (!strcmp(f.cFileName, ".") || !strcmp(f.cFileName, ".."))
+ continue;
+ if (m_recurse) {
+ m_log.debug("processing nested directory (%s)", f.cFileName);
+ string nested = string(path) + '/' + f.cFileName;
+ _walk(nested.c_str(), callback_fn, callback_data, startsWith, endsWith);
+ }
+ else {
+ m_log.debug("recursion disabled, skipping nested directory (%s)", f.cFileName);
+ }
+ }
+ else {
+ string fullname = string(path) + '/' + f.cFileName;
+ struct stat stat_buf;
+ if (stat(fullname.c_str(), &stat_buf) == 0) {
+ m_log.debug("invoking callback for file (%s)", fullname.c_str());
+ callback_fn(fullname.c_str(), stat_buf, callback_data);
+ }
+ else {
+ m_log.warn("unable to access (%s)", fullname.c_str());
+ }
+ }
+ } while (FindNextFile(h, &f));
+ FindClose(h);
+#else
+ DIR* d = opendir(path);
+ if (!d) {
+ m_log.warn("Unable to open directory (%s)", path);
+ return;
+ }
+ char dir_buf[sizeof(struct dirent) + PATH_MAX];
+ struct dirent* ent = (struct dirent*)dir_buf;
+ struct dirent* entptr = nullptr;
+ while (readdir_r(d, ent, &entptr) == 0 && entptr) {
+ if (!strcmp(entptr->d_name, ".") || !strcmp(entptr->d_name, ".."))
+ continue;
+ else if (startsWith || endsWith) {
+ string fname(entptr->d_name);
+ if ((startsWith && !boost::algorithm::starts_with(fname, startsWith)) ||
+ (endsWith && !boost::algorithm::ends_with(fname, endsWith))) {
+ continue;
+ }
+ }
+
+ string fullname = string(path) + '/' + entptr->d_name;
+ struct stat stat_buf;
+ if (stat(fullname.c_str(), &stat_buf) != 0) {
+ m_log.warn("unable to access (%s)", fullname.c_str());
+ }
+ else if (S_ISDIR(stat_buf.st_mode)) {
+ if (m_recurse) {
+ m_log.debug("processing nested directory (%s)", entptr->d_name);
+ _walk(fullname.c_str(), callback_fn, callback_data, startsWith, endsWith);
+ }
+ else {
+ m_log.debug("recursion disabled, skipping nested directory (%s)", entptr->d_name);
+ }
+ }
+ else {
+ m_log.debug("invoking callback for file (%s)", fullname.c_str());
+ callback_fn(fullname.c_str(), stat_buf, callback_data);
+ }
+ }
+ closedir(d);
+#endif
+ }
diff --git a/shibsp/util/DirectoryWalker.h b/shibsp/util/DirectoryWalker.h
new file mode 100644
index 00000000..d64d9625
--- /dev/null
+++ b/shibsp/util/DirectoryWalker.h
@@ -0,0 +1,95 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file shibsp/util/DirectoryWalker.h
+ *
+ * Iterates over directory entries.
+ */
+
+#if !defined(__shibsp_dirwalk_h__)
+#define __shibsp_dirwalk_h__
+
+#include <logging/Category.h>
+
+#include <string>
+#include <sys/stat.h>
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+# pragma warning( push )
+# pragma warning( disable : 4251 )
+#endif
+
+ /**
+ * Portable directory walker that invokes a callback function for every file in a
+ * directory, optionally doing depth-first recursion of nested directories.
+ */
+ class SHIBSP_API DirectoryWalker
+ {
+ MAKE_NONCOPYABLE(DirectoryWalker);
+ public:
+
+ /**
+ * Constructor.
+ *
+ * @param log log category
+ * @param path directory path to walk
+ * @param recurse true iff nested directories should be processed
+ */
+ DirectoryWalker(Category& log, const char* path, bool recurse=false);
+
+ virtual ~DirectoryWalker();
+
+ /** Callback function, passed the file pathname, stat buffer, and optional callback data. */
+ typedef void (*DirectoryWalkerCallback)(const char* pathname, struct stat& stat_buf, void* data);
+
+ /**
+ * Perform a depth-first traversal of the directory.
+ *
+ * @param callback_fn callback function to invoke for each match
+ * @param callback_data optional pointer to pass to callback
+ * @param startsWith optional prefix matching, skipping non-matching entries
+ * @param endsWith optional suffix matching, skipping non-matching entries
+ */
+ void walk(
+ const DirectoryWalkerCallback& callback_fn,
+ void* callback_data = nullptr,
+ const char* startsWith = nullptr,
+ const char* endsWith = nullptr
+ ) const {
+ _walk(m_path.c_str(), callback_fn, callback_data, startsWith, endsWith);
+ }
+
+ private:
+ void _walk(
+ const char* path,
+ const DirectoryWalkerCallback& callback_fn,
+ void* callback_data = nullptr,
+ const char* startsWith = nullptr,
+ const char* endsWith = nullptr
+ ) const;
+
+ Category& m_log;
+ std::string m_path;
+ bool m_recurse;
+ };
+
+#if defined (_MSC_VER)
+# pragma warning( pop )
+#endif
+};
+
+#endif /* __shibsp_dirwalk_h__ */
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list