[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