diff options
| author | Michael Stapelberg <michael@stapelberg.de> | 2014-12-07 15:14:02 +0100 | 
|---|---|---|
| committer | Michael Stapelberg <michael@stapelberg.de> | 2014-12-07 15:17:31 +0100 | 
| commit | b219f47f394e536198997578e4cce3c539b84b6d (patch) | |
| tree | 91e7a6b489ed3dbbfc70a07b0ffa86a03512a4a4 | |
| parent | 7bdfb5b72e730f2131dccd75f211aaa6d2236954 (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.c | 14 | ||||
| -rw-r--r-- | i3status.conf | 8 | ||||
| -rw-r--r-- | include/i3status.h | 7 | ||||
| -rw-r--r-- | man/i3status.man | 6 | ||||
| -rw-r--r-- | src/first_network_device.c | 39 | 
5 files changed, 68 insertions, 6 deletions
@@ -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; +} +  | 
