]> git.sur5r.net Git - i3/i3status/commitdiff
support the special interface name _first_ for ethernet/wireless
authorMichael Stapelberg <michael@stapelberg.de>
Sun, 7 Dec 2014 14:14:02 +0000 (15:14 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 7 Dec 2014 14:17:31 +0000 (15:17 +0100)
Since we have deterministic device names in Linux, these strings are a
much better default in the i3status config than "eth0" and "wlan0" (what
we used before).

i3status.c
i3status.conf
include/i3status.h
man/i3status.man
src/first_network_device.c [new file with mode: 0644]

index fc16c49c4bfc080948e5012eb37735a7099d16a9..daa2d0065032139aedb780529d16ed0e79269445 100644 (file)
@@ -576,13 +576,23 @@ int main(int argc, char *argv[]) {
 
                         CASE_SEC_TITLE("wireless") {
                                 SEC_OPEN_MAP("wireless");
-                                print_wireless_info(json_gen, buffer, title, cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down"));
+                                const char *interface = NULL;
+                                if (strcasecmp(title, "_first_") == 0)
+                                        interface = first_eth_interface(NET_TYPE_WIRELESS);
+                                if (interface == NULL)
+                                        interface = title;
+                                print_wireless_info(json_gen, buffer, interface, cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down"));
                                 SEC_CLOSE_MAP;
                         }
 
                         CASE_SEC_TITLE("ethernet") {
                                 SEC_OPEN_MAP("ethernet");
-                                print_eth_info(json_gen, buffer, title, cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down"));
+                                const char *interface = NULL;
+                                if (strcasecmp(title, "_first_") == 0)
+                                        interface = first_eth_interface(NET_TYPE_ETHERNET);
+                                if (interface == NULL)
+                                        interface = title;
+                                print_eth_info(json_gen, buffer, interface, cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down"));
                                 SEC_CLOSE_MAP;
                         }
 
index 01c182c636f4e19a3e0b78617799dbfded110845..7052e23d106a475ddde209ebb2c6a34aa3e4afc5 100644 (file)
@@ -15,18 +15,18 @@ order += "ipv6"
 order += "disk /"
 order += "run_watch DHCP"
 order += "run_watch VPN"
-order += "wireless wlan0"
-order += "ethernet eth0"
+order += "wireless _first_"
+order += "ethernet _first_"
 order += "battery 0"
 order += "load"
 order += "tztime local"
 
-wireless wlan0 {
+wireless _first_ {
         format_up = "W: (%quality at %essid) %ip"
         format_down = "W: down"
 }
 
-ethernet eth0 {
+ethernet _first_ {
         # if you use %speed, i3status requires root privileges
         format_up = "E: %ip (%speed)"
         format_down = "E: down"
index d816f0a00af3e26e8dff246630284c9cc2367b7e..f8f0784ceed2485420dafc5d3abc87961a75788a 100644 (file)
@@ -170,6 +170,13 @@ char *auto_detect_format();
 /* src/print_time.c */
 void set_timezone(const char *tz);
 
+/* src/first_network_device.c */
+typedef enum {
+       NET_TYPE_WIRELESS = 0,
+       NET_TYPE_ETHERNET = 1
+} net_type_t;
+const char *first_eth_interface(const net_type_t type);
+
 void print_ipv6_info(yajl_gen json_gen, char *buffer, const char *format_up, const char *format_down);
 void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *prefix_type, const char *threshold_type, const double low_threshold);
 void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, const char *format_down, const char *status_chr, const char *status_bat, const char *status_full, int low_threshold, char *threshold_type, bool last_full_capacity, bool integer_battery_capacity, bool hide_seconds);
index 06dc4a64cc1842520375027e1dbd568ef2d1b512..e11aff508a7f5afe1becbb73c779cf247ea0ef66 100644 (file)
@@ -274,6 +274,9 @@ Gets the link quality, frequency and ESSID of the given wireless network
 interface. You can specify different format strings for the network being
 connected or not connected.
 
+The special interface name `_first_` will be replaced by the first wireless
+network interface found on the system (excluding devices starting with "lo").
+
 *Example order*: +wireless wlan0+
 
 *Example format*: +W: (%quality at %essid, %bitrate / %frequency) %ip+
@@ -284,6 +287,9 @@ Gets the IP address and (if possible) the link speed of the given ethernet
 interface. Getting the link speed requires the cap_net_admin capability. Set
 it using +setcap cap_net_admin=ep $(which i3status)+.
 
+The special interface name `_first_` will be replaced by the first non-wireless
+network interface found on the system (excluding devices starting with "lo").
+
 *Example order*: +ethernet eth0+
 
 *Example format*: +E: %ip (%speed)+
diff --git a/src/first_network_device.c b/src/first_network_device.c
new file mode 100644 (file)
index 0000000..c160027
--- /dev/null
@@ -0,0 +1,39 @@
+// vim:ts=8:expandtab
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <ifaddrs.h>
+
+#include "i3status.h"
+
+const char *first_eth_interface(const net_type_t type) {
+        static char *interface = NULL;
+        struct ifaddrs *ifaddr, *addrp;
+        struct stat stbuf;
+        static char path[1024];
+
+        getifaddrs(&ifaddr);
+
+        if (ifaddr == NULL)
+                return NULL;
+
+        free(interface);
+        interface = NULL;
+        for (addrp = ifaddr;
+             addrp != NULL;
+             addrp = addrp->ifa_next) {
+                if (strncasecmp("lo", addrp->ifa_name, strlen("lo")) == 0)
+                        continue;
+                // Skip this interface if it is a wireless interface.
+                snprintf(path, sizeof(path), "/sys/class/net/%s/wireless", addrp->ifa_name);
+                const bool is_wireless = (stat(path, &stbuf) == 0);
+                if (( is_wireless && type == NET_TYPE_ETHERNET) ||
+                    (!is_wireless && type == NET_TYPE_WIRELESS))
+                        continue;
+                interface = strdup(addrp->ifa_name);
+                break;
+        }
+
+        freeifaddrs(ifaddr);
+        return interface;
+}
+