summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2014-12-07 15:14:02 +0100
committerMichael Stapelberg <michael@stapelberg.de>2014-12-07 15:17:31 +0100
commitb219f47f394e536198997578e4cce3c539b84b6d (patch)
tree91e7a6b489ed3dbbfc70a07b0ffa86a03512a4a4
parent7bdfb5b72e730f2131dccd75f211aaa6d2236954 (diff)
support the special interface name _first_ for ethernet/wireless
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).
-rw-r--r--i3status.c14
-rw-r--r--i3status.conf8
-rw-r--r--include/i3status.h7
-rw-r--r--man/i3status.man6
-rw-r--r--src/first_network_device.c39
5 files changed, 68 insertions, 6 deletions
diff --git a/i3status.c b/i3status.c
index fc16c49..daa2d00 100644
--- a/i3status.c
+++ b/i3status.c
@@ -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;
}
diff --git a/i3status.conf b/i3status.conf
index 01c182c..7052e23 100644
--- a/i3status.conf
+++ b/i3status.conf
@@ -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"
diff --git a/include/i3status.h b/include/i3status.h
index d816f0a..f8f0784 100644
--- a/include/i3status.h
+++ b/include/i3status.h
@@ -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);
diff --git a/man/i3status.man b/man/i3status.man
index 06dc4a6..e11aff5 100644
--- a/man/i3status.man
+++ b/man/i3status.man
@@ -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
index 0000000..c160027
--- /dev/null
+++ b/src/first_network_device.c
@@ -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;
+}
+