configurable if_up, may check for:
authorPhil <n0-1@users.sourceforge.net>
Fri, 30 May 2008 11:30:58 +0000 (11:30 +0000)
committerPhil <n0-1@users.sourceforge.net>
Fri, 30 May 2008 11:30:58 +0000 (11:30 +0000)
* IFF_UP flag,
* IFF_UP and IFF_RUNNING flags or
* IFF_UP, IFF_RUNNING flags and assigned address

git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@1121 7f574dfc-610e-0410-a909-a81674777703

ChangeLog
doc/config_settings.xml
doc/conky.conf
src/conky.c
src/conky.h
src/linux.c

index 8e3536b..287c018 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,7 @@
 
 2008-05-30
        * Simplified docs for color0-9 config settings and variables.
+       * Improved $if_up for configurable behaviour.
 
 2008-04-29
        * own_window_type dock patch (thanks Morgan).
index a5dc6ff..c51d7e9 100644 (file)
        </varlistentry>
 
        <varlistentry>
+               <term><command><option>if_up_strictness</option></command></term>
+               <listitem>
+                       How strict should if_up be when testing an interface for being up? The value is one of up, link or address, to check for the interface being solely up, being up and having link or being up, having link and an assigned IP address.
+                       <para></para></listitem>
+       </varlistentry>
+
+       <varlistentry>
                <term><command><option>imap</option></command></term>
                <listitem>
                        Default global IMAP server.  Arguments are: "host user pass [-i interval] [-f folder] [-p port] [-e command]".  Default port is 143, default folder is 'INBOX', default interval is 5 minutes.  If the password is supplied as '*', you will be prompted to enter the password when Conky starts.
index 1e1ec86..df96def 100644 (file)
@@ -140,6 +140,10 @@ show_graph_scale no
 # Timing interval for music player thread, e.g. mpd, audacious
 #music_player_interval (update_interval is default)
 
+# Strictness of if_up. One of: up, link or address. The later ones imply the further ones.
+# Defaults to up.
+#if_up_strictness address
+
 # variable is given either in format $variable or in ${variable}. Latter
 # allows characters right after the variable and must be used in network
 # stuff because of an argument
index a0c222a..1360ebc 100644 (file)
@@ -8510,6 +8510,21 @@ static void load_config_file(const char *f)
                         * as per config */
                }
 #endif
+               CONF("if_up_strictness") {
+                       if (!value) {
+                               ERR("incorrect if_up_strictness value, defaulting to 'up'");
+                               ifup_strictness = IFUP_UP;
+                       } else if (!strcmp(value, "up")) {
+                               ifup_strictness = IFUP_UP;
+                       } else if (!strcmp(value, "link")) {
+                               ifup_strictness = IFUP_LINK;
+                       } else if (!strcmp(value, "address")) {
+                               ifup_strictness = IFUP_ADDR;
+                       } else {
+                               ERR("incorrect if_up_strictness value, defaulting to 'up'");
+                               ifup_strictness = IFUP_UP;
+                       }
+               }
                else {
                        ERR("%s: %d: no such configuration: '%s'", f, line, name);
                }
index bcbc5a6..41e66d9 100644 (file)
@@ -337,6 +337,13 @@ enum {
        BATTERY_TIME
 };
 
+/* if_up strictness selector */
+enum {
+       IFUP_UP,
+       IFUP_LINK,
+       IFUP_ADDR
+} ifup_strictness;
+
 #ifdef MPD
 #include "libmpdclient.h"
 #endif
index ecaac57..9baffff 100644 (file)
@@ -212,66 +212,44 @@ char *get_ioscheduler(char *disk)
 
 int interface_up(const char *dev)
 {
-       int fd, dnl, ifnl, nl;
-       unsigned int k;
-       struct ifconf conf;
-       struct sockaddr addr;
-       char   *ifdev;
+       int fd;
+       struct ifreq ifr;
 
-       dnl = strlen(dev);
-       if((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) {
+       if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
                CRIT_ERR("could not create sockfd");
                return 0;
        }
-
-       /* allocate memory for interface request */
-       if((conf.ifc_buf = calloc(16, sizeof(struct ifreq))) == NULL) {
-               CRIT_ERR("could not allocate memory for interface query");
-               return 0;
-       }
-       conf.ifc_len = sizeof(struct ifreq) * 16;
-
-       /* send a conf query ioctl to device to enumerate all interfaces */
-       if(ioctl(fd, SIOCGIFCONF, &conf)) {
-               /* if device does not exist, treat like not up - fail fast */
+       strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+       if (ioctl(fd, SIOCGIFFLAGS, &ifr)) {
+               /* if device does not exist, treat like not up */
                if (errno != ENODEV)
                        perror("SIOCGIFFLAGS");
-       } else {
-               /* for all enumerated interface devices ... */
-               for (k = 0; k < conf.ifc_len / sizeof(struct ifreq); k++) {
-                       /* end of buffer - break out */
-                       if (!(((struct ifreq *) conf.ifc_buf) + k))
-                               break;
-                       /* get interface device name */
-                       ifdev =  ((struct ifreq *) conf.ifc_buf)[k].ifr_ifrn.ifrn_name;
-                       ifnl = strlen(ifdev);
-                       nl = dnl > ifnl ? ifnl : dnl;
-                       /* if it does not match our specified device - move on */
-                       if (strncmp(dev, ifdev, nl) != 0) {
-                               continue;
-                       }
-                       /* get associated address on device */
-                       addr = ((struct ifreq *) conf.ifc_buf)[k].ifr_ifru.ifru_addr;
-                       /* if ip is 0.0.0.0 it is not up */
-                       if(((addr.sa_data[2] & 255) == 0 && (addr.sa_data[3] & 255) == 0 &&
-                           (addr.sa_data[4] & 255) == 0 && (addr.sa_data[5] & 255) == 0) || 
-                           /* oh yeah also include IANA link local RFC3330
-                           * http://www.faqs.org/rfcs/rfc3330.html
-                            * http://www.iana.org/assignments/ipv4-address-space Notes [6]
-                            * exclude 169.254.*.*  how about 223.255 and 240.0??? */
-                          ((addr.sa_data[2] & 255) == 169 && (addr.sa_data[3] & 255) == 254)) {
-                               break;
-                       }
-                       /* otherwise we are good */
-                       free(conf.ifc_buf);
-                       close(fd);
-                       return 1;
-               }
+               goto END_FALSE;
+       }
+
+       if (!(ifr.ifr_flags & IFF_UP)) /* iface is not up */
+               goto END_FALSE;
+       if (ifup_strictness == IFUP_UP)
+               goto END_TRUE;
+
+       if (!(ifr.ifr_flags & IFF_RUNNING))
+               goto END_FALSE;
+       if (ifup_strictness == IFUP_LINK)
+               goto END_TRUE;
+
+       if (ioctl(fd, SIOCGIFADDR, &ifr)) {
+               perror("SIOCGIFADDR");
+               goto END_FALSE;
        }
-       /* cleanup */
+       if (((struct sockaddr_in *)&(ifr.ifr_ifru.ifru_addr))->sin_addr.s_addr)
+               goto END_TRUE;
+
+END_FALSE:
        close(fd);
-       free(conf.ifc_buf);
        return 0;
+END_TRUE:
+       close(fd);
+       return 1;
 }
 
 #define COND_FREE(x) if(x) free(x); x = 0