X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=wmiistatus.c;h=2f87d9259591308b40fc864e483d9d7dec974014;hb=a9bf807cddceaf0dcaf774cf4f020607e77f84cc;hp=10b1b331e399a3b61cb3c43173b42951d551dc89;hpb=513cfe8f1bb892eda973221477ce385f2ca4aca8;p=i3%2Fi3status diff --git a/wmiistatus.c b/wmiistatus.c index 10b1b33..2f87d92 100644 --- a/wmiistatus.c +++ b/wmiistatus.c @@ -2,7 +2,7 @@ * Generates a status line for use with wmii or other minimal window managers * * - * Copyright (c) 2008 Michael Stapelberg and contributors + * Copyright (c) 2008-2009 Michael Stapelberg and contributors * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -59,6 +59,9 @@ #undef _IS_WMIISTATUS_C #include "config.h" +/* socket file descriptor for general purposes */ +static int general_socket; + /* * This function just concats two strings in place, it should only be used * for concatting order to the name of a file or concatting color codes. @@ -97,7 +100,7 @@ static void cleanup_rbar_dir() { /* * Creates the specified file in wmii's /rbar directory with * correct modes and initializes colors if colormode is enabled - * ' + * */ static void create_file(const char *name) { char pathbuf[strlen(wmii_path)+256+1]; @@ -121,6 +124,11 @@ static void create_file(const char *name) { (void)close(fd); } +/* + * Waits until wmii_path/rbar exists (= the filesystem gets mounted), + * cleans up all files and creates the needed files + * + */ static void setup(void) { unsigned int i; struct stat statbuf; @@ -191,6 +199,11 @@ void die(const char *fmt, ...) { exit(EXIT_FAILURE); } +/* + * Skip the given character for exactly 'amount' times, returns + * a pointer to the first non-'character' character in 'input'. + * + */ static char *skip_character(char *input, char character, int amount) { char *walk; size_t len = strlen(input); @@ -204,8 +217,9 @@ static char *skip_character(char *input, char character, int amount) { } /* - * Get battery information from /sys. Note that it uses the design capacity to calculate the percentage, - * not the full capacity. + * Get battery information from /sys. Note that it uses the design capacity to + * calculate the percentage, not the last full capacity, so you can see how + * worn off your battery is. * */ static char *get_battery_info() { @@ -219,7 +233,7 @@ static char *get_battery_info() { charging_status_t status = CS_DISCHARGING; if ((fd = open(battery_path, O_RDONLY)) == -1) - die("Could not open %s", battery_path); + return "No battery found"; memset(part, 0, sizeof(part)); (void)read(fd, buf, sizeof(buf)); @@ -284,93 +298,76 @@ static char *get_wireless_info() { (void)read(fd, buf, sizeof(buf)); (void)close(fd); - interfaces = skip_character(buf, '\n', 2) + 1; - while (interfaces < buf+strlen(buf)) { + interfaces = skip_character(buf, '\n', 1) + 1; + while ((interfaces = skip_character(interfaces, '\n', 1)+1) < buf+strlen(buf)) { while (isspace((int)*interfaces)) interfaces++; - if (strncmp(interfaces, wlan_interface, strlen(wlan_interface)) == 0) { - int quality; - /* Skip status field (0000) */ - interfaces += strlen(wlan_interface) + 2; - interfaces = skip_character(interfaces, ' ', 1); - while (isspace((int)*interfaces)) - interfaces++; - quality = atoi(interfaces); - /* For some reason, I get 255 sometimes */ - if ((quality == 255) || (quality == 0)) { + if (!BEGINS_WITH(interfaces, wlan_interface)) + continue; + int quality; + if (sscanf(interfaces, "%*[^:]: 0000 %d", &quality) != 1) + continue; + /* for some reason, I get 255 sometimes */ + if ((quality == 255) || (quality == 0)) { if (use_colors) - (void)snprintf(part, sizeof(part), "%s%s", concat("#FF0000 ", wmii_normcolors), " W: down"); + (void)snprintf(part, sizeof(part), "%s%s", + concat("#FF0000 ", wmii_normcolors), " W: down"); else (void)snprintf(part, sizeof(part), "W: down"); - - } else { - const char *ip_address; - (void)snprintf(part, sizeof(part), "W: (%03d%%) ", quality); - ip_address = get_ip_address(wlan_interface); - strcpy(part+strlen(part), ip_address); - } - - return part; - } - interfaces = skip_character(interfaces, '\n', 1) + 1; + } else (void)snprintf(part, sizeof(part), "W: (%03d%%) %s", + quality, get_ip_address(wlan_interface)); + return part; } return part; } +/* + * Return the IP address for the given interface or "no IP" if the + * interface is up and running but hasn't got an IP address yet + * + */ static const char *get_ip_address(const char *interface) { static char part[512]; struct ifreq ifr; - int fd; + struct sockaddr_in addr; + socklen_t len = sizeof(struct sockaddr_in); memset(part, 0, sizeof(part)); - fd = socket(AF_INET, SOCK_DGRAM, 0); - - strcpy(ifr.ifr_name, interface); - if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) - die("Could not get interface flags (SIOCGIFFLAGS)"); - - if (!(ifr.ifr_flags & IFF_UP) || - !(ifr.ifr_flags & IFF_RUNNING)) { - close(fd); + (void)strcpy(ifr.ifr_name, interface); + ifr.ifr_addr.sa_family = AF_INET; + if (ioctl(general_socket, SIOCGIFADDR, &ifr) < 0) return NULL; - } - strcpy(ifr.ifr_name, interface); - ifr.ifr_addr.sa_family = AF_INET; - if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) { - struct sockaddr_in addr; - memcpy(&addr, &ifr.ifr_addr, sizeof(struct sockaddr_in)); - (void)inet_ntop(AF_INET, &addr.sin_addr.s_addr, part, (socklen_t)sizeof(struct sockaddr_in)); - if (strlen(part) == 0) - snprintf(part, sizeof(part), "no IP"); - } + memcpy(&addr, &ifr.ifr_addr, len); + (void)inet_ntop(AF_INET, &addr.sin_addr.s_addr, part, len); + if (strlen(part) == 0) + (void)snprintf(part, sizeof(part), "no IP"); - (void)close(fd); return part; } +/* + * Combines ethernet IP addresses and speed (if requested) for displaying + * + */ static char *get_eth_info() { static char part[512]; const char *ip_address = get_ip_address(eth_interface); int ethspeed = 0; if (get_ethspeed) { + /* This code path requires root privileges */ struct ifreq ifr; struct ethtool_cmd ecmd; - int fd, err; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - write_error_to_statusbar("Could not open socket"); + int err; ecmd.cmd = ETHTOOL_GSET; (void)memset(&ifr, 0, sizeof(ifr)); ifr.ifr_data = (caddr_t)&ecmd; (void)strcpy(ifr.ifr_name, eth_interface); - if ((err = ioctl(fd, SIOCETHTOOL, &ifr)) == 0) + if ((err = ioctl(general_socket, SIOCETHTOOL, &ifr)) == 0) ethspeed = (ecmd.speed == 65535 ? 0 : ecmd.speed); - else write_error_to_statusbar("Could not get interface speed. Insufficient privileges?"); - - (void)close(fd); + else get_ethspeed = false; } if (ip_address == NULL) @@ -440,6 +437,9 @@ int main(int argc, char *argv[]) { setup(); + if ((general_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + die("Could not create socket"); + while (1) { for (i = 0; i < num_run_watches; i += 2) { bool running = process_runs(run_watches[i+1]);