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