<commit_before>#include "adapters/net.hpp"

#include <arpa/inet.h>
#include <dirent.h>
#include <linux/ethtool.h>
#include <linux/if_link.h>
#include <linux/sockios.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <cassert>
#include <iomanip>

#include "common.hpp"
#include "settings.hpp"
#include "utils/command.hpp"
#include "utils/file.hpp"
#include "utils/string.hpp"

POLYBAR_NS

namespace net {
  enum class NetType {
    WIRELESS,
    ETHERNET,
    OTHER,
  };

  static const string NO_IP = string("N/A");
  static const string NO_MAC = string("N/A");
  static const string NET_PATH = "/sys/class/net/";
  static const string VIRTUAL_PATH = "/sys/devices/virtual/";

  static bool is_virtual(const std::string& ifname) {
    char* target = realpath((NET_PATH + ifname).c_str(), nullptr);

    if (!target) {
      throw system_error("realpath");
    }

    const std::string real_path{target};
    free(target);
    return real_path.rfind(VIRTUAL_PATH, 0) == 0;
  }

  NetType iface_type(const std::string& ifname) {
    if (file_util::exists(NET_PATH + ifname + "/wireless")) {
      return NetType::WIRELESS;
    }

    if (is_virtual(ifname)) {
      return NetType::OTHER;
    }

    return NetType::ETHERNET;
  }

  bool is_interface_valid(const string& ifname) {
    return if_nametoindex(ifname.c_str()) != 0;
  }

  /**
   * Returns the canonical name of the given interface and whether that differs
   * from the given name.
   *
   * The canonical name is the name that has an entry in `/sys/class/net`.
   *
   * This resolves any altnames that were defined (see man ip-link).
   */
  std::pair<string, bool> get_canonical_interface(const string& ifname) {
    int idx = if_nametoindex(ifname.c_str());

    if (idx == 0) {
      throw system_error("if_nameindex(" + ifname + ")");
    }

    char canonical[IF_NAMESIZE];
    if (!if_indextoname(idx, canonical)) {
      throw system_error("if_indextoname(" + to_string(idx) + ")");
    }

    string str{canonical};

    return {str, str != ifname};
  }

  /**
   * Test if interface with given name is a wireless device
   */
  bool is_wireless_interface(const string& ifname) {
    return iface_type(ifname) == NetType::WIRELESS;
  }

  std::string find_interface(NetType type) {
    struct ifaddrs* ifaddrs;
    getifaddrs(&ifaddrs);
    for (struct ifaddrs* i = ifaddrs; i != nullptr; i = i->ifa_next) {
      const std::string name{i->ifa_name};
      const NetType iftype = iface_type(name);
      if (iftype != type) {
        continue;
      }
      freeifaddrs(ifaddrs);
      return name;
    }
    freeifaddrs(ifaddrs);
    return "";
  }

  std::string find_wireless_interface() {
    return find_interface(NetType::WIRELESS);
  }

  std::string find_wired_interface() {
    return find_interface(NetType::ETHERNET);
  }

  // class : network {{{

  /**
   * Construct network interface
   */
  network::network(string interface) : m_log(logger::make()), m_interface(move(interface)) {
    assert(is_interface_valid(m_interface));<commit_msg>net: prefer running interface for auto-detection (#2557)<commit_after>#include "adapters/net.hpp"

#include <arpa/inet.h>
#include <dirent.h>
#include <linux/ethtool.h>
#include <linux/if_link.h>
#include <linux/sockios.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <cassert>
#include <iomanip>

#include "common.hpp"
#include "settings.hpp"
#include "utils/command.hpp"
#include "utils/file.hpp"
#include "utils/string.hpp"

POLYBAR_NS

namespace net {
  enum class NetType {
    WIRELESS,
    ETHERNET,
    OTHER,
  };

  static const string NO_IP = string("N/A");
  static const string NO_MAC = string("N/A");
  static const string NET_PATH = "/sys/class/net/";
  static const string VIRTUAL_PATH = "/sys/devices/virtual/";

  static bool is_virtual(const std::string& ifname) {
    char* target = realpath((NET_PATH + ifname).c_str(), nullptr);

    if (!target) {
      throw system_error("realpath");
    }

    const std::string real_path{target};
    free(target);
    return real_path.rfind(VIRTUAL_PATH, 0) == 0;
  }

  NetType iface_type(const std::string& ifname) {
    if (file_util::exists(NET_PATH + ifname + "/wireless")) {
      return NetType::WIRELESS;
    }

    if (is_virtual(ifname)) {
      return NetType::OTHER;
    }

    return NetType::ETHERNET;
  }

  bool is_interface_valid(const string& ifname) {
    return if_nametoindex(ifname.c_str()) != 0;
  }

  /**
   * Returns the canonical name of the given interface and whether that differs
   * from the given name.
   *
   * The canonical name is the name that has an entry in `/sys/class/net`.
   *
   * This resolves any altnames that were defined (see man ip-link).
   */
  std::pair<string, bool> get_canonical_interface(const string& ifname) {
    int idx = if_nametoindex(ifname.c_str());

    if (idx == 0) {
      throw system_error("if_nameindex(" + ifname + ")");
    }

    char canonical[IF_NAMESIZE];
    if (!if_indextoname(idx, canonical)) {
      throw system_error("if_indextoname(" + to_string(idx) + ")");
    }

    string str{canonical};

    return {str, str != ifname};
  }

  /**
   * Test if interface with given name is a wireless device
   */
  bool is_wireless_interface(const string& ifname) {
    return iface_type(ifname) == NetType::WIRELESS;
  }

  std::string find_interface(NetType type) {
    struct ifaddrs* ifaddrs;
    getifaddrs(&ifaddrs);

    struct ifaddrs* candidate_if = nullptr;

    for (struct ifaddrs* i = ifaddrs; i != nullptr; i = i->ifa_next) {
      const std::string name{i->ifa_name};
      const NetType iftype = iface_type(name);
      if (iftype != type) {
        continue;
      }
      if (candidate_if == nullptr) {
        candidate_if = i;
      } else if (((candidate_if->ifa_flags & IFF_RUNNING) == 0) && ((i->ifa_flags & IFF_RUNNING) > 0)) {
        candidate_if = i;
      }
    }
    if (candidate_if) {
      const std::string name{candidate_if->ifa_name};
      freeifaddrs(ifaddrs);
      return name;
    }
    freeifaddrs(ifaddrs);
    return "";
  }

  std::string find_wireless_interface() {
    return find_interface(NetType::WIRELESS);
  }

  std::string find_wired_interface() {
    return find_interface(NetType::ETHERNET);
  }

  // class : network {{{

  /**
   * Construct network interface
   */
  network::network(string interface) : m_log(logger::make()), m_interface(move(interface)) {
    assert(is_interface_valid(m_interface));
{'fraction_non_alphanumeric': 0.13929596615802992, 'fraction_numerical': 0.002115123130382233, 'mean_word_length': 3.395750332005312, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 39, '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': '3177979', 'n_tokens_mistral': 2363, 'n_tokens_neox': 2295, 'n_words': 519}