aboutsummaryrefslogtreecommitdiffhomepage
path: root/env_universal_common.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-04-25 17:44:49 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2014-04-25 17:45:22 -0700
commitbf14668b2a831d583196d8c5d1f58c69eefa216e (patch)
tree97c1b2362922e83176756fd62cacb49b83ec4ec6 /env_universal_common.cpp
parenta475dd15e65759f2d20822cd3b19b874575c7f5e (diff)
Migrate machine and hostname identification from fishd.cpp to
env_universal_common.cpp, so that fish can use it
Diffstat (limited to 'env_universal_common.cpp')
-rw-r--r--env_universal_common.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/env_universal_common.cpp b/env_universal_common.cpp
index 5194e8ff..592930bf 100644
--- a/env_universal_common.cpp
+++ b/env_universal_common.cpp
@@ -27,6 +27,7 @@
#include <dirent.h>
#include <signal.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
#include <map>
#ifdef HAVE_SYS_SELECT_H
@@ -706,3 +707,126 @@ void env_universal_t::enqueue_all(connection_t *c) const
c->unsent.push(msg);
}
}
+
+
+
+/**
+ Maximum length of hostname. Longer hostnames are truncated
+ */
+#define HOSTNAME_LEN 32
+
+/* Length of a MAC address */
+#define MAC_ADDRESS_MAX_LEN 6
+
+
+/* Thanks to Jan Brittenson
+ http://lists.apple.com/archives/xcode-users/2009/May/msg00062.html
+ */
+#ifdef SIOCGIFHWADDR
+
+/* Linux */
+#include <net/if.h>
+static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN], const char *interface = "eth0")
+{
+ bool result = false;
+ const int dummy = socket(AF_INET, SOCK_STREAM, 0);
+ if (dummy >= 0)
+ {
+ struct ifreq r;
+ strncpy((char *)r.ifr_name, interface, sizeof r.ifr_name - 1);
+ r.ifr_name[sizeof r.ifr_name - 1] = 0;
+ if (ioctl(dummy, SIOCGIFHWADDR, &r) >= 0)
+ {
+ memcpy(macaddr, r.ifr_hwaddr.sa_data, MAC_ADDRESS_MAX_LEN);
+ result = true;
+ }
+ close(dummy);
+ }
+ return result;
+}
+
+#elif defined(HAVE_GETIFADDRS)
+
+/* OS X and BSD */
+#include <ifaddrs.h>
+#include <net/if_dl.h>
+static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN], const char *interface = "en0")
+{
+ // BSD, Mac OS X
+ struct ifaddrs *ifap;
+ bool ok = false;
+
+ if (getifaddrs(&ifap) == 0)
+ {
+ for (const ifaddrs *p = ifap; p; p = p->ifa_next)
+ {
+ if (p->ifa_addr->sa_family == AF_LINK)
+ {
+ if (p->ifa_name && p->ifa_name[0] &&
+ ! strcmp((const char*)p->ifa_name, interface))
+ {
+
+ const sockaddr_dl& sdl = *(sockaddr_dl*)p->ifa_addr;
+
+ size_t alen = sdl.sdl_alen;
+ if (alen > MAC_ADDRESS_MAX_LEN) alen = MAC_ADDRESS_MAX_LEN;
+ memcpy(macaddr, sdl.sdl_data + sdl.sdl_nlen, alen);
+ ok = true;
+ break;
+ }
+ }
+ }
+ freeifaddrs(ifap);
+ }
+ return ok;
+}
+
+#else
+
+/* Unsupported */
+static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN])
+{
+ return false;
+}
+
+#endif
+
+/* Function to get an identifier based on the hostname */
+bool get_hostname_identifier(std::string *result)
+{
+ bool success = false;
+ char hostname[HOSTNAME_LEN + 1] = {};
+ if (gethostname(hostname, HOSTNAME_LEN) == 0)
+ {
+ result->assign(hostname);
+ success = true;
+ }
+ return success;
+}
+
+/* Get a sort of unique machine identifier. Prefer the MAC address; if that fails, fall back to the hostname; if that fails, pick something. */
+std::string get_machine_identifier(void)
+{
+ std::string result;
+ unsigned char mac_addr[MAC_ADDRESS_MAX_LEN] = {};
+ if (get_mac_address(mac_addr))
+ {
+ result.reserve(2 * MAC_ADDRESS_MAX_LEN);
+ for (size_t i=0; i < MAC_ADDRESS_MAX_LEN; i++)
+ {
+ char buff[3];
+ snprintf(buff, sizeof buff, "%02x", mac_addr[i]);
+ result.append(buff);
+ }
+ }
+ else if (get_hostname_identifier(&result))
+ {
+ /* Hooray */
+ }
+ else
+ {
+ /* Fallback */
+ result.assign("nohost");
+ }
+ return result;
+}