diff --git a/src/Makefile.am b/src/Makefile.am index f22eddae..e12f0222 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -51,11 +51,11 @@ endif # BUILD_CONFIG_OUTPUT # source files always needed for compiling mandatory_sources = colours.c colours.h combine.c combine.h common.c common.h \ conky.c conky.h core.c core.h diskio.c diskio.h exec.c exec.h fs.c \ - fs.h logging.h mail.c mail.h mixer.c mixer.h template.c template.h \ - timed_thread.c timed_thread.h mboxscan.c mboxscan.h read_tcp.c \ - read_tcp.h scroll.c scroll.h specials.c specials.h tailhead.c \ - tailhead.h temphelper.c temphelper.h text_object.c text_object.h \ - timeinfo.c timeinfo.h algebra.c algebra.h + fs.h logging.h mail.c mail.h mixer.c mixer.h net_stat.c net_stat.h \ + template.c template.h timed_thread.c timed_thread.h mboxscan.c \ + mboxscan.h read_tcp.c read_tcp.h scroll.c scroll.h specials.c \ + specials.h tailhead.c tailhead.h temphelper.c temphelper.h \ + text_object.c text_object.h timeinfo.c timeinfo.h algebra.c algebra.h # source files only needed when the apropriate option is enabled audacious = audacious.c audacious.h diff --git a/src/common.c b/src/common.c index eb61b72f..160f23c6 100644 --- a/src/common.c +++ b/src/common.c @@ -32,6 +32,7 @@ #include "conky.h" #include "fs.h" #include "logging.h" +#include "net_stat.h" #include #include #include @@ -211,135 +212,6 @@ void variable_substitute(const char *s, char *dest, unsigned int n) *dest = '\0'; } -/* network interface stuff */ - -static struct net_stat netstats[16]; - -struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_at_crash2) -{ - unsigned int i; - - if (!dev) { - return 0; - } - - /* find interface stat */ - for (i = 0; i < 16; 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++) { - 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)"); - return 0; -} - -void clear_net_stats(void) -{ - int i; - for (i = 0; i < 16; i++) { - if (netstats[i].dev) { - free(netstats[i].dev); - } - } - memset(netstats, 0, sizeof(netstats)); -} - -/* We should check if this is ok with OpenBSD and NetBSD as well. */ -int interface_up(const char *dev) -{ - int fd; - struct ifreq ifr; - - if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { - CRIT_ERR(NULL, NULL, "could not create sockfd"); - return 0; - } - strncpy(ifr.ifr_name, dev, IFNAMSIZ); - if (ioctl(fd, SIOCGIFFLAGS, &ifr)) { - /* if device does not exist, treat like not up */ - if (errno != ENODEV && errno != ENXIO) - perror("SIOCGIFFLAGS"); - 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; - } - if (((struct sockaddr_in *)&(ifr.ifr_ifru.ifru_addr))->sin_addr.s_addr) - goto END_TRUE; - -END_FALSE: - close(fd); - return 0; -END_TRUE: - close(fd); - return 1; -} - -void free_dns_data(void) -{ - int i; - struct dns_data *data = &info.nameserver_info; - for (i = 0; i < data->nscount; i++) - free(data->ns_list[i]); - if (data->ns_list) - free(data->ns_list); - memset(data, 0, sizeof(struct dns_data)); -} - -//static double last_dns_update; - -void update_dns_data(void) -{ - FILE *fp; - char line[256]; - struct dns_data *data = &info.nameserver_info; - - /* maybe updating too often causes higher load because of /etc lying on a real FS - if (current_update_time - last_dns_update < 10.0) - return; - else - last_dns_update = current_update_time; - */ - - free_dns_data(); - - if ((fp = fopen("/etc/resolv.conf", "r")) == NULL) - return; - while(!feof(fp)) { - if (fgets(line, 255, fp) == NULL) { - break; - } - if (!strncmp(line, "nameserver ", 11)) { - line[strlen(line) - 1] = '\0'; // remove trailing newline - data->nscount++; - data->ns_list = realloc(data->ns_list, data->nscount * sizeof(char *)); - data->ns_list[data->nscount - 1] = strndup(line + 11, text_buffer_size); - } - } - fclose(fp); -} - void format_seconds(char *buf, unsigned int n, long seconds) { long days; diff --git a/src/common.h b/src/common.h index d39d1562..33d9d1db 100644 --- a/src/common.h +++ b/src/common.h @@ -18,7 +18,6 @@ void start_update_threading(void); void strfold(char *start, int count); int check_mount(char *s); void prepare_update(void); -void update_dns_data(void); void update_uptime(void); void update_meminfo(void); void update_net_stats(void); @@ -59,35 +58,6 @@ unsigned int round_to_int(float); extern int no_buffers; -struct dns_data { - int nscount; - char **ns_list; -}; -void free_dns_data(void); - -struct net_stat { - char *dev; - int up; - long long last_read_recv, last_read_trans; - long long recv, trans; - double recv_speed, trans_speed; - struct sockaddr addr; -#if defined(__linux__) - char addrs[273]; -#endif /* __linux__ */ - double net_rec[15], net_trans[15]; - // wireless extensions - char essid[32]; - char bitrate[16]; - char mode[16]; - int link_qual; - int link_qual_max; - char ap[18]; -}; -void clear_net_stats(void); -struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_at_crash2); -int interface_up(const char *dev); - void get_adt746x_cpu(char *, size_t); void get_adt746x_fan(char *, size_t); diff --git a/src/conky.c b/src/conky.c index fb235fa9..db88a3c3 100644 --- a/src/conky.c +++ b/src/conky.c @@ -89,6 +89,7 @@ #include "mixer.h" #include "mail.h" #include "mboxscan.h" +#include "net_stat.h" #include "read_tcp.h" #include "scroll.h" #include "specials.h" @@ -924,47 +925,28 @@ void generate_text_internal(char *p, int p_max_size, #ifdef HAVE_IWLIB OBJ(wireless_essid) { - snprintf(p, p_max_size, "%s", obj->data.net->essid); + print_wireless_essid(obj, p, p_max_size); } OBJ(wireless_mode) { - snprintf(p, p_max_size, "%s", obj->data.net->mode); + print_wireless_mode(obj, p, p_max_size); } OBJ(wireless_bitrate) { - snprintf(p, p_max_size, "%s", obj->data.net->bitrate); + print_wireless_bitrate(obj, p, p_max_size); } OBJ(wireless_ap) { - snprintf(p, p_max_size, "%s", obj->data.net->ap); + print_wireless_ap(obj, p, p_max_size); } OBJ(wireless_link_qual) { - spaced_print(p, p_max_size, "%d", 4, - obj->data.net->link_qual); + print_wireless_link_qual(obj, p, p_max_size); } OBJ(wireless_link_qual_max) { - spaced_print(p, p_max_size, "%d", 4, - obj->data.net->link_qual_max); + print_wireless_link_qual_max(obj, p, p_max_size); } OBJ(wireless_link_qual_perc) { - if (obj->data.net->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); - } else { - spaced_print(p, p_max_size, "unk", 5); - } + print_wireless_link_qual_perc(obj, p, p_max_size); } OBJ(wireless_link_bar) { -#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); -#ifdef X11 - } -#endif /* X11 */ + print_wireless_link_bar(obj, p, p_max_size); } #endif /* HAVE_IWLIB */ @@ -1275,16 +1257,14 @@ void generate_text_internal(char *p, int p_max_size, } #endif /* X11 */ OBJ(downspeed) { - human_readable(obj->data.net->recv_speed, p, 255); + print_downspeed(obj, p, p_max_size); } OBJ(downspeedf) { - spaced_print(p, p_max_size, "%.1f", 8, - obj->data.net->recv_speed / 1024.0); + print_downspeedf(obj, p, p_max_size); } #ifdef X11 OBJ(downspeedgraph) { - 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); + print_downspeedgraph(obj, p); } #endif /* X11 */ OBJ(else) { @@ -1299,27 +1279,11 @@ void generate_text_internal(char *p, int p_max_size, /* harmless object, just ignore */ } OBJ(addr) { - 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) { - 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); - } + print_addr(obj, p, p_max_size); } #if defined(__linux__) OBJ(addrs) { - 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 */ - strcpy(p, obj->data.net->addrs); - } else { - strcpy(p, "0.0.0.0"); - } + print_addrs(obj, p, p_max_size); } #endif /* __linux__ */ #if defined(IMLIB2) && defined(X11) @@ -1487,9 +1451,7 @@ void generate_text_internal(char *p, int p_max_size, } #endif OBJ(nameserver) { - if (cur->nameserver_info.nscount > obj->data.i) - snprintf(p, p_max_size, "%s", - cur->nameserver_info.ns_list[obj->data.i]); + print_nameserver(obj, p, p_max_size); } #ifdef EVE OBJ(eve) { @@ -1909,10 +1871,10 @@ void generate_text_internal(char *p, int p_max_size, print_tztime(obj, p, p_max_size); } OBJ(totaldown) { - human_readable(obj->data.net->recv, p, 255); + print_totaldown(obj, p, p_max_size); } OBJ(totalup) { - human_readable(obj->data.net->trans, p, 255); + print_totalup(obj, p, p_max_size); } OBJ(updates) { snprintf(p, p_max_size, "%d", total_updates); @@ -1923,16 +1885,14 @@ void generate_text_internal(char *p, int p_max_size, } } OBJ(upspeed) { - human_readable(obj->data.net->trans_speed, p, 255); + print_upspeed(obj, p, p_max_size); } OBJ(upspeedf) { - spaced_print(p, p_max_size, "%.1f", 8, - obj->data.net->trans_speed / 1024.0); + print_upspeedf(obj, p, p_max_size); } #ifdef X11 OBJ(upspeedgraph) { - 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); + print_upspeedgraph(obj, p); } #endif /* X11 */ OBJ(uptime_short) { diff --git a/src/conky.h b/src/conky.h index 62a4ac3e..33183318 100644 --- a/src/conky.h +++ b/src/conky.h @@ -256,7 +256,6 @@ struct information { struct bmpx_s bmpx; #endif struct usr_info users; - struct dns_data nameserver_info; struct process *cpu[10]; struct process *memu[10]; struct process *time[10]; diff --git a/src/core.c b/src/core.c index 4db44eaa..36d1e34c 100644 --- a/src/core.c +++ b/src/core.c @@ -48,6 +48,7 @@ #include "mixer.h" #include "mail.h" #include "mboxscan.h" +#include "net_stat.h" #include "read_tcp.h" #include "scroll.h" #include "specials.h" @@ -82,7 +83,7 @@ void update_entropy(void); * which gets overwritten in consecutive calls. I.e.: * this function is NOT reentrant. */ -static const char *dev_name(const char *path) +const char *dev_name(const char *path) { static char buf[255]; /* should be enough for pathnames */ ssize_t buflen; @@ -206,79 +207,21 @@ struct text_object *construct_text_object(const char *s, const char *arg, long #ifdef HAVE_IWLIB END OBJ(wireless_essid, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(wireless_mode, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(wireless_bitrate, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(wireless_ap, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(wireless_link_qual, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(wireless_link_qual_max, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(wireless_link_qual_perc, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(wireless_link_bar, &update_net_stats) - SIZE_DEFAULTS(bar); - if (arg) { - arg = scan_bar(arg, &obj->a, &obj->b); - obj->data.net = 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); - free(buf); - } + parse_net_stat_bar_arg(obj, arg, free_at_crash); #endif /* HAVE_IWLIB */ #endif /* __linux__ */ @@ -550,34 +493,12 @@ struct text_object *construct_text_object(const char *s, const char *arg, long END OBJ(conky_build_date, 0) END OBJ(conky_build_arch, 0) END OBJ(downspeed, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(downspeedf, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); #ifdef X11 END OBJ(downspeedgraph, &update_net_stats) - 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); - - // default to DEFAULTNETDEV - buf = strndup(buf ? buf : DEFAULTNETDEV, text_buffer_size); - obj->data.net = get_net_stat(buf, obj, free_at_crash); - free(buf); + parse_net_stat_graph_arg(obj, arg, free_at_crash); #endif /* X11 */ END OBJ(else, 0) obj_be_ifblock_else(ifblock_opaque, obj); @@ -660,7 +581,7 @@ struct text_object *construct_text_object(const char *s, const char *arg, long END OBJ(hr, 0) obj->data.i = arg ? atoi(arg) : 1; END OBJ(nameserver, &update_dns_data) - obj->data.i = arg ? atoi(arg) : 0; + parse_nameserver_arg(obj, arg); END OBJ(offset, 0) obj->data.i = arg ? atoi(arg) : 1; END OBJ(voffset, 0) @@ -701,24 +622,10 @@ struct text_object *construct_text_object(const char *s, const char *arg, long return NULL; } } else OBJ(addr, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); #if defined(__linux__) END OBJ(addrs, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); #endif /* __linux__ */ END OBJ_ARG(tail, 0, "tail needs arguments") init_tailhead("tail", arg, obj, free_at_crash); @@ -1094,24 +1001,9 @@ struct text_object *construct_text_object(const char *s, const char *arg, long init_iconv_stop(); #endif END OBJ(totaldown, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(totalup, &update_net_stats) - obj->data.net = get_net_stat(arg, obj, free_at_crash); - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(updates, 0) END OBJ_IF(if_updatenr, 0) obj->data.ifblock.i = arg ? atoi(arg) : 0; @@ -1122,35 +1014,12 @@ struct text_object *construct_text_object(const char *s, const char *arg, long END OBJ(alignc, 0) obj->data.i = arg ? atoi(arg) : 0; END OBJ(upspeed, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } + parse_net_stat_arg(obj, arg, free_at_crash); END OBJ(upspeedf, &update_net_stats) - if (arg) { - obj->data.net = 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); - free(buf); - } - + parse_net_stat_arg(obj, arg, free_at_crash); #ifdef X11 END OBJ(upspeedgraph, &update_net_stats) - 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); - - // default to DEFAULTNETDEV - buf = strndup(buf ? buf : DEFAULTNETDEV, text_buffer_size); - obj->data.net = get_net_stat(buf, obj, free_at_crash); - free(buf); + parse_net_stat_graph_arg(obj, arg, free_at_crash); #endif END OBJ(uptime_short, &update_uptime) END OBJ(uptime, &update_uptime) diff --git a/src/core.h b/src/core.h index 1d1c140d..da1aa25f 100644 --- a/src/core.h +++ b/src/core.h @@ -46,4 +46,6 @@ void free_text_objects(struct text_object *root, int internal); void scan_mixer_bar(const char *arg, int *a, int *w, int *h); #endif /* X11 */ +const char *dev_name(const char *); + #endif /* _CONKY_CORE_H_ */ diff --git a/src/freebsd.c b/src/freebsd.c index 7f58eb7b..736b3948 100644 --- a/src/freebsd.c +++ b/src/freebsd.c @@ -54,6 +54,7 @@ #include "conky.h" #include "freebsd.h" #include "logging.h" +#include "net_stat.h" #include "top.h" #include "diskio.h" diff --git a/src/linux.c b/src/linux.c index 0c85a12f..e1deceb9 100644 --- a/src/linux.c +++ b/src/linux.c @@ -33,6 +33,7 @@ #include "logging.h" #include "common.h" #include "linux.h" +#include "net_stat.h" #include "diskio.h" #include "temphelper.h" #include diff --git a/src/net_stat.c b/src/net_stat.c new file mode 100644 index 00000000..59ecf477 --- /dev/null +++ b/src/net_stat.c @@ -0,0 +1,401 @@ +/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*- + * vim: ts=4 sw=4 noet ai cindent syntax=c + * + * Conky, a system monitor, based on torsmo + * + * Any original torsmo code is licensed under the BSD license + * + * All code written since the fork of torsmo is licensed under the GPL + * + * Please see COPYING for details + * + * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen + * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al. + * (see AUTHORS) + * All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "config.h" +#include "logging.h" +#include "specials.h" +#include "net/if.h" +#include "text_object.h" +#include "net_stat.h" +#include +#include +#include + +/* network interface stuff */ + +struct net_stat netstats[16]; + +struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_at_crash2) +{ + unsigned int i; + + if (!dev) { + return 0; + } + + /* find interface stat */ + for (i = 0; i < 16; 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++) { + 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)"); + return 0; +} + +void parse_net_stat_arg(struct text_object *obj, const char *arg, void *free_at_crash) +{ + if (!arg) + arg = DEFAULTNETDEV; + + obj->data.net = 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); + } else { + // default to DEFAULTNETDEV + char *buf = strndup(DEFAULTNETDEV, text_buffer_size); + obj->data.net = 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) + return; + + human_readable(obj->data.net.recv_speed, p, p_max_size); +} + +void print_downspeedf(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + spaced_print(p, p_max_size, "%.1f", 8, obj->data.netrecv_speed / 1024.0); +} + +void print_upspeed(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + human_readable(obj->data.net.trans_speed, p, p_max_size); +} + +void print_upspeedf(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + spaced_print(p, p_max_size, "%.1f", 8, obj->data.net.trans_speed / 1024.0); +} + +void print_totaldown(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + human_readable(obj->data.net.recv, p, p_max_size); +} + +void print_totalup(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + human_readable(obj->data.net.trans, p, p_max_size); +} + +void print_addr(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + 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) { + 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); + } +} + +#ifdef __linux__ +void print_addrs(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + 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); + } else { + strncpy(p, "0.0.0.0", p_max_size); + } +} +#endif /* __linux__ */ + +#ifdef X11 +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); + + // default to DEFAULTNETDEV + if (buf) { + obj->data.net = get_net_stat(buf, obj, free_at_crash); + free(buf); + return; + } + obj->data.net = get_net_stat(DEFAULTNETDEV, obj, free_at_crash); +} + +void print_downspeedgraph(struct text_object *obj, char *p) +{ + if (!obj->data.net) + 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); +} + +void print_upspeedgraph(struct text_object *obj, char *p) +{ + if (!obj->data.net) + 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); +} +#endif /* X11 */ + +#ifdef __linux__ +#ifdef HAVE_IWLIB +void print_wireless_essid(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + snprintf(p, p_max_size, "%s", obj->data.net.essid); +} +void print_wireless_mode(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + snprintf(p, p_max_size, "%s", obj->data.net.mode); +} +void print_wireless_bitrate(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + snprintf(p, p_max_size, "%s", obj->data.net.bitrate); +} +void print_wireless_ap(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + snprintf(p, p_max_size, "%s", obj->data.net.ap); +} +void print_wireless_link_qual(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + spaced_print(p, p_max_size, "%d", 4, obj->data.net.link_qual); +} +void print_wireless_link_qual_max(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + spaced_print(p, p_max_size, "%d", 4, obj->data.net.link_qual_max); +} +void print_wireless_link_qual_perc(struct text_object *obj, char *p, int p_max_size) +{ + if (!obj->data.net) + return; + + if (obj->data.net.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); + } 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) + 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); + } +} +#endif /* HAVE_IWLIB */ +#endif /* __linux__ */ + +void clear_net_stats(void) +{ + int i; + for (i = 0; i < 16; i++) { + if (netstats[i].dev) { + free(netstats[i].dev); + } + } + memset(netstats, 0, sizeof(netstats)); +} + +/* We should check if this is ok with OpenBSD and NetBSD as well. */ +int interface_up(const char *dev) +{ + int fd; + struct ifreq ifr; + + if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + CRIT_ERR(NULL, NULL, "could not create sockfd"); + return 0; + } + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + if (ioctl(fd, SIOCGIFFLAGS, &ifr)) { + /* if device does not exist, treat like not up */ + if (errno != ENODEV && errno != ENXIO) + perror("SIOCGIFFLAGS"); + 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; + } + if (((struct sockaddr_in *)&(ifr.ifr_ifru.ifru_addr))->sin_addr.s_addr) + goto END_TRUE; + +END_FALSE: + close(fd); + return 0; +END_TRUE: + close(fd); + return 1; +} + +static struct { + int nscount; + char **ns_list; +} dns_data = { + .nscount = 0, + .ns_list = NULL, +}; + +void free_dns_data(void) +{ + int i; + for (i = 0; i < dns_data.nscount; i++) + free(dns_data.ns_list[i]); + if (dns_data.ns_list) + free(dns_data.ns_list); + memset(&dns_data, 0, sizeof(dns_data)); +} + +void update_dns_data(void) +{ + FILE *fp; + char line[256]; + //static double last_dns_update = 0.0; + + /* maybe updating too often causes higher load because of /etc lying on a real FS + if (current_update_time - last_dns_update < 10.0) + return; + + last_dns_update = current_update_time; + */ + + free_dns_data(); + + if ((fp = fopen("/etc/resolv.conf", "r")) == NULL) + return; + while(!feof(fp)) { + if (fgets(line, 255, fp) == NULL) { + break; + } + if (!strncmp(line, "nameserver ", 11)) { + line[strlen(line) - 1] = '\0'; // remove trailing newline + dns_data.nscount++; + dns_data.ns_list = realloc(dns_data.ns_list, dns_data.nscount * sizeof(char *)); + dns_data.ns_list[dns_data.nscount - 1] = strndup(line + 11, text_buffer_size); + } + } + fclose(fp); +} + +void parse_nameserver_arg(struct text_object *obj, const char *arg) +{ + obj->data.l = arg ? atoi(arg) : 0; +} + +void print_nameserver(struct text_object *obj, char *p, int p_max_size) +{ + if (dns_data.nscount > obj->data.l) + snprintf(p, p_max_size, "%s", dns_data.ns_list[obj->data.l]); +} diff --git a/src/net_stat.h b/src/net_stat.h new file mode 100644 index 00000000..af3ba977 --- /dev/null +++ b/src/net_stat.h @@ -0,0 +1,98 @@ +/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*- + * vim: ts=4 sw=4 noet ai cindent syntax=c + * + * Conky, a system monitor, based on torsmo + * + * Any original torsmo code is licensed under the BSD license + * + * All code written since the fork of torsmo is licensed under the GPL + * + * Please see COPYING for details + * + * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen + * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al. + * (see AUTHORS) + * All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef _NET_STAT_H +#define _NET_STAT_H + +#include /* struct sockaddr */ + +struct net_stat { + char *dev; + int up; + long long last_read_recv, last_read_trans; + long long recv, trans; + double recv_speed, trans_speed; + struct sockaddr addr; +#if defined(__linux__) + char addrs[273]; +#endif /* __linux__ */ + double net_rec[15], net_trans[15]; + // wireless extensions + char essid[32]; + char bitrate[16]; + char mode[16]; + int link_qual; + int link_qual_max; + char ap[18]; +}; + +extern struct net_stat netstats[]; + +struct net_stat *get_net_stat(const char *, void *, void *); + +void parse_net_stat_arg(struct text_object *, const char *, void *); +void parse_net_stat_bar_arg(struct text_object *, const char *, void *); +void print_downspeed(struct text_object *, char *, int); +void print_downspeedf(struct text_object *, char *, int); +void print_upspeed(struct text_object *, char *, int); +void print_upspeedf(struct text_object *, char *, int); +void print_totaldown(struct text_object *, char *, int); +void print_totalup(struct text_object *, char *, int); +void print_addr(struct text_object *, char *, int); +#ifdef __linux__ +void print_addrs(struct text_object *, char *, int); +#endif /* __linux__ */ +#ifdef X11 +void parse_net_stat_graph_arg(struct text_object *, const char *, void *); +void print_downspeedgraph(struct text_object *, char *); +void print_upspeedgraph(struct text_object *, char *); +#endif /* X11 */ +#ifdef __linux__ +#ifdef HAVE_IWLIB +void print_wireless_essid(struct text_object *, char *, int); +void print_wireless_mode(struct text_object *, char *, int); +void print_wireless_bitrate(struct text_object *, char *, int); +void print_wireless_ap(struct text_object *, char *, int); +void print_wireless_link_qual(struct text_object *, char *, int); +void print_wireless_link_qual_max(struct text_object *, char *, int); +void print_wireless_link_qual_perc(struct text_object *, char *, int); +void print_wireless_link_bar(struct text_object *, char *, int); +#endif /* HAVE_IWLIB */ +#endif /* __linux__ */ + +void clear_net_stats(void); +int interface_up(const char *); + +void free_dns_data(void); +void update_dns_data(void); +void parse_nameserver_arg(struct text_object *, const char *); +void print_nameserver(struct text_object *, char *, int); + +#endif /* _NET_STAT_H */ diff --git a/src/netbsd.c b/src/netbsd.c index ccc7ebe9..dc4e0f71 100644 --- a/src/netbsd.c +++ b/src/netbsd.c @@ -29,6 +29,7 @@ */ #include "netbsd.h" +#include "net_stat.h" static kvm_t *kd = NULL; int kd_init = 0, nkd_init = 0; diff --git a/src/openbsd.c b/src/openbsd.c index bcbe0727..4d5f240d 100644 --- a/src/openbsd.c +++ b/src/openbsd.c @@ -61,6 +61,7 @@ #include "conky.h" #include "diskio.h" #include "logging.h" +#include "net_stat.h" #include "openbsd.h" #include "top.h"