aboutsummaryrefslogtreecommitdiffstats
path: root/modules/entropy/proc_walk/es_ftw.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-09-28 15:34:09 +0000
committerlloyd <[email protected]>2008-09-28 15:34:09 +0000
commitea32d18231b9c6c5c84b3754c4249170d3b4e4c0 (patch)
treecc179337d0594ed105768011722b9dbae105e07a /modules/entropy/proc_walk/es_ftw.cpp
parentb841401e095cfc1aa0708689d7920eb95ece71af (diff)
This is the first checkin to net.randombit.botan.modularized, which
has the intent of modularizing Botan's source code, and making it much easier to add or remove various things at compile time. In this first checkin: Add support for nested directories in modules/ and move all the modules into grouped directories like entropy/ or compression/ Currently this is not ideal, it will _only_ find code in modules/*/*/modinfo.txt, while it would be much better to allow for arbitrary nestings under modules (find modules -name modinfo.txt) for more complicated setups. This 'new' (OMG I've found directories!) structure allows for a more free naming convention (no need for leading es_, ml_, etc to group names, though some keep it for lack of a more meaningful name being obvious to me right at the moment).
Diffstat (limited to 'modules/entropy/proc_walk/es_ftw.cpp')
-rw-r--r--modules/entropy/proc_walk/es_ftw.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/modules/entropy/proc_walk/es_ftw.cpp b/modules/entropy/proc_walk/es_ftw.cpp
new file mode 100644
index 000000000..ec11378f8
--- /dev/null
+++ b/modules/entropy/proc_walk/es_ftw.cpp
@@ -0,0 +1,147 @@
+/*************************************************
+* FTW EntropySource Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/es_ftw.h>
+#include <botan/util.h>
+#include <cstring>
+#include <deque>
+
+#ifndef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 199309
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+namespace Botan {
+
+namespace {
+
+class Directory_Walker
+ {
+ public:
+ Directory_Walker(const std::string& root) { add_directory(root); }
+ ~Directory_Walker();
+
+ int next_fd();
+ private:
+ void add_directory(const std::string&);
+
+ std::deque<std::pair<DIR*, std::string> > dirs;
+ };
+
+void Directory_Walker::add_directory(const std::string& dirname)
+ {
+ DIR* dir = ::opendir(dirname.c_str());
+ if(dir)
+ dirs.push_back(std::make_pair(dir, dirname));
+ }
+
+Directory_Walker::~Directory_Walker()
+ {
+ while(dirs.size())
+ {
+ ::closedir(dirs[0].first);
+ dirs.pop_front();
+ }
+ }
+
+int Directory_Walker::next_fd()
+ {
+ while(dirs.size())
+ {
+ std::pair<DIR*, std::string> dirinfo = dirs[0];
+
+ struct dirent* entry = ::readdir(dirinfo.first);
+
+ if(!entry)
+ {
+ ::closedir(dirinfo.first);
+ dirs.pop_front();
+ continue;
+ }
+
+ const std::string filename = entry->d_name;
+
+ if(filename == "." || filename == "..")
+ continue;
+
+ const std::string full_path = dirinfo.second + '/' + filename;
+
+ struct stat stat_buf;
+ if(::lstat(full_path.c_str(), &stat_buf) == -1)
+ continue;
+
+ if(S_ISDIR(stat_buf.st_mode))
+ add_directory(full_path);
+ else if(S_ISREG(stat_buf.st_mode))
+ {
+ int fd = ::open(full_path.c_str(), O_RDONLY | O_NOCTTY);
+
+ if(fd > 0)
+ return fd;
+ }
+ }
+
+ return -1;
+ }
+
+}
+
+/*************************************************
+* FTW_EntropySource Constructor *
+*************************************************/
+FTW_EntropySource::FTW_EntropySource(const std::string& p) : path(p)
+ {
+ }
+
+/*************************************************
+* FTW Fast Poll *
+*************************************************/
+void FTW_EntropySource::do_fast_poll()
+ {
+ poll(32*1024);
+ }
+
+/*************************************************
+* FTW Slow Poll *
+*************************************************/
+void FTW_EntropySource::do_slow_poll()
+ {
+ poll(256*1024);
+ }
+
+/*************************************************
+* FTW Poll *
+*************************************************/
+void FTW_EntropySource::poll(u32bit max_read)
+ {
+ Directory_Walker dir(path);
+ SecureVector<byte> read_buf(1024);
+
+ u32bit read_so_far = 0;
+ while(read_so_far < max_read)
+ {
+ int fd = dir.next_fd();
+
+ if(fd == -1)
+ break;
+
+ ssize_t got = ::read(fd, read_buf.begin(), read_buf.size());
+
+ if(got > 0)
+ {
+ add_bytes(read_buf, got);
+ read_so_far += got;
+ }
+
+ ::close(fd);
+ }
+ }
+
+}