8 #include <botan/internal/es_ftw.h> 9 #include <botan/secmem.h> 13 #ifndef _POSIX_C_SOURCE 14 #define _POSIX_C_SOURCE 199309 17 #include <sys/types.h> 28 class File_Descriptor_Source
34 virtual int next_fd() = 0;
36 virtual ~File_Descriptor_Source() {}
41 class Directory_Walker :
public File_Descriptor_Source
44 Directory_Walker(
const std::string& root) :
45 m_cur_dir(std::make_pair<DIR*, std::string>(0,
""))
47 if(DIR* root_dir = ::opendir(root.c_str()))
48 m_cur_dir = std::make_pair(root_dir, root);
54 ::closedir(m_cur_dir.first);
59 void add_directory(
const std::string& dirname)
61 m_dirlist.push_back(dirname);
64 std::pair<struct dirent*, std::string> get_next_dirent();
66 std::pair<DIR*, std::string> m_cur_dir;
67 std::deque<std::string> m_dirlist;
70 std::pair<struct dirent*, std::string> Directory_Walker::get_next_dirent()
72 while(m_cur_dir.first)
74 struct dirent* dir = ::readdir(m_cur_dir.first);
77 return std::make_pair(dir, m_cur_dir.second);
79 ::closedir(m_cur_dir.first);
80 m_cur_dir = std::make_pair<DIR*, std::string>(0,
"");
82 while(!m_dirlist.empty() && m_cur_dir.first == 0)
84 const std::string next_dir_name = m_dirlist[0];
85 m_dirlist.pop_front();
87 if(DIR* next_dir = ::opendir(next_dir_name.c_str()))
88 m_cur_dir = std::make_pair(next_dir, next_dir_name);
92 return std::make_pair<struct dirent*, std::string>(0,
"");
95 int Directory_Walker::next_fd()
99 std::pair<struct dirent*, std::string> entry = get_next_dirent();
104 const std::string filename = entry.first->d_name;
106 if(filename ==
"." || filename ==
"..")
109 const std::string full_path = entry.second +
'/' + filename;
111 struct stat stat_buf;
112 if(::lstat(full_path.c_str(), &stat_buf) == -1)
115 if(S_ISDIR(stat_buf.st_mode))
117 add_directory(full_path);
119 else if(S_ISREG(stat_buf.st_mode) && (stat_buf.st_mode & S_IROTH))
121 int fd = ::open(full_path.c_str(), O_RDONLY |
O_NOCTTY);
151 const size_t MAX_FILES_READ_PER_POLL = 2048;
154 dir =
new Directory_Walker(path);
158 for(
size_t i = 0; i != MAX_FILES_READ_PER_POLL; ++i)
160 int fd = dir->next_fd();
170 ssize_t got = ::read(fd, &io_buffer[0], io_buffer.
size());
174 accum.
add(&io_buffer[0], got, .001);
void poll(Entropy_Accumulator &accum)
MemoryRegion< byte > & get_io_buffer(size_t size)
void add(const void *bytes, size_t length, double entropy_bits_per_byte)
FTW_EntropySource(const std::string &root_dir)
bool polling_goal_achieved() const