<commit_before>
#include <planet/common.hpp>
#include <planet/dns_op.hpp>

namespace planet {


int dns_op::forward_lookup(std::string const& hostname, int family, std::vector<std::string>& store)
{
    struct addrinfo hints = {}, *result;
    hints.ai_family     = family;       // AF_INET,AF_INET6,AF_UNSPEC
    hints.ai_socktype   = SOCK_STREAM;  // Stream socke

    int s = getaddrinfo(hostname.c_str(), NULL, &hints, &result);
    if (s != 0)
        return s;
    std::vector<char> buf(1024, 0);
    for (struct addrinfo *ai = result; ai; ai = ai->ai_next) {
        if (ai->ai_family == AF_INET)
            inet_ntop(ai->ai_family, &((struct sockaddr_in *)ai->ai_addr)->sin_addr, buf.data(), buf.size());
        else if (ai->ai_family == AF_INET6)
            inet_ntop(ai->ai_family, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, buf.data(), buf.size());
        store.emplace_back(buf.data());
        std::fill(buf.begin(), buf.end(), 0);
    }
    freeaddrinfo(result);
    return 0;
}

dns_op::~dns_op()
{
    syslog(LOG_INFO, "dns_op: dtor called target=%s", hostname_.c_str());
}

inline int dns_op::open(fusecpp::path_type const& path, struct fuse_file_info& fi)
{
    return 0;
}

int dns_op::read(fusecpp::path_type const& path, char *buf, size_t size, off_t offset, struct fuse_file_info& fi)
{
    if (resolved_names_.empty())
        return 0;
    std::string& resolved = *resolved_names_.begin();
    std::size_t length = resolved.length();
    if (size <= length)
        return -ENOBUFS;
    std::copy(resolved.begin(), resolved.end(), buf);
    buf[length] = '\0';
    resolved_names_.erase(resolved_names_.begin());
    return length + 1;
}

int dns_op::write(fusecpp::path_type const& path, char const *buf, size_t size, off_t offset, struct fuse_file_info& fi)
{
    std::string request = buf;
    auto pos = request.find_first_of(' ');
    if (pos == std::string::npos)
        return -EINVAL;
    std::string opecode = request.substr(0, pos), hostname_ = request.substr(pos + 1);
    syslog(LOG_INFO, "dns_op: write: opecode=%s / hostname=%s", opecode.c_str(), hostname_.c_str());

    int family;
    if (opecode == "resolve")            family = AF_UNSPEC;
    else if (opecode == "resolve_inet")  family = AF_INET;
    else if (opecode == "resolve_inet6") family = AF_INET6;
    else return -EINVAL;
    resolved_names_.clear();
    forward_lookup(hostname_, family, resolved_names_);
    return hostname_.length();
}

inline int dns_op::release(fusecpp::path_type const& path, struct fuse_file_info& fi)
{
    return 0;
}

bool dns_op::is_matching_path(fusecpp::path_type const& path)
{
    return path == "/dns";
}


}   // namespace planet
<commit_msg>dns_op::write: return exact request length<commit_after>
#include <planet/common.hpp>
#include <planet/dns_op.hpp>

namespace planet {


int dns_op::forward_lookup(std::string const& hostname, int family, std::vector<std::string>& store)
{
    struct addrinfo hints = {}, *result;
    hints.ai_family     = family;       // AF_INET,AF_INET6,AF_UNSPEC
    hints.ai_socktype   = SOCK_STREAM;  // Stream socke

    int s = getaddrinfo(hostname.c_str(), NULL, &hints, &result);
    if (s != 0)
        return s;
    std::vector<char> buf(1024, 0);
    for (struct addrinfo *ai = result; ai; ai = ai->ai_next) {
        if (ai->ai_family == AF_INET)
            inet_ntop(ai->ai_family, &((struct sockaddr_in *)ai->ai_addr)->sin_addr, buf.data(), buf.size());
        else if (ai->ai_family == AF_INET6)
            inet_ntop(ai->ai_family, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, buf.data(), buf.size());
        store.emplace_back(buf.data());
        std::fill(buf.begin(), buf.end(), 0);
    }
    freeaddrinfo(result);
    return 0;
}

dns_op::~dns_op()
{
    syslog(LOG_INFO, "dns_op: dtor called target=%s", hostname_.c_str());
}

inline int dns_op::open(fusecpp::path_type const& path, struct fuse_file_info& fi)
{
    return 0;
}

int dns_op::read(fusecpp::path_type const& path, char *buf, size_t size, off_t offset, struct fuse_file_info& fi)
{
    if (resolved_names_.empty())
        return 0;
    std::string& resolved = *resolved_names_.begin();
    std::size_t length = resolved.length();
    if (size <= length)
        return -ENOBUFS;
    std::copy(resolved.begin(), resolved.end(), buf);
    buf[length] = '\0';
    resolved_names_.erase(resolved_names_.begin());
    return length + 1;
}

int dns_op::write(fusecpp::path_type const& path, char const *buf, size_t size, off_t offset, struct fuse_file_info& fi)
{
    std::string request(buf, size);
    auto pos = request.find_first_of(' ');
    if (pos == std::string::npos)
        return -EINVAL;
    std::string opecode = request.substr(0, pos), hostname_ = request.substr(pos + 1);
    syslog(LOG_INFO, "dns_op: write: opecode=%s / hostname=%s", opecode.c_str(), hostname_.c_str());

    int family;
    if (opecode == "resolve")            family = AF_UNSPEC;
    else if (opecode == "resolve_inet")  family = AF_INET;
    else if (opecode == "resolve_inet6") family = AF_INET6;
    else return -EINVAL;
    resolved_names_.clear();
    forward_lookup(hostname_, family, resolved_names_);
    return request.length();
}

inline int dns_op::release(fusecpp::path_type const& path, struct fuse_file_info& fi)
{
    return 0;
}

bool dns_op::is_matching_path(fusecpp::path_type const& path)
{
    return path == "/dns";
}


}   // namespace planet

{'fraction_non_alphanumeric': 0.1540590405904059, 'fraction_numerical': 0.007749077490774908, 'mean_word_length': 3.6254266211604094, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '77310', 'n_tokens_mistral': 1988, 'n_tokens_neox': 1953, 'n_words': 432}