10#include <botan/internal/proc_walk.h>
13#ifndef _POSIX_C_SOURCE
14 #define _POSIX_C_SOURCE 199309
27class Directory_Walker
final :
public File_Descriptor_Source
30 explicit Directory_Walker(
const std::string& root) :
31 m_cur_dir(std::make_pair<DIR*, std::string>(
nullptr,
""))
33 if(DIR* root_dir = ::opendir(root.c_str()))
34 m_cur_dir = std::make_pair(root_dir, root);
40 ::closedir(m_cur_dir.first);
43 int next_fd()
override;
45 std::pair<struct dirent*, std::string> get_next_dirent();
47 std::pair<DIR*, std::string> m_cur_dir;
48 std::deque<std::string> m_dirlist;
51std::pair<struct dirent*, std::string> Directory_Walker::get_next_dirent()
53 while(m_cur_dir.first)
55 if(
struct dirent* dir = ::readdir(m_cur_dir.first))
56 return std::make_pair(dir, m_cur_dir.second);
58 ::closedir(m_cur_dir.first);
59 m_cur_dir = std::make_pair<DIR*, std::string>(
nullptr,
"");
61 while(!m_dirlist.empty() && !m_cur_dir.first)
63 const std::string next_dir_name = m_dirlist[0];
64 m_dirlist.pop_front();
66 if(DIR* next_dir = ::opendir(next_dir_name.c_str()))
67 m_cur_dir = std::make_pair(next_dir, next_dir_name);
71 return std::make_pair<struct dirent*, std::string>(
nullptr,
"");
74int Directory_Walker::next_fd()
78 std::pair<struct dirent*, std::string> entry = get_next_dirent();
83 const std::string filename = entry.first->d_name;
85 if(filename ==
"." || filename ==
"..")
88 const std::string full_path = entry.second +
"/" + filename;
91 if(::lstat(full_path.c_str(), &stat_buf) == -1)
94 if(S_ISDIR(stat_buf.st_mode))
96 m_dirlist.push_back(full_path);
98 else if(S_ISREG(stat_buf.st_mode) && (stat_buf.st_mode & S_IROTH))
100 int fd = ::open(full_path.c_str(), O_RDONLY |
O_NOCTTY);
114 const size_t MAX_FILES_READ_PER_POLL = 2048;
119 m_dir.reset(
new Directory_Walker(m_path));
125 for(
size_t i = 0; i != MAX_FILES_READ_PER_POLL; ++i)
127 int fd = m_dir->next_fd();
136 ssize_t got = ::read(fd, m_buf.data(), m_buf.size());
141 rng.
add_entropy(m_buf.data(),
static_cast<size_t>(got));
size_t poll(RandomNumberGenerator &rng) override
virtual void add_entropy(const uint8_t input[], size_t length)=0
int(* final)(unsigned char *, CTX *)