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;
}
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"
/* 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);
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+
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)+
--- /dev/null
+// 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;
+}
+