xdbe replaced with more generic pixmap based buffering but there are 3 major bugs:
[monky] / src / net_stat.c
index 59ecf47..c8c7640 100644 (file)
@@ -10,7 +10,7 @@
  * Please see COPYING for details
  *
  * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
- * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
+ * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
  *     (see AUTHORS)
  * All rights reserved.
  *
  */
 
 #include "config.h"
+#include "conky.h"
 #include "logging.h"
 #include "specials.h"
 #include "net/if.h"
 #include "text_object.h"
 #include "net_stat.h"
+#include <netinet/in.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/ioctl.h>
+#include <unistd.h>
 
 /* network interface stuff */
 
-struct net_stat netstats[16];
+struct net_stat netstats[MAX_NET_INTERFACES];
 
 struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_at_crash2)
 {
@@ -51,21 +54,21 @@ struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_
        }
 
        /* find interface stat */
-       for (i = 0; i < 16; i++) {
+       for (i = 0; i < MAX_NET_INTERFACES; i++) {
                if (netstats[i].dev && strcmp(netstats[i].dev, dev) == 0) {
                        return &netstats[i];
                }
        }
 
        /* wasn't found? add it */
-       for (i = 0; i < 16; i++) {
+       for (i = 0; i < MAX_NET_INTERFACES; i++) {
                if (netstats[i].dev == 0) {
                        netstats[i].dev = strndup(dev, text_buffer_size);
                        return &netstats[i];
                }
        }
 
-       CRIT_ERR(free_at_crash1, free_at_crash2, "too many interfaces used (limit is 16)");
+       CRIT_ERR(free_at_crash1, free_at_crash2, "too many interfaces used (limit is %d)", MAX_NET_INTERFACES);
        return 0;
 }
 
@@ -74,99 +77,114 @@ void parse_net_stat_arg(struct text_object *obj, const char *arg, void *free_at_
        if (!arg)
                arg = DEFAULTNETDEV;
 
-       obj->data.net = get_net_stat(arg, obj, free_at_crash);
+       obj->data.opaque = get_net_stat(arg, obj, free_at_crash);
 }
 
 void parse_net_stat_bar_arg(struct text_object *obj, const char *arg, void *free_at_crash)
 {
-       SIZE_DEFAULTS(bar);
        if (arg) {
-               arg = scan_bar(arg, &obj->a, &obj->b);
-               obj->data.net = get_net_stat(arg, obj, free_at_crash);
+               arg = scan_bar(obj, arg);
+               obj->data.opaque = get_net_stat(arg, obj, free_at_crash);
        } else {
                // default to DEFAULTNETDEV
                char *buf = strndup(DEFAULTNETDEV, text_buffer_size);
-               obj->data.net = get_net_stat(buf, obj, free_at_crash);
+               obj->data.opaque = get_net_stat(buf, obj, free_at_crash);
                free(buf);
        }
 }
 
 void print_downspeed(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       human_readable(obj->data.net.recv_speed, p, p_max_size);
+       human_readable(ns->recv_speed, p, p_max_size);
 }
 
 void print_downspeedf(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       spaced_print(p, p_max_size, "%.1f", 8, obj->data.netrecv_speed / 1024.0);
+       spaced_print(p, p_max_size, "%.1f", 8, ns->recv_speed / 1024.0);
 }
 
 void print_upspeed(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       human_readable(obj->data.net.trans_speed, p, p_max_size);
+       human_readable(ns->trans_speed, p, p_max_size);
 }
 
 void print_upspeedf(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       spaced_print(p, p_max_size, "%.1f", 8, obj->data.net.trans_speed / 1024.0);
+       spaced_print(p, p_max_size, "%.1f", 8, ns->trans_speed / 1024.0);
 }
 
 void print_totaldown(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       human_readable(obj->data.net.recv, p, p_max_size);
+       human_readable(ns->recv, p, p_max_size);
 }
 
 void print_totalup(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       human_readable(obj->data.net.trans, p, p_max_size);
+       human_readable(ns->trans, p, p_max_size);
 }
 
 void print_addr(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       if ((obj->data.net.addr.sa_data[2] & 255) == 0 &&
-           (obj->data.net.addr.sa_data[3] & 255) == 0 &&
-           (obj->data.net.addr.sa_data[4] & 255) == 0 &&
-           (obj->data.net.addr.sa_data[5] & 255) == 0) {
+       if ((ns->addr.sa_data[2] & 255) == 0 &&
+           (ns->addr.sa_data[3] & 255) == 0 &&
+           (ns->addr.sa_data[4] & 255) == 0 &&
+           (ns->addr.sa_data[5] & 255) == 0) {
                snprintf(p, p_max_size, "No Address");
        } else {
                snprintf(p, p_max_size, "%u.%u.%u.%u",
-                        obj->data.net.addr.sa_data[2] & 255,
-                        obj->data.net.addr.sa_data[3] & 255,
-                        obj->data.net.addr.sa_data[4] & 255,
-                        obj->data.net.addr.sa_data[5] & 255);
+                        ns->addr.sa_data[2] & 255,
+                        ns->addr.sa_data[3] & 255,
+                        ns->addr.sa_data[4] & 255,
+                        ns->addr.sa_data[5] & 255);
        }
 }
 
 #ifdef __linux__
 void print_addrs(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       if (NULL != obj->data.net.addrs && strlen(obj->data.net.addrs) > 2) {
-               obj->data.net.addrs[strlen(obj->data.net.addrs) - 2] = 0; /* remove ", " from end of string */
-               strncpy(p, obj->data.net.addrs, p_max_size);
+       if (NULL != ns->addrs && strlen(ns->addrs) > 2) {
+               ns->addrs[strlen(ns->addrs) - 2] = 0; /* remove ", " from end of string */
+               strncpy(p, ns->addrs, p_max_size);
        } else {
                strncpy(p, "0.0.0.0", p_max_size);
        }
@@ -177,35 +195,35 @@ void print_addrs(struct text_object *obj, char *p, int p_max_size)
 void parse_net_stat_graph_arg(struct text_object *obj, const char *arg, void *free_at_crash)
 {
        char *buf = 0;
-       SIZE_DEFAULTS(graph);
-       buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
-                       &obj->e, &obj->char_a, &obj->char_b);
+       buf = scan_graph(obj, arg, 0);
 
        // default to DEFAULTNETDEV
        if (buf) {
-               obj->data.net = get_net_stat(buf, obj, free_at_crash);
+               obj->data.opaque = get_net_stat(buf, obj, free_at_crash);
                free(buf);
                return;
        }
-       obj->data.net = get_net_stat(DEFAULTNETDEV, obj, free_at_crash);
+       obj->data.opaque = get_net_stat(DEFAULTNETDEV, obj, free_at_crash);
 }
 
-void print_downspeedgraph(struct text_object *obj, char *p)
+void print_downspeedgraph(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns || !p_max_size)
                return;
 
-       new_graph(p, obj->a, obj->b, obj->c, obj->d,
-                       obj->data.net.recv_speed / 1024.0, obj->e, 1, obj->char_a, obj->char_b);
+       new_graph(obj, p, p_max_size, ns->recv_speed / 1024.0);
 }
 
-void print_upspeedgraph(struct text_object *obj, char *p)
+void print_upspeedgraph(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns || !p_max_size)
                return;
 
-       new_graph(p, obj->a, obj->b, obj->c, obj->d,
-                       obj->data.net.trans_speed / 1024.0, obj->e, 1, obj->char_a, obj->char_b);
+       new_graph(obj, p, p_max_size, ns->trans_speed / 1024.0);
 }
 #endif /* X11 */
 
@@ -213,75 +231,82 @@ void print_upspeedgraph(struct text_object *obj, char *p)
 #ifdef HAVE_IWLIB
 void print_wireless_essid(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       snprintf(p, p_max_size, "%s", obj->data.net.essid);
+       snprintf(p, p_max_size, "%s", ns->essid);
 }
 void print_wireless_mode(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       snprintf(p, p_max_size, "%s", obj->data.net.mode);
+       snprintf(p, p_max_size, "%s", ns->mode);
 }
 void print_wireless_bitrate(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       snprintf(p, p_max_size, "%s", obj->data.net.bitrate);
+       snprintf(p, p_max_size, "%s", ns->bitrate);
 }
 void print_wireless_ap(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       snprintf(p, p_max_size, "%s", obj->data.net.ap);
+       snprintf(p, p_max_size, "%s", ns->ap);
 }
 void print_wireless_link_qual(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       spaced_print(p, p_max_size, "%d", 4, obj->data.net.link_qual);
+       spaced_print(p, p_max_size, "%d", 4, ns->link_qual);
 }
 void print_wireless_link_qual_max(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       spaced_print(p, p_max_size, "%d", 4, obj->data.net.link_qual_max);
+       spaced_print(p, p_max_size, "%d", 4, ns->link_qual_max);
 }
 void print_wireless_link_qual_perc(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-       if (obj->data.net.link_qual_max > 0) {
+       if (ns->link_qual_max > 0) {
                spaced_print(p, p_max_size, "%.0f", 5,
-                               (double) obj->data.net.link_qual /
-                               obj->data.net.link_qual_max * 100);
+                               (double) ns->link_qual /
+                               ns->link_qual_max * 100);
        } else {
                spaced_print(p, p_max_size, "unk", 5);
        }
 }
 void print_wireless_link_bar(struct text_object *obj, char *p, int p_max_size)
 {
-       if (!obj->data.net)
+       struct net_stat *ns = obj->data.opaque;
+
+       if (!ns)
                return;
 
-#ifdef X11
-       if(output_methods & TO_X) {
-               new_bar(p, obj->a, obj->b, ((double) obj->data.net.link_qual /
-                                       obj->data.net.link_qual_max) * 255.0);
-       } else
-#endif /* X11 */
-       {
-               if(!obj->a) obj->a = DEFAULT_BAR_WIDTH_NO_X;
-               new_bar_in_shell(p, p_max_size, ((double) obj->data.net.link_qual /
-                                       obj->data.net.link_qual_max) * 100.0, obj->a);
-       }
+       new_bar(obj, p, p_max_size,
+                       ((double) ns->link_qual / ns->link_qual_max) * 255.0);
 }
 #endif /* HAVE_IWLIB */
 #endif /* __linux__ */
@@ -289,7 +314,7 @@ void print_wireless_link_bar(struct text_object *obj, char *p, int p_max_size)
 void clear_net_stats(void)
 {
        int i;
-       for (i = 0; i < 16; i++) {
+       for (i = 0; i < MAX_NET_INTERFACES; i++) {
                if (netstats[i].dev) {
                        free(netstats[i].dev);
                }
@@ -297,11 +322,28 @@ void clear_net_stats(void)
        memset(netstats, 0, sizeof(netstats));
 }
 
+void parse_if_up_arg(struct text_object *obj, const char *arg)
+{
+       obj->data.opaque = strndup(arg, text_buffer_size);
+}
+
+void free_if_up(struct text_object *obj)
+{
+       if (obj->data.opaque) {
+               free(obj->data.opaque);
+               obj->data.opaque = NULL;
+       }
+}
+
 /* We should check if this is ok with OpenBSD and NetBSD as well. */
-int interface_up(const char *dev)
+int interface_up(struct text_object *obj)
 {
        int fd;
        struct ifreq ifr;
+       char *dev = obj->data.opaque;
+
+       if (!dev)
+               return 0;
 
        if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
                CRIT_ERR(NULL, NULL, "could not create sockfd");
@@ -358,7 +400,7 @@ void free_dns_data(void)
        memset(&dns_data, 0, sizeof(dns_data));
 }
 
-void update_dns_data(void)
+int update_dns_data(void)
 {
        FILE *fp;
        char line[256];
@@ -374,7 +416,7 @@ void update_dns_data(void)
        free_dns_data();
 
        if ((fp = fopen("/etc/resolv.conf", "r")) == NULL)
-               return;
+               return 0;
        while(!feof(fp)) {
                if (fgets(line, 255, fp) == NULL) {
                        break;
@@ -387,6 +429,7 @@ void update_dns_data(void)
                }
        }
        fclose(fp);
+       return 0;
 }
 
 void parse_nameserver_arg(struct text_object *obj, const char *arg)