#ifndef FORTUNA_URANDOM_ENTROPY_SRC_CPP
#define FORTUNA_URANDOM_ENTROPY_SRC_CPP
#include "urandom_entropy_src.h"
#include "event_adder_impl.h"
#include <cassert>
#include <climits>
#include <cstdint>
#include <cstring>
#include <mutex>
#include <stdexcept>
#include <vector>
namespace fortuna {
namespace accumulator {
auto UrandomEntropySrc::event(accumulator::EventAdderImpl& adder) -> void {
std::lock_guard<std::mutex> lg(mtx);
std::ifstream file;
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
std::ifstream urandom("/dev/urandom", std::ios::in | std::ios::binary);
// how much to get at once
static constexpr const unsigned int this_many_bytes{32};
this->bytes.resize(this_many_bytes);
assert((bytes.size()) == this_many_bytes);
// check if stream is open
if (urandom) {
fmt::print(stderr, "[i] ues: /dev/urandom stream open\n");
std::unique_lock<std::mutex> ul;
urandom.read(&this->bytes.front(), this_many_bytes);
urandom.close();
}
else {
// open failed
const std::string msg{"\t[!] Failed to open /dev/urandom\n"};
fmt::print(stderr, "{}", msg);
throw std::runtime_error(msg);
adder.add(this->bytes);
std::memset(this->bytes.data(), 0x00, this->bytes.size()); // clear out
catch (std::ifstream::failure& e) {
// FIXME: handle the exception
fmt::print(stderr, "io exception caugth: {}\n", e.what());
throw;
catch (std::exception& e) {
fmt::print(stderr, "[!] ues: exception caugth: {}\n", e.what());
UrandomEntropySrc::UrandomEntropySrc() : EntropySrc::EntropySrc() {}
UrandomEntropySrc::~UrandomEntropySrc() noexcept {}
} // namespace accumulator
} // namespace fortuna
#endif // FORTUNA_URANDOM_ENTROPY_SRC_CPP