From c5d065d1199a0ef3b0d7f72368fac47d4579b901 Mon Sep 17 00:00:00 2001 From: Tiago Vale Date: Sat, 4 Dec 2010 20:45:34 +0000 Subject: [PATCH 01/19] Added support for POWER_SUPPLY_POWER_NOW In Linux, apparently POWER_SUPPLY_CURRENT_NOW was deprecated and replaced by POWER_SUPPLY_POWER_NOW. In my system, ever since kernel 2.6.36.1 battery lifetime showed "unknown" in conky. Check http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=532000. Signed-off-by: Pavel Labath --- src/linux.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/linux.cc b/src/linux.cc index d25dff82..e0929204 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -1588,6 +1588,12 @@ present voltage: 16608 mV On some systems POWER_SUPPLY_ENERGY_* is replaced by POWER_SUPPLY_CHARGE_* */ +/* Tiago Marques Vale + Regarding the comment above, since kernel 2.6.36.1 I have + POWER_SUPPLY_POWER_NOW instead of POWER_SUPPLY_CURRENT_NOW + See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=532000 +*/ + #define SYSFS_BATTERY_BASE_PATH "/sys/class/power_supply" #define ACPI_BATTERY_BASE_PATH "/proc/acpi/battery" #define APM_PATH "/proc/apm" @@ -1709,6 +1715,8 @@ void get_battery_stuff(char *buffer, unsigned int n, const char *bat, int item) * tradition! */ else if (strncmp(buf, "POWER_SUPPLY_CURRENT_NOW=", 25) == 0) sscanf(buf, "POWER_SUPPLY_CURRENT_NOW=%d", &present_rate); + else if (strncmp(buf, "POWER_SUPPLY_POWER_NOW=", 23) == 0) + sscanf(buf, "POWER_SUPPLY_POWER_NOW=%d", &present_rate); else if (strncmp(buf, "POWER_SUPPLY_ENERGY_NOW=", 24) == 0) sscanf(buf, "POWER_SUPPLY_ENERGY_NOW=%d", &remaining_capacity); else if (strncmp(buf, "POWER_SUPPLY_ENERGY_FULL=", 25) == 0) From f0d48190ff0aac644f10c5ea3c4c1f68d94e18de Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Sat, 1 Jan 2011 11:37:31 +0100 Subject: [PATCH 02/19] $mixer: report more reasonable values for mono devices --- src/mixer.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mixer.cc b/src/mixer.cc index b8d09d09..0ba833c1 100644 --- a/src/mixer.cc +++ b/src/mixer.cc @@ -52,6 +52,7 @@ static int mixer_fd; static const char *devs[] = SOUND_DEVICE_NAMES; +static int stereo_flags; int mixer_init(const char *name) { @@ -70,6 +71,8 @@ int mixer_init(const char *name) } } + ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo_flags); + for (i = 0; i < sizeof(devs) / sizeof(const char *); i++) { if (strcasecmp(devs[i], name) == 0) { return i; @@ -93,6 +96,11 @@ static int mixer_get(int i) } rep = 0; + if(!(stereo_flags & (1< Date: Sun, 2 Jan 2011 14:22:40 +0100 Subject: [PATCH 03/19] Revert "$mixer: report more reasonable values for mono devices" the user reports this didn't fix the problem (see sf.net #3131452) This reverts commit 540f78f0bdf3d065b9b4620aaa16c57e227c7ef1. --- src/mixer.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/mixer.cc b/src/mixer.cc index 0ba833c1..b8d09d09 100644 --- a/src/mixer.cc +++ b/src/mixer.cc @@ -52,7 +52,6 @@ static int mixer_fd; static const char *devs[] = SOUND_DEVICE_NAMES; -static int stereo_flags; int mixer_init(const char *name) { @@ -71,8 +70,6 @@ int mixer_init(const char *name) } } - ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo_flags); - for (i = 0; i < sizeof(devs) / sizeof(const char *); i++) { if (strcasecmp(devs[i], name) == 0) { return i; @@ -96,11 +93,6 @@ static int mixer_get(int i) } rep = 0; - if(!(stereo_flags & (1< Date: Tue, 4 Jan 2011 14:48:33 +0100 Subject: [PATCH 04/19] add a $memdirty variable patch contributed by Piotr Karbowski (sf.net #3138195) --- doc/variables.xml | 9 +++++++++ src/common.cc | 1 + src/common.h | 1 + src/conky.h | 2 +- src/core.cc | 4 ++++ src/linux.cc | 4 +++- 6 files changed, 19 insertions(+), 2 deletions(-) diff --git a/doc/variables.xml b/doc/variables.xml index b55da7b9..a5f2b561 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -2032,6 +2032,15 @@ Bar that shows amount of memory in use (including memory used by system buffers and caches) + + + + + + + Amount of "dirty" memory (linux only) + + diff --git a/src/common.cc b/src/common.cc index d4fe02e0..98bbf58a 100644 --- a/src/common.cc +++ b/src/common.cc @@ -526,6 +526,7 @@ PRINT_HR_GENERATOR(memwithbuffers) PRINT_HR_GENERATOR(memeasyfree) PRINT_HR_GENERATOR(memfree) PRINT_HR_GENERATOR(memmax) +PRINT_HR_GENERATOR(memdirty) PRINT_HR_GENERATOR(swap) PRINT_HR_GENERATOR(swapfree) PRINT_HR_GENERATOR(swapmax) diff --git a/src/common.h b/src/common.h index 55f301d5..2fad9776 100644 --- a/src/common.h +++ b/src/common.h @@ -107,6 +107,7 @@ void print_memwithbuffers(struct text_object *, char *, int); void print_memeasyfree(struct text_object *, char *, int); void print_memfree(struct text_object *, char *, int); void print_memmax(struct text_object *, char *, int); +void print_memdirty(struct text_object *, char *, int); void print_swap(struct text_object *, char *, int); void print_swapfree(struct text_object *, char *, int); void print_swapmax(struct text_object *, char *, int); diff --git a/src/conky.h b/src/conky.h index de29d871..b27bab45 100644 --- a/src/conky.h +++ b/src/conky.h @@ -196,7 +196,7 @@ struct information { double uptime; /* memory information in kilobytes */ - unsigned long long mem, memwithbuffers, memeasyfree, memfree, memmax; + unsigned long long mem, memwithbuffers, memeasyfree, memfree, memmax, memdirty; unsigned long long swap, swapfree, swapmax; unsigned long long bufmem, buffers, cached; diff --git a/src/core.cc b/src/core.cc index 41b6c094..1ead4200 100644 --- a/src/core.cc +++ b/src/core.cc @@ -985,6 +985,10 @@ struct text_object *construct_text_object(char *s, const char *arg, long obj->callbacks.print = &print_memmax; END OBJ(memperc, &update_meminfo) obj->callbacks.percentage = &mem_percentage; +#ifdef __linux__ + END OBJ(memdirty, &update_meminfo) + obj->callbacks.print = &print_memdirty; +#endif #ifdef BUILD_X11 END OBJ(memgauge, &update_meminfo) scan_gauge(obj, arg, 1); diff --git a/src/linux.cc b/src/linux.cc index e0929204..b5ff75a3 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -165,7 +165,7 @@ int update_meminfo(void) /* unsigned int a; */ char buf[256]; - info.mem = info.memwithbuffers = info.memmax = info.swap = info.swapfree = info.swapmax = + info.mem = info.memwithbuffers = info.memmax = info.memdirty = info.swap = info.swapfree = info.swapmax = info.bufmem = info.buffers = info.cached = info.memfree = info.memeasyfree = 0; if (!(meminfo_fp = open_file("/proc/meminfo", &rep))) { @@ -189,6 +189,8 @@ int update_meminfo(void) sscanf(buf, "%*s %llu", &info.buffers); } else if (strncmp(buf, "Cached:", 7) == 0) { sscanf(buf, "%*s %llu", &info.cached); + } else if (strncmp(buf, "Dirty:", 6) == 0) { + sscanf(buf, "%*s %llu", &info.memdirty); } } From 41dc5db094e8b53c9ae690e8b400d146b38af57e Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 5 Jan 2011 13:54:04 +0100 Subject: [PATCH 05/19] Initialize special_t when allocating it (this should fix sf.net #3138243) --- src/specials.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/specials.cc b/src/specials.cc index 3e05810e..900a2eca 100644 --- a/src/specials.cc +++ b/src/specials.cc @@ -279,8 +279,7 @@ struct special_t *new_special_t_node() { special_t *newnode = new special_t; - newnode->graph = NULL; - newnode->next = NULL; + memset(newnode, 0, sizeof *newnode); return newnode; } From 6287b22a3d6aad2a45b91357baee068d1fd22e2a Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Wed, 9 Feb 2011 18:49:52 +0100 Subject: [PATCH 06/19] Add $v6addrs to increase IPv6 support This is only the beginning of the ipv6 support, This var isn't documented and only works on Linux. It should also be patched to show the addresses in compressed format Some other vars should also be added to see things like netmask, scope, routes, ... --- cmake/ConkyBuildOptions.cmake | 2 ++ cmake/ConkyPlatformChecks.cmake | 7 ++++++ cmake/config.h.in | 2 ++ src/core.cc | 5 +++++ src/linux.cc | 27 ++++++++++++++++++++++ src/net_stat.cc | 40 +++++++++++++++++++++++++++++++++ src/net_stat.h | 13 +++++++++++ 7 files changed, 96 insertions(+) diff --git a/cmake/ConkyBuildOptions.cmake b/cmake/ConkyBuildOptions.cmake index 219acb33..580a9a24 100644 --- a/cmake/ConkyBuildOptions.cmake +++ b/cmake/ConkyBuildOptions.cmake @@ -73,12 +73,14 @@ if(OS_LINUX) option(BUILD_WLAN "Enable wireless support" false) # nvidia may also work on FreeBSD, not sure option(BUILD_NVIDIA "Enable nvidia support" false) + option(BUILD_IPV6 "Enable if you want IPv6 support" true) else(OS_LINUX) set(BUILD_PORT_MONITORS false) set(BUILD_IBM false) set(BUILD_HDDTEMP false) set(BUILD_WLAN false) set(BUILD_NVIDIA false) + set(BUILD_IPV6 false) endif(OS_LINUX) # Optional features etc diff --git a/cmake/ConkyPlatformChecks.cmake b/cmake/ConkyPlatformChecks.cmake index a852c999..38159525 100644 --- a/cmake/ConkyPlatformChecks.cmake +++ b/cmake/ConkyPlatformChecks.cmake @@ -82,6 +82,13 @@ if(BUILD_IRC) set(conky_libs ${conky_libs} -lircclient) endif(BUILD_IRC) +if(BUILD_IPV6) + find_file(IF_INET6 if_inet6 PATHS /proc/net) + if(NOT IF_INET6) + message(FATAL_ERROR "/proc/net/if_inet6 unavailable") + endif(NOT IF_INET6) +endif(BUILD_IPV6) + if(BUILD_HTTP) find_file(HTTP_H_ microhttpd.h) #I'm not using check_include_files because microhttpd.h seems to need a lot of different headers and i'm not sure which... diff --git a/cmake/config.h.in b/cmake/config.h.in index a505765b..f946aecf 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -95,6 +95,8 @@ #cmakedefine BUILD_IRC 1 +#cmakedefine BUILD_IPV6 1 + #cmakedefine BUILD_HTTP 1 #cmakedefine BUILD_ICONV 1 diff --git a/src/core.cc b/src/core.cc index 1ead4200..c16ef15a 100644 --- a/src/core.cc +++ b/src/core.cc @@ -865,6 +865,11 @@ struct text_object *construct_text_object(char *s, const char *arg, long END OBJ(addrs, &update_net_stats) parse_net_stat_arg(obj, arg, free_at_crash); obj->callbacks.print = &print_addrs; +#ifdef BUILD_IPV6 + END OBJ(v6addrs, &update_net_stats) + parse_net_stat_arg(obj, arg, free_at_crash); + obj->callbacks.print = &print_v6addrs; +#endif /* BUILD_IPV6 */ END #endif /* __linux__ */ OBJ_ARG(tail, 0, "tail needs arguments") diff --git a/src/linux.cc b/src/linux.cc index b5ff75a3..bd09c222 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -32,6 +32,7 @@ #include "net_stat.h" #include "diskio.h" #include "temphelper.h" +#include "proc.h" #include #include #include @@ -569,6 +570,32 @@ int update_net_stats(void) free(winfo); #endif } + +#ifdef BUILD_IPV6 + FILE *file; + char v6addr[32]; + char devname[21]; + struct net_stat *ns; + struct v6addr *lastv6; + if ((file = fopen(PROCDIR"/net/if_inet6", "r")) != NULL) { + while (fscanf(file, "%32s %*02x %*02x %*02x %*02x %20s\n", v6addr, devname) != EOF) { + ns = get_net_stat(devname, NULL, NULL); + if(ns->v6addrs == NULL) { + lastv6 = (struct v6addr *) malloc(sizeof(struct v6addr)); + ns->v6addrs = lastv6; + } else { + lastv6 = ns->v6addrs; + while(lastv6->next) lastv6 = lastv6->next; + lastv6->next = (struct v6addr *) malloc(sizeof(struct v6addr)); + lastv6 = lastv6->next; + } + strncpy(lastv6->addr, v6addr, 32); + lastv6->next = NULL; + } + } + fclose(file); +#endif /* BUILD_IPV6 */ + first = 0; fclose(net_dev_fp); diff --git a/src/net_stat.cc b/src/net_stat.cc index d7b5251e..eff8aabd 100644 --- a/src/net_stat.cc +++ b/src/net_stat.cc @@ -205,6 +205,36 @@ void print_addrs(struct text_object *obj, char *p, int p_max_size) strncpy(p, "0.0.0.0", p_max_size); } } + +#ifdef BUILD_IPV6 +void print_v6addrs(struct text_object *obj, char *p, int p_max_size) +{ + struct net_stat *ns = (struct net_stat *)obj->data.opaque; + char *current_char = p; + struct v6addr *current_v6 = ns->v6addrs; + + if (!ns) + return; + + if( ! ns->v6addrs) { + strncpy(p, "::", p_max_size); + return; + } + while(current_v6) { + for(int i=0; i<8; i++) { + strncpy(current_char, current_v6->addr+(i*4), 4); + *(current_char+4)=':'; + current_char+=5; + } + current_v6 = current_v6->next; + if(current_v6) { + strncpy(current_char-1, ", ", 3); + current_char++; + } else *(current_char-1)=0; + } +} +#endif /* BUILD_IPV6 */ + #endif /* __linux__ */ #ifdef BUILD_X11 @@ -353,9 +383,19 @@ double wireless_link_barval(struct text_object *obj) void clear_net_stats(void) { +#ifdef BUILD_IPV6 + struct v6addr *nextv6; +#endif /* BUILD_IPV6 */ int i; for (i = 0; i < MAX_NET_INTERFACES; i++) { free_and_zero(netstats[i].dev); +#ifdef BUILD_IPV6 + while(netstats[i].v6addrs) { + nextv6 = netstats[i].v6addrs; + netstats[i].v6addrs = netstats[i].v6addrs->next; + free_and_zero(nextv6); + } +#endif /* BUILD_IPV6 */ } memset(netstats, 0, sizeof(netstats)); } diff --git a/src/net_stat.h b/src/net_stat.h index e048eba7..21e29bdf 100644 --- a/src/net_stat.h +++ b/src/net_stat.h @@ -33,6 +33,13 @@ #include /* struct sockaddr */ +#ifdef BUILD_IPV6 +struct v6addr { + char addr[32]; + struct v6addr *next; +}; +#endif /* BUILD_IPV6 */ + struct net_stat { char *dev; int up; @@ -40,6 +47,9 @@ struct net_stat { long long recv, trans; double recv_speed, trans_speed; struct sockaddr addr; +#ifdef BUILD_IPV6 + struct v6addr *v6addrs; +#endif /* BUILD_IPV6 */ #if defined(__linux__) char addrs[273]; #endif /* __linux__ */ @@ -70,6 +80,9 @@ 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); +#ifdef BUILD_IPV6 +void print_v6addrs(struct text_object *, char *, int); +#endif /* BUILD_IPV6 */ #endif /* __linux__ */ #ifdef BUILD_X11 void parse_net_stat_graph_arg(struct text_object *, const char *, void *); From 2aafb591ee28d00a881fa104b698c26d19f32f59 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Thu, 10 Feb 2011 01:08:34 +0100 Subject: [PATCH 07/19] Add fscanf_no_i18n() to fix sf.net #3154556 --- src/linux.cc | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/linux.cc b/src/linux.cc index bd09c222..00c343e2 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -871,6 +871,26 @@ int update_cpu_usage(void) return 0; } +//fscanf() that reads floats with points even if you are using a locale where +//floats are with commas +int fscanf_no_i18n(FILE *stream, const char *format, ...) { + int returncode; + va_list ap; + +#ifdef BUILD_I18N + const char *oldlocale = setlocale(LC_NUMERIC, NULL); + + setlocale(LC_NUMERIC, "C"); +#endif + va_start(ap, format); + returncode = vfscanf(stream, format, ap); + va_end(ap); +#ifdef BUILD_I18N + setlocale(LC_NUMERIC, oldlocale); +#endif + return returncode; +} + int update_load_average(void) { #ifdef HAVE_GETLOADAVG @@ -891,7 +911,7 @@ int update_load_average(void) info.loadavg[0] = info.loadavg[1] = info.loadavg[2] = 0.0; return 0; } - if (fscanf(fp, "%f %f %f", &info.loadavg[0], &info.loadavg[1], + if (fscanf_no_i18n(fp, "%f %f %f", &info.loadavg[0], &info.loadavg[1], &info.loadavg[2]) < 0) info.loadavg[0] = info.loadavg[1] = info.loadavg[2] = 0.0; fclose(fp); From 5a5e8f80b1145239a1e194fe02aac0e274ca810a Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Thu, 10 Feb 2011 16:01:16 +0100 Subject: [PATCH 08/19] Support for short-version ipv6-addresses --- src/net_stat.cc | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/net_stat.cc b/src/net_stat.cc index eff8aabd..42e88331 100644 --- a/src/net_stat.cc +++ b/src/net_stat.cc @@ -221,10 +221,35 @@ void print_v6addrs(struct text_object *obj, char *p, int p_max_size) return; } while(current_v6) { - for(int i=0; i<8; i++) { - strncpy(current_char, current_v6->addr+(i*4), 4); - *(current_char+4)=':'; - current_char+=5; + char extracompress = 0; //0 until the first '0000', 1 after the first '0000', 2 after the first non-'0000' after a '0000' + for(int i=0; i<8; i++) { //loop trough the 8 parts of the ipv6 + //skip the zeros in front of each part + int j=0; + while(j<4) if(*(current_v6->addr+(i*4)+j) == '0') j++; else break; + if(j==4) { + if(*(current_v6->addr+(i*4)+3) == '0') { //4 zeros + switch(extracompress) { + case 0: //first time this happens, so replace by '::' + *current_char = ':'; + current_char++; + if(current_char == p+1) { //to make sure there is no ':::' when the first '0000' isn't at the beginning + *current_char = ':'; + current_char++; + } + extracompress=1; + continue; + case 1: //again, ignore them, they are included in the '::' + continue; + default: //again, but only remove the first 3 zero's because extra-compression may no longer be applied + j=3; //but if there are 4 zero's, keep the last + } + } else j=0; //no zeros to skip + } + if(extracompress == 1) extracompress = 2; + //place each part followed by : in the ip + strncpy(current_char, current_v6->addr+(i*4)+j, 4-j); + *(current_char+4-j)=':'; + current_char+=5-j; } current_v6 = current_v6->next; if(current_v6) { From ac4a3682aecb9d6466fea4aebb183b5f8f632905 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Thu, 10 Feb 2011 16:20:06 +0100 Subject: [PATCH 09/19] Fix security bug in 's getSkillname --- src/eve.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/eve.cc b/src/eve.cc index 187a5f4e..29b8c45c 100644 --- a/src/eve.cc +++ b/src/eve.cc @@ -285,7 +285,8 @@ static char *getSkillname(const char *file, int skillid) if (!file_exists(file)) { skilltree = getXmlFromAPI(NULL, NULL, NULL, EVEURL_SKILLTREE); - writeSkilltree(skilltree, file); +//2x file_exits() so that someone (malicious?) couldn't create it during during the previous call + if (!file_exists(file)) writeSkilltree(skilltree, file); free(skilltree); } From b548f476ccd4076de095bf1c41d32228b917317b Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Thu, 10 Feb 2011 23:27:14 +0100 Subject: [PATCH 10/19] Support for -n in $v6addrs --- src/linux.cc | 4 +++- src/net_stat.cc | 33 ++++++++++++++++++++++++++++----- src/net_stat.h | 2 ++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/linux.cc b/src/linux.cc index 00c343e2..5b5a5404 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -575,10 +575,11 @@ int update_net_stats(void) FILE *file; char v6addr[32]; char devname[21]; + unsigned int netmask; struct net_stat *ns; struct v6addr *lastv6; if ((file = fopen(PROCDIR"/net/if_inet6", "r")) != NULL) { - while (fscanf(file, "%32s %*02x %*02x %*02x %*02x %20s\n", v6addr, devname) != EOF) { + while (fscanf(file, "%32s %*02x %02x %*02x %*02x %20s\n", v6addr, &netmask, devname) != EOF) { ns = get_net_stat(devname, NULL, NULL); if(ns->v6addrs == NULL) { lastv6 = (struct v6addr *) malloc(sizeof(struct v6addr)); @@ -590,6 +591,7 @@ int update_net_stats(void) lastv6 = lastv6->next; } strncpy(lastv6->addr, v6addr, 32); + lastv6->netmask = netmask; lastv6->next = NULL; } } diff --git a/src/net_stat.cc b/src/net_stat.cc index 42e88331..7f46a9e7 100644 --- a/src/net_stat.cc +++ b/src/net_stat.cc @@ -90,10 +90,24 @@ struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_ void parse_net_stat_arg(struct text_object *obj, const char *arg, void *free_at_crash) { + bool shownetmask = false; + char dev[21]; //a netdev can only be 20 chars long + int i=0; + if (!arg) arg = DEFAULTNETDEV; - obj->data.opaque = get_net_stat(arg, obj, free_at_crash); + if (*arg == '-') { //there are flags + for(i=1; arg[i] != ' ' && arg[i] != 0; i++) { + if(arg[i]=='n') shownetmask = true; + } + } + sscanf(arg+i, "%20s", dev); + if(*dev==0) strcpy(dev, DEFAULTNETDEV); + + struct net_stat *netstat = get_net_stat(dev, obj, free_at_crash); + netstat->v6show_nm = shownetmask; + obj->data.opaque = netstat; } void parse_net_stat_bar_arg(struct text_object *obj, const char *arg, void *free_at_crash) @@ -217,7 +231,7 @@ void print_v6addrs(struct text_object *obj, char *p, int p_max_size) return; if( ! ns->v6addrs) { - strncpy(p, "::", p_max_size); + if(ns->v6show_nm) strncpy(p, "::/128", p_max_size); else strncpy(p, "::", p_max_size); return; } while(current_v6) { @@ -251,11 +265,20 @@ void print_v6addrs(struct text_object *obj, char *p, int p_max_size) *(current_char+4-j)=':'; current_char+=5-j; } + current_char--; + //netmask + if(ns->v6show_nm) { + char netmaskstr[5]; //max 5 chars (/128 + null-terminator) + sprintf(netmaskstr, "/%u", current_v6->netmask); + strcpy(current_char, netmaskstr); + current_char += strlen(netmaskstr); + } + //next (or last) address current_v6 = current_v6->next; if(current_v6) { - strncpy(current_char-1, ", ", 3); - current_char++; - } else *(current_char-1)=0; + strcpy(current_char, ", "); + current_char+=2; + } else *current_char=0; } } #endif /* BUILD_IPV6 */ diff --git a/src/net_stat.h b/src/net_stat.h index 21e29bdf..bbeed45a 100644 --- a/src/net_stat.h +++ b/src/net_stat.h @@ -36,6 +36,7 @@ #ifdef BUILD_IPV6 struct v6addr { char addr[32]; + unsigned int netmask; struct v6addr *next; }; #endif /* BUILD_IPV6 */ @@ -49,6 +50,7 @@ struct net_stat { struct sockaddr addr; #ifdef BUILD_IPV6 struct v6addr *v6addrs; + bool v6show_nm; #endif /* BUILD_IPV6 */ #if defined(__linux__) char addrs[273]; From 997dcc87d98accf68c31cc43ace1c92a6c5a139b Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Fri, 11 Feb 2011 00:27:12 +0100 Subject: [PATCH 11/19] fix build without ipv6 support --- src/net_stat.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/net_stat.cc b/src/net_stat.cc index 7f46a9e7..c3aa101b 100644 --- a/src/net_stat.cc +++ b/src/net_stat.cc @@ -106,7 +106,9 @@ void parse_net_stat_arg(struct text_object *obj, const char *arg, void *free_at_ if(*dev==0) strcpy(dev, DEFAULTNETDEV); struct net_stat *netstat = get_net_stat(dev, obj, free_at_crash); +#ifdef BUILD_IPV6 netstat->v6show_nm = shownetmask; +#endif /* BUILD_IPV6 */ obj->data.opaque = netstat; } From 2754fab78dc7829c2cb44225e80abdc035290cc8 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Fri, 11 Feb 2011 13:05:00 +0100 Subject: [PATCH 12/19] Support for scope in $v6addrs --- src/conky.cc | 3 +++ src/linux.cc | 23 +++++++++++++++++++++-- src/net_stat.cc | 12 +++++++++++- src/net_stat.h | 2 ++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/conky.cc b/src/conky.cc index ce9ee7df..1e2f0e4a 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -251,6 +251,9 @@ static void print_version(void) #ifdef BUILD_HTTP << _(" * HTTP\n") #endif +#ifdef BUILD_IPV6 + << _(" * IPv6\n") +#endif /* BUILD_IPV6 */ #ifdef BUILD_IRC << _(" * IRC\n") #endif diff --git a/src/linux.cc b/src/linux.cc index 5b5a5404..8db40a69 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -575,11 +575,11 @@ int update_net_stats(void) FILE *file; char v6addr[32]; char devname[21]; - unsigned int netmask; + unsigned int netmask, scope; struct net_stat *ns; struct v6addr *lastv6; if ((file = fopen(PROCDIR"/net/if_inet6", "r")) != NULL) { - while (fscanf(file, "%32s %*02x %02x %*02x %*02x %20s\n", v6addr, &netmask, devname) != EOF) { + while (fscanf(file, "%32s %*02x %02x %02x %*02x %20s\n", v6addr, &netmask, &scope, devname) != EOF) { ns = get_net_stat(devname, NULL, NULL); if(ns->v6addrs == NULL) { lastv6 = (struct v6addr *) malloc(sizeof(struct v6addr)); @@ -592,6 +592,25 @@ int update_net_stats(void) } strncpy(lastv6->addr, v6addr, 32); lastv6->netmask = netmask; + switch(scope) { + case 0: //global + lastv6->scope = 'G'; + break; + case 16: //host-local + lastv6->scope = 'H'; + break; + case 32: //link-local + lastv6->scope = 'L'; + break; + case 64: //site-local + lastv6->scope = 'S'; + break; + case 128: //compat + lastv6->scope = 'C'; + break; + default: + lastv6->scope = '?'; + } lastv6->next = NULL; } } diff --git a/src/net_stat.cc b/src/net_stat.cc index c3aa101b..4d8a44b5 100644 --- a/src/net_stat.cc +++ b/src/net_stat.cc @@ -91,6 +91,7 @@ struct net_stat *get_net_stat(const char *dev, void *free_at_crash1, void *free_ void parse_net_stat_arg(struct text_object *obj, const char *arg, void *free_at_crash) { bool shownetmask = false; + bool showscope = false; char dev[21]; //a netdev can only be 20 chars long int i=0; @@ -100,6 +101,7 @@ void parse_net_stat_arg(struct text_object *obj, const char *arg, void *free_at_ if (*arg == '-') { //there are flags for(i=1; arg[i] != ' ' && arg[i] != 0; i++) { if(arg[i]=='n') shownetmask = true; + if(arg[i]=='s') showscope = true; } } sscanf(arg+i, "%20s", dev); @@ -108,6 +110,7 @@ void parse_net_stat_arg(struct text_object *obj, const char *arg, void *free_at_ struct net_stat *netstat = get_net_stat(dev, obj, free_at_crash); #ifdef BUILD_IPV6 netstat->v6show_nm = shownetmask; + netstat->v6show_sc = showscope; #endif /* BUILD_IPV6 */ obj->data.opaque = netstat; } @@ -233,7 +236,9 @@ void print_v6addrs(struct text_object *obj, char *p, int p_max_size) return; if( ! ns->v6addrs) { - if(ns->v6show_nm) strncpy(p, "::/128", p_max_size); else strncpy(p, "::", p_max_size); + strncpy(p, "::", p_max_size); + if(ns->v6show_nm) strcat(p, "/128"); + if(ns->v6show_sc) strcat(p, "(/)"); return; } while(current_v6) { @@ -275,6 +280,11 @@ void print_v6addrs(struct text_object *obj, char *p, int p_max_size) strcpy(current_char, netmaskstr); current_char += strlen(netmaskstr); } + //scope + if(ns->v6show_sc) { + sprintf(current_char, "(%c)", current_v6->scope); + current_char += 3; + } //next (or last) address current_v6 = current_v6->next; if(current_v6) { diff --git a/src/net_stat.h b/src/net_stat.h index bbeed45a..3838deef 100644 --- a/src/net_stat.h +++ b/src/net_stat.h @@ -37,6 +37,7 @@ struct v6addr { char addr[32]; unsigned int netmask; + char scope; struct v6addr *next; }; #endif /* BUILD_IPV6 */ @@ -51,6 +52,7 @@ struct net_stat { #ifdef BUILD_IPV6 struct v6addr *v6addrs; bool v6show_nm; + bool v6show_sc; #endif /* BUILD_IPV6 */ #if defined(__linux__) char addrs[273]; From 18ce365d167cb0fdf5299a75630dab3752ac5021 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Fri, 11 Feb 2011 15:43:01 +0100 Subject: [PATCH 13/19] change reading args of $v6addrs and add docs --- doc/variables.xml | 13 +++++++++++++ src/net_stat.cc | 22 ++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/doc/variables.xml b/doc/variables.xml index a5f2b561..037b7793 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -3929,6 +3929,19 @@ Display time in UTC (universal coordinate time). + + + + + + + + IPv6 addresses for an interface, followed by + netmask if -n is specified and scope with -s. Scopes are + Global(G), Host-local(H), Link-local(L), Site-local(S), Compat(C) + and Unspecified(/). Linux only. + + diff --git a/src/net_stat.cc b/src/net_stat.cc index 4d8a44b5..18eaca3c 100644 --- a/src/net_stat.cc +++ b/src/net_stat.cc @@ -92,22 +92,28 @@ void parse_net_stat_arg(struct text_object *obj, const char *arg, void *free_at_ { bool shownetmask = false; bool showscope = false; - char dev[21]; //a netdev can only be 20 chars long + char nextarg[21]; //longest arg possible is a devname (max 20 chars) int i=0; + struct net_stat *netstat = NULL; if (!arg) arg = DEFAULTNETDEV; - if (*arg == '-') { //there are flags - for(i=1; arg[i] != ' ' && arg[i] != 0; i++) { - if(arg[i]=='n') shownetmask = true; - if(arg[i]=='s') showscope = true; + while(sscanf(arg+i, " %20s", nextarg) == 1) { + if(strcmp(nextarg, "-n") == 0 || strcmp(nextarg, "--netmask") == 0) shownetmask = true; + else if(strcmp(nextarg, "-s") == 0 || strcmp(nextarg, "--scope") == 0) showscope = true; + else if(nextarg[0]=='-') { //multiple flags in 1 arg + for(int j=1; nextarg[j] != 0; j++) { + if(nextarg[j]=='n') shownetmask = true; + if(nextarg[j]=='s') showscope = true; + } } + else netstat = get_net_stat(nextarg, obj, free_at_crash); + i+=strlen(nextarg); //skip this arg + while( ! (isspace(arg[i]) || arg[i] == 0)) i++; //and skip the spaces in front of it } - sscanf(arg+i, "%20s", dev); - if(*dev==0) strcpy(dev, DEFAULTNETDEV); + if(netstat == NULL) netstat = get_net_stat(DEFAULTNETDEV, obj, free_at_crash); - struct net_stat *netstat = get_net_stat(dev, obj, free_at_crash); #ifdef BUILD_IPV6 netstat->v6show_nm = shownetmask; netstat->v6show_sc = showscope; From 70b6f35a846f7b85bd11e66c1f23feee6b369688 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Fri, 11 Feb 2011 18:30:04 +0100 Subject: [PATCH 14/19] fix racecondition in eve, based on a patch from Vasiliy Kulikov, based on a patch from Brandon --- src/eve.cc | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/eve.cc b/src/eve.cc index 29b8c45c..40853d6a 100644 --- a/src/eve.cc +++ b/src/eve.cc @@ -254,19 +254,6 @@ static char *formatTime(struct tm *ends) } } -static int file_exists(const char *filename) -{ - struct stat fi; - - if ((stat(filename, &fi)) == 0) { - if (fi.st_size > 0) - return 1; - else - return 0; - } else - return 0; -} - static void writeSkilltree(char *content, const char *filename) { FILE *fp = fopen(filename, "w"); @@ -283,14 +270,12 @@ static char *getSkillname(const char *file, int skillid) xmlDocPtr doc = 0; xmlNodePtr root = 0; - if (!file_exists(file)) { - skilltree = getXmlFromAPI(NULL, NULL, NULL, EVEURL_SKILLTREE); -//2x file_exits() so that someone (malicious?) couldn't create it during during the previous call - if (!file_exists(file)) writeSkilltree(skilltree, file); - free(skilltree); - } + skilltree = getXmlFromAPI(NULL, NULL, NULL, EVEURL_SKILLTREE); + writeSkilltree(skilltree, file); + free(skilltree); doc = xmlReadFile(file, NULL, 0); + unlink(file); if (!doc) return NULL; @@ -341,7 +326,7 @@ static char *getSkillname(const char *file, int skillid) static char *eve(char *userid, char *apikey, char *charid) { Character *chr = NULL; - const char *skillfile = "/tmp/.cesf"; + char skillfile[] = "/tmp/.cesfXXXXXX"; int i = 0; char *output = 0; char *timel = 0; @@ -349,6 +334,7 @@ static char *eve(char *userid, char *apikey, char *charid) char *content = 0; time_t now = 0; char *error = 0; + int tmp_fd, old_umask; for (i = 0; i < MAXCHARS; i++) { @@ -401,6 +387,14 @@ static char *eve(char *userid, char *apikey, char *charid) output = (char *)malloc(200 * sizeof(char)); timel = formatTime(&chr->ends); + old_umask = umask(0066); + tmp_fd = mkstemp(skillfile); + umask(old_umask); + if (tmp_fd == -1) { + error = strdup("Cannot create temporary file"); + return error; + } + close(tmp_fd); skill = getSkillname(skillfile, chr->skill); chr->skillname = strdup(skill); From 723255f142848c2b309bbb0c93242eb6e1a9ae6c Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Sat, 12 Feb 2011 17:18:33 +0100 Subject: [PATCH 15/19] Use inet_ntop(), thanks to pavelo for telling me about this --- src/linux.cc | 18 +++++++++++++++++- src/net_stat.cc | 35 ++++------------------------------- src/net_stat.h | 2 +- 3 files changed, 22 insertions(+), 33 deletions(-) diff --git a/src/linux.cc b/src/linux.cc index 8db40a69..fc343518 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -347,6 +347,21 @@ void print_gateway_ip(struct text_object *obj, char *p, int p_max_size) snprintf(p, p_max_size, "%s", gw_info.ip); } +u_int8_t hextobyte(const char in[2]) { + u_int8_t out=0; + char currentchar; + + for(int i=0; i<2; i++) { + currentchar=in[i]; + if(currentchar <= '9') currentchar -= '0'; + else if(currentchar <= 'A') currentchar -= 'A' - 10; + else currentchar -= 'a' - 10; + out<<=4; + out+=currentchar; + } + return out; +} + int update_net_stats(void) { FILE *net_dev_fp; @@ -590,7 +605,8 @@ int update_net_stats(void) lastv6->next = (struct v6addr *) malloc(sizeof(struct v6addr)); lastv6 = lastv6->next; } - strncpy(lastv6->addr, v6addr, 32); + for(int i=0; i<16; i++) + lastv6->addr.s6_addr[i]=hextobyte(v6addr+2*i); lastv6->netmask = netmask; switch(scope) { case 0: //global diff --git a/src/net_stat.cc b/src/net_stat.cc index 18eaca3c..11ecd07c 100644 --- a/src/net_stat.cc +++ b/src/net_stat.cc @@ -236,6 +236,7 @@ void print_v6addrs(struct text_object *obj, char *p, int p_max_size) { struct net_stat *ns = (struct net_stat *)obj->data.opaque; char *current_char = p; + char tempaddress[INET6_ADDRSTRLEN]; struct v6addr *current_v6 = ns->v6addrs; if (!ns) @@ -248,37 +249,9 @@ void print_v6addrs(struct text_object *obj, char *p, int p_max_size) return; } while(current_v6) { - char extracompress = 0; //0 until the first '0000', 1 after the first '0000', 2 after the first non-'0000' after a '0000' - for(int i=0; i<8; i++) { //loop trough the 8 parts of the ipv6 - //skip the zeros in front of each part - int j=0; - while(j<4) if(*(current_v6->addr+(i*4)+j) == '0') j++; else break; - if(j==4) { - if(*(current_v6->addr+(i*4)+3) == '0') { //4 zeros - switch(extracompress) { - case 0: //first time this happens, so replace by '::' - *current_char = ':'; - current_char++; - if(current_char == p+1) { //to make sure there is no ':::' when the first '0000' isn't at the beginning - *current_char = ':'; - current_char++; - } - extracompress=1; - continue; - case 1: //again, ignore them, they are included in the '::' - continue; - default: //again, but only remove the first 3 zero's because extra-compression may no longer be applied - j=3; //but if there are 4 zero's, keep the last - } - } else j=0; //no zeros to skip - } - if(extracompress == 1) extracompress = 2; - //place each part followed by : in the ip - strncpy(current_char, current_v6->addr+(i*4)+j, 4-j); - *(current_char+4-j)=':'; - current_char+=5-j; - } - current_char--; + inet_ntop(AF_INET6, &(current_v6->addr), tempaddress, INET6_ADDRSTRLEN); + strcpy(current_char, tempaddress); + current_char+=strlen(current_char); //netmask if(ns->v6show_nm) { char netmaskstr[5]; //max 5 chars (/128 + null-terminator) diff --git a/src/net_stat.h b/src/net_stat.h index 3838deef..5446785f 100644 --- a/src/net_stat.h +++ b/src/net_stat.h @@ -35,7 +35,7 @@ #ifdef BUILD_IPV6 struct v6addr { - char addr[32]; + struct in6_addr addr; unsigned int netmask; char scope; struct v6addr *next; From 678d79e6febe9aa16268018147bb3042bdb809c7 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Sat, 12 Feb 2011 18:01:41 +0100 Subject: [PATCH 16/19] use sscanf() instead of hextobyte() --- src/linux.cc | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/linux.cc b/src/linux.cc index fc343518..55d1bb03 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -347,21 +347,6 @@ void print_gateway_ip(struct text_object *obj, char *p, int p_max_size) snprintf(p, p_max_size, "%s", gw_info.ip); } -u_int8_t hextobyte(const char in[2]) { - u_int8_t out=0; - char currentchar; - - for(int i=0; i<2; i++) { - currentchar=in[i]; - if(currentchar <= '9') currentchar -= '0'; - else if(currentchar <= 'A') currentchar -= 'A' - 10; - else currentchar -= 'a' - 10; - out<<=4; - out+=currentchar; - } - return out; -} - int update_net_stats(void) { FILE *net_dev_fp; @@ -606,7 +591,7 @@ int update_net_stats(void) lastv6 = lastv6->next; } for(int i=0; i<16; i++) - lastv6->addr.s6_addr[i]=hextobyte(v6addr+2*i); + sscanf(v6addr+2*i, "%2x", (unsigned int*) &(lastv6->addr.s6_addr[i])); lastv6->netmask = netmask; switch(scope) { case 0: //global From 5aaac61f4e07cbf0b4016bd97431afc34a9aa0b4 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Sat, 12 Feb 2011 19:11:01 +0100 Subject: [PATCH 17/19] make cast unnecessary --- src/linux.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linux.cc b/src/linux.cc index 55d1bb03..880405fe 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -591,7 +591,7 @@ int update_net_stats(void) lastv6 = lastv6->next; } for(int i=0; i<16; i++) - sscanf(v6addr+2*i, "%2x", (unsigned int*) &(lastv6->addr.s6_addr[i])); + sscanf(v6addr+2*i, "%2hhx", &(lastv6->addr.s6_addr[i])); lastv6->netmask = netmask; switch(scope) { case 0: //global From cb544bd1f7e5f43aa3ec084670caa9fc2837dd8d Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Sun, 13 Feb 2011 00:10:20 +0100 Subject: [PATCH 18/19] Check that there is no writing outside the string --- src/net_stat.cc | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/net_stat.cc b/src/net_stat.cc index 11ecd07c..42b7e1fd 100644 --- a/src/net_stat.cc +++ b/src/net_stat.cc @@ -235,41 +235,38 @@ void print_addrs(struct text_object *obj, char *p, int p_max_size) void print_v6addrs(struct text_object *obj, char *p, int p_max_size) { struct net_stat *ns = (struct net_stat *)obj->data.opaque; - char *current_char = p; char tempaddress[INET6_ADDRSTRLEN]; struct v6addr *current_v6 = ns->v6addrs; if (!ns) return; + if(p_max_size == 0) return; if( ! ns->v6addrs) { strncpy(p, "::", p_max_size); - if(ns->v6show_nm) strcat(p, "/128"); - if(ns->v6show_sc) strcat(p, "(/)"); + if(ns->v6show_nm) strncat(p, "/128", p_max_size); + if(ns->v6show_sc) strncat(p, "(/)", p_max_size); return; } + *p=0; while(current_v6) { inet_ntop(AF_INET6, &(current_v6->addr), tempaddress, INET6_ADDRSTRLEN); - strcpy(current_char, tempaddress); - current_char+=strlen(current_char); + strncat(p, tempaddress, p_max_size); //netmask if(ns->v6show_nm) { char netmaskstr[5]; //max 5 chars (/128 + null-terminator) sprintf(netmaskstr, "/%u", current_v6->netmask); - strcpy(current_char, netmaskstr); - current_char += strlen(netmaskstr); + strncat(p, netmaskstr, p_max_size); } //scope if(ns->v6show_sc) { - sprintf(current_char, "(%c)", current_v6->scope); - current_char += 3; + char scopestr[3]; + sprintf(scopestr, "(%c)", current_v6->scope); + strncat(p, scopestr, p_max_size); } //next (or last) address current_v6 = current_v6->next; - if(current_v6) { - strcpy(current_char, ", "); - current_char+=2; - } else *current_char=0; + if(current_v6) strncat(p, ", ", p_max_size); } } #endif /* BUILD_IPV6 */ From 70da1c8b370767e0d618571d9a9d803f3113e376 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Fri, 4 Mar 2011 19:29:52 +0100 Subject: [PATCH 19/19] Allow xmms2_smart to display only the title (sf.net #3140371) In the current implementation of xmms2_smart, when a song being played does not have an artist name (as is the case with many streams) conky displays an empty space a dash followed by the title (ex: " - Song Title"). The following patch improves this by only displaying the song title in xmms2_smart when the song artist is empty. Moreover, the patch also fixes an issue that existed with the previous xmms2_smart which seemed to be checking the string length of the song title twice before outputing the url of the song. This seems like a typo and what this line likely meant to do was check that both the song artist and song title were empty before displaying the song url. Patch contributed by Tamim Khan. Signed-off-by: Pavel Labath --- src/xmms2.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/xmms2.cc b/src/xmms2.cc index d3159412..f6078d50 100644 --- a/src/xmms2.cc +++ b/src/xmms2.cc @@ -371,9 +371,12 @@ double xmms2_barval(struct text_object *obj) void print_xmms2_smart(struct text_object *obj, char *p, int p_max_size) { (void)obj; - if (strlen(info.xmms2.title) < 2 - && strlen(info.xmms2.title) < 2) { + int artist_len = strlen(info.xmms2.artist); + int title_len = strlen(info.xmms2.title); + if (artist_len < 2 && title_len < 2) { snprintf(p, p_max_size, "%s", info.xmms2.url); + } else if (artist_len < 1) { + snprintf(p, p_max_size, "%s", info.xmms2.title); } else { snprintf(p, p_max_size, "%s - %s", info.xmms2.artist, info.xmms2.title);