<commit_before>//
//  ZeroMQUtilities.cpp
//  MWorksCore
//
//  Created by <NAME> on 8/3/16.
//
//

#include "ZeroMQUtilities.hpp"

#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <netdb.h>

#include <boost/format.hpp>
#include <boost/scope_exit.hpp>

#include "Utilities.h"


BEGIN_NAMESPACE_MW
BEGIN_NAMESPACE(zeromq)


std::string formatTCPEndpoint(const std::string &hostname, int port) {
    return (boost::format("tcp://%1%:%2%") % hostname % port).str();
}


bool getHostname(std::string &hostname) {
    struct ifaddrs *interfaces = nullptr;
    if (0 != getifaddrs(&interfaces)) {
        merror(M_NETWORK_MESSAGE_DOMAIN, "Cannot get network interface addresses: %s", strerror(errno));
    } else {
        BOOST_SCOPE_EXIT(&interfaces) {
            freeifaddrs(interfaces);
        } BOOST_SCOPE_EXIT_END
        
        for (auto ifa = interfaces; ifa; ifa = ifa->ifa_next) {
            if ((ifa->ifa_flags & IFF_UP) &&
                !(ifa->ifa_flags & IFF_LOOPBACK) &&
                ifa->ifa_addr)
            {
                auto addr = ifa->ifa_addr;
                if ((addr->sa_family == AF_INET &&
                     !IN_LINKLOCAL(reinterpret_cast<struct sockaddr_in *>(addr)->sin_addr.s_addr)) ||
                    (addr->sa_family == AF_INET6 &&
                     !IN6_IS_ADDR_LINKLOCAL(&(reinterpret_cast<struct sockaddr_in6 *>(addr)->sin6_addr))))
                {
                    std::array<char, NI_MAXHOST> host;
                    auto error = getnameinfo(addr, addr->sa_len, host.data(), host.size(), nullptr, 0, 0);
                    if (0 == error) {
                        hostname = host.data();
                        return true;
                    }
                    merror(M_NETWORK_MESSAGE_DOMAIN,
                           "Cannot convert socket address to host name: %s",
                           gai_strerror(error));
                }
            }
        }
    }
    
    merror(M_NETWORK_MESSAGE_DOMAIN, "Cannot determine system hostname");
    return false;
}


bool resolveHostname(const std::string &hostname, std::string &address) {
    const struct addrinfo hints = {
        AI_DEFAULT,
        PF_UNSPEC,
        SOCK_STREAM,
        IPPROTO_TCP,
        0,
        nullptr,<commit_msg>Added a missing byte-order conversion in zeromq::getHostname<commit_after>//
//  ZeroMQUtilities.cpp
//  MWorksCore
//
//  Created by <NAME> on 8/3/16.
//
//

#include "ZeroMQUtilities.hpp"

#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <netdb.h>

#include <boost/format.hpp>
#include <boost/scope_exit.hpp>

#include "Utilities.h"


BEGIN_NAMESPACE_MW
BEGIN_NAMESPACE(zeromq)


std::string formatTCPEndpoint(const std::string &hostname, int port) {
    return (boost::format("tcp://%1%:%2%") % hostname % port).str();
}


bool getHostname(std::string &hostname) {
    struct ifaddrs *interfaces = nullptr;
    if (0 != getifaddrs(&interfaces)) {
        merror(M_NETWORK_MESSAGE_DOMAIN, "Cannot get network interface addresses: %s", strerror(errno));
    } else {
        BOOST_SCOPE_EXIT(&interfaces) {
            freeifaddrs(interfaces);
        } BOOST_SCOPE_EXIT_END
        
        for (auto ifa = interfaces; ifa; ifa = ifa->ifa_next) {
            if ((ifa->ifa_flags & IFF_UP) &&
                !(ifa->ifa_flags & IFF_LOOPBACK) &&
                ifa->ifa_addr)
            {
                auto addr = ifa->ifa_addr;
                if ((addr->sa_family == AF_INET &&
                     // s_addr is stored in network (i.e. big-endian) byte order, so we must convert it
                     // to host byte order before using it
                     !IN_LINKLOCAL(ntohl(reinterpret_cast<struct sockaddr_in *>(addr)->sin_addr.s_addr))) ||
                    (addr->sa_family == AF_INET6 &&
                     !IN6_IS_ADDR_LINKLOCAL(&(reinterpret_cast<struct sockaddr_in6 *>(addr)->sin6_addr))))
                {
                    std::array<char, NI_MAXHOST> host;
                    auto error = getnameinfo(addr, addr->sa_len, host.data(), host.size(), nullptr, 0, 0);
                    if (0 == error) {
                        hostname = host.data();
                        return true;
                    }
                    merror(M_NETWORK_MESSAGE_DOMAIN,
                           "Cannot convert socket address to host name: %s",
                           gai_strerror(error));
                }
            }
        }
    }
    
    merror(M_NETWORK_MESSAGE_DOMAIN, "Cannot determine system hostname");
    return false;
}


bool resolveHostname(const std::string &hostname, std::string &address) {
    const struct addrinfo hints = {
        AI_DEFAULT,
        PF_UNSPEC,
        SOCK_STREAM,
        IPPROTO_TCP,
        0,
        nullptr,
{'fraction_non_alphanumeric': 0.12301669070677931, 'fraction_numerical': 0.006181743251596951, 'mean_word_length': 1.9240963855421687, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 45, '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': '7132686', 'n_tokens_mistral': 1569, 'n_tokens_neox': 1509, 'n_words': 310}