diff --git a/cmake/ConkyBuildOptions.cmake b/cmake/ConkyBuildOptions.cmake index 6f2c0ff8..35d51384 100644 --- a/cmake/ConkyBuildOptions.cmake +++ b/cmake/ConkyBuildOptions.cmake @@ -48,6 +48,8 @@ mark_as_advanced(RELEASE) option(MAINTAINER_MODE "Enable maintainer mode (builds docs)" false) +set(LOCALE_DIR "${CMAKE_INSTALL_PREFIX}/share/locale" CACHE STRING "Directory containing the locales") + # Some standard options set(SYSTEM_CONFIG_FILE "/etc/conky/conky2.conf" CACHE STRING "Default system-wide Conky configuration file") # use FORCE below to make sure this changes when CMAKE_INSTALL_PREFIX is modified @@ -117,11 +119,6 @@ if(BUILD_LUA) endif(BUILD_LUA) option(BUILD_AUDACIOUS "Build audacious (music player) support" false) -if(BUILD_AUDACIOUS) - option(BUILD_AUDACIOUS_LEGACY "Use legacy audacious (music player) support" false) -else(BUILD_AUDACIOUS) - set(BUILD_AUDACIOUS_LEGACY false) -endif(BUILD_AUDACIOUS) option(BUILD_BMPX "Build BMPx (music player) support" false) diff --git a/cmake/ConkyPlatformChecks.cmake b/cmake/ConkyPlatformChecks.cmake index 39c49ef9..539d4a23 100644 --- a/cmake/ConkyPlatformChecks.cmake +++ b/cmake/ConkyPlatformChecks.cmake @@ -161,45 +161,48 @@ endif(BUILD_ICONV) if(BUILD_X11) include(FindX11) find_package(X11) - set(conky_includes ${conky_includes} ${X11_INCLUDE_DIR}) - set(conky_libs ${conky_libs} ${X11_LIBRARIES}) + if(X11_FOUND) + set(conky_includes ${conky_includes} ${X11_INCLUDE_DIR}) + set(conky_libs ${conky_libs} ${X11_LIBRARIES}) - # check for Xdamage - if(BUILD_XDAMAGE) - if(NOT X11_Xdamage_FOUND) - message(FATAL_ERROR "Unable to find Xdamage library") - endif(NOT X11_Xdamage_FOUND) - if(NOT X11_Xfixes_FOUND) - message(FATAL_ERROR "Unable to find Xfixes library") - endif(NOT X11_Xfixes_FOUND) - set(conky_libs ${conky_libs} ${X11_Xdamage_LIB} ${X11_Xfixes_LIB}) - endif(BUILD_XDAMAGE) + # check for Xdamage + if(BUILD_XDAMAGE) + if(NOT X11_Xdamage_FOUND) + message(FATAL_ERROR "Unable to find Xdamage library") + endif(NOT X11_Xdamage_FOUND) + if(NOT X11_Xfixes_FOUND) + message(FATAL_ERROR "Unable to find Xfixes library") + endif(NOT X11_Xfixes_FOUND) + set(conky_libs ${conky_libs} ${X11_Xdamage_LIB} ${X11_Xfixes_LIB}) + endif(BUILD_XDAMAGE) - # check for Xft - if(BUILD_XFT) - find_path(freetype_INCLUDE_PATH freetype/config/ftconfig.h ${INCLUDE_SEARCH_PATH} - /usr/include/freetype2 - /usr/local/include/freetype2) - if(freetype_INCLUDE_PATH) - set(freetype_FOUND true) - set(conky_includes ${conky_includes} ${freetype_INCLUDE_PATH}) - else(freetype_INCLUDE_PATH) - message(FATAL_ERROR "Unable to find freetype library") - endif(freetype_INCLUDE_PATH) - if(NOT X11_Xft_FOUND) - message(FATAL_ERROR "Unable to find Xft library") - endif(NOT X11_Xft_FOUND) - set(conky_libs ${conky_libs} ${X11_Xft_LIB}) - endif(BUILD_XFT) - - # check for Xdbe - if(BUILD_XDBE) - if(NOT X11_Xext_FOUND) - message(FATAL_ERROR "Unable to find Xext library (needed for Xdbe)") - endif(NOT X11_Xext_FOUND) - set(conky_libs ${conky_libs} ${X11_Xext_LIB}) - endif(BUILD_XDBE) + # check for Xft + if(BUILD_XFT) + find_path(freetype_INCLUDE_PATH freetype/config/ftconfig.h ${INCLUDE_SEARCH_PATH} + /usr/include/freetype2 + /usr/local/include/freetype2) + if(freetype_INCLUDE_PATH) + set(freetype_FOUND true) + set(conky_includes ${conky_includes} ${freetype_INCLUDE_PATH}) + else(freetype_INCLUDE_PATH) + message(FATAL_ERROR "Unable to find freetype library") + endif(freetype_INCLUDE_PATH) + if(NOT X11_Xft_FOUND) + message(FATAL_ERROR "Unable to find Xft library") + endif(NOT X11_Xft_FOUND) + set(conky_libs ${conky_libs} ${X11_Xft_LIB}) + endif(BUILD_XFT) + # check for Xdbe + if(BUILD_XDBE) + if(NOT X11_Xext_FOUND) + message(FATAL_ERROR "Unable to find Xext library (needed for Xdbe)") + endif(NOT X11_Xext_FOUND) + set(conky_libs ${conky_libs} ${X11_Xext_LIB}) + endif(BUILD_XDBE) + else(X11_FOUND) + message(FATAL_ERROR "Unable to find X11 library") + endif(X11_FOUND) endif(BUILD_X11) if(BUILD_LUA) @@ -226,15 +229,14 @@ endif(BUILD_LUA) if(BUILD_AUDACIOUS) set(WANT_GLIB true) - if(NOT BUILD_AUDACIOUS_LEGACY) - pkg_check_modules(AUDACIOUS REQUIRED audacious>=1.4.0 dbus-glib-1 gobject-2.0) - set(conky_libs ${conky_libs} ${AUDACIOUS_LIBRARIES}) - set(conky_includes ${conky_includes} ${AUDACIOUS_INCLUDE_DIRS}) - else(NOT BUILD_AUDACIOUS_LEGACY) + pkg_check_modules(NEW_AUDACIOUS audacious>=1.4.0) + if(NEW_AUDACIOUS_FOUND) + pkg_check_modules(AUDACIOUS REQUIRED audclient>=1.4.0) + else(NEW_AUDACIOUS_FOUND) pkg_check_modules(AUDACIOUS REQUIRED audacious<1.4.0) - set(conky_libs ${conky_libs} ${AUDACIOUS_LIBRARIES}) - set(conky_includes ${conky_includes} ${AUDACIOUS_INCLUDE_DIRS}) - endif(NOT BUILD_AUDACIOUS_LEGACY) + endif(NEW_AUDACIOUS_FOUND) + set(conky_libs ${conky_libs} ${AUDACIOUS_LIBRARIES}) + set(conky_includes ${conky_includes} ${AUDACIOUS_INCLUDE_DIRS}) endif(BUILD_AUDACIOUS) if(BUILD_BMPX) diff --git a/cmake/config.h.in b/cmake/config.h.in index 0b5bf4b6..51f375d5 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -15,6 +15,7 @@ #define PACKAGE_LIBDIR "@PACKAGE_LIBRARY_DIR@" #define DEFAULTNETDEV "@DEFAULTNETDEV@" #define CONFIG_FILE "@CONFIG_FILE@" +#define LOCALE_DIR "@LOCALE_DIR@" #define MAX_USER_TEXT_DEFAULT @MAX_USER_TEXT_DEFAULT@ #define DEFAULT_TEXT_BUFFER_SIZE @DEFAULT_TEXT_BUFFER_SIZE@ #define MAX_NET_INTERFACES @MAX_NET_INTERFACES@ @@ -48,7 +49,7 @@ #cmakedefine BUILD_AUDACIOUS 1 -#cmakedefine BUILD_AUDACIOUS_LEGACY 1 +#cmakedefine NEW_AUDACIOUS_FOUND 1 #cmakedefine BUILD_MPD 1 diff --git a/doc/config_settings.xml b/doc/config_settings.xml index 3051388b..3f6f987a 100644 --- a/doc/config_settings.xml +++ b/doc/config_settings.xml @@ -799,7 +799,7 @@ - When ARGB visuals are enabled, this use this to modify the alpha value used. Valid range is 0-255, where 0 is 0% opacity, and 255 is 100% opacity. Note that if own_window_transparent is enabled, this value has no effect. + When ARGB visuals are enabled, this use this to modify the alpha value used. Valid range is 0-255, where 0 is 0% opacity, and 255 is 100% opacity. diff --git a/doc/variables.xml b/doc/variables.xml index 54874e20..db5d435b 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -1016,7 +1016,11 @@ use a temperature gradient, which makes the gradient values change depending on the amplitude of a particular graph value (try it and see). If -t or -l is your first argument, - you may need to preceed it by a space (' '). + you may need to preceed it by a space (' '). You may also use + double-quotes around the exec argument should you need to execute a + command with spaces. For example, ${execgraph "date +'%S'"} to execute + `date +'%S'` and graph the result. Without quotes, it would simply + print the result of `date`. @@ -1028,7 +1032,7 @@ Same as exec but with specific interval. Interval can't be less than update_interval in configuration. See - also $texeci + also $texeci diff --git a/src/audacious.cc b/src/audacious.cc index 0fa139d0..b310d503 100644 --- a/src/audacious.cc +++ b/src/audacious.cc @@ -29,11 +29,11 @@ #include #include -#ifndef BUILD_AUDACIOUS_LEGACY +#ifdef NEW_AUDACIOUS_FOUND #include #include #include -#else /* BUILD_AUDACIOUS_LEGACY */ +#else /* NEW_AUDACIOUS_FOUND */ #include #define audacious_remote_is_running(x) \ xmms_remote_is_running(x) @@ -55,7 +55,7 @@ xmms_remote_get_playlist_file(x, y) #define audacious_remote_get_playlist_length(x) \ xmms_remote_get_playlist_length(x) -#endif /* BUILD_AUDACIOUS_LEGACY */ +#endif /* NEW_AUDACIOUS_FOUND */ /* access to this item array is synchronized */ static audacious_t audacious_items; @@ -125,7 +125,7 @@ void audacious_thread_func(thread_handle &handle) gint rate, freq, chans, vol; gchar *psong, *pfilename; -#ifndef BUILD_AUDACIOUS_LEGACY +#ifdef NEW_AUDACIOUS_FOUND DBusGProxy *session = NULL; DBusGConnection *connection = NULL; #else @@ -136,7 +136,7 @@ void audacious_thread_func(thread_handle &handle) psong = NULL; pfilename = NULL; -#ifndef BUILD_AUDACIOUS_LEGACY +#ifdef NEW_AUDACIOUS_FOUND g_type_init(); connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); if (!connection) { @@ -147,7 +147,7 @@ void audacious_thread_func(thread_handle &handle) if (!session) { CRIT_ERR(NULL, NULL, "unable to create dbus proxy"); } -#endif /* BUILD_AUDACIOUS_LEGACY */ +#endif /* NEW_AUDACIOUS_FOUND */ /* Loop until the main thread resets the runnable signal. */ while (1) { @@ -242,7 +242,7 @@ void audacious_thread_func(thread_handle &handle) } if (handle.test(0)) { -#ifndef BUILD_AUDACIOUS_LEGACY +#ifdef NEW_AUDACIOUS_FOUND /* release reference to dbus proxy */ g_object_unref(session); #endif diff --git a/src/ccurl_thread.cc b/src/ccurl_thread.cc index 343aee71..0db1d54c 100644 --- a/src/ccurl_thread.cc +++ b/src/ccurl_thread.cc @@ -48,19 +48,23 @@ typedef struct _ccurl_memory_t { size_t size; } ccurl_memory_t; +typedef struct _ccurl_headers_t { + char *last_modified; + char *etag; +} ccurl_headers_t; + /* finds a location based on uri in the list provided */ -ccurl_location_ptr ccurl_find_location(ccurl_location_list &locations, char *uri) +ccurl_location_ptr ccurl_find_location(ccurl_location_list &locations, const std::string &uri) { for (ccurl_location_list::iterator i = locations.begin(); i != locations.end(); i++) { - if ((*i)->uri && - strcmp((*i)->uri, uri) == EQUAL) { + if ((*i)->uri == std::string(uri)) { return *i; } } ccurl_location_ptr next = ccurl_location_ptr(new ccurl_location_t); - DBGP("new curl location: '%s'", uri); - next->uri = strndup(uri, text_buffer_size.get(*state)); + DBGP("new curl location: '%s'", uri.c_str()); + next->uri = uri; locations.push_back(next); return next; } @@ -70,13 +74,35 @@ void ccurl_free_locations(ccurl_location_list &locations) { for (ccurl_location_list::iterator i = locations.begin(); i != locations.end(); i++) { - free_and_zero((*i)->uri); free_and_zero((*i)->result); (*i)->p_timed_thread.reset(); } locations.clear(); } +/* callback used by curl for parsing the header data */ +size_t ccurl_parse_header_callback(void *ptr, size_t size, size_t nmemb, void *data) +{ + size_t realsize = size * nmemb; + const char *value = (const char*)ptr; + char *end; + ccurl_headers_t *headers = (ccurl_headers_t*)data; + + if (strncmp(value, "Last-Modified: ", 15) == EQUAL) { + headers->last_modified = strndup(value + 15, realsize - 15); + if ((end = strchr(headers->last_modified, '\r')) != NULL) { + *end = '\0'; + } + } else if (strncmp(value,"ETag: ", 6) == EQUAL) { + headers->etag = strndup(value + 6, realsize - 6); + if ((end = strchr(headers->etag, '\r')) != NULL) { + *end = '\0'; + } + } + + return realsize; +} + /* callback used by curl for writing the received data */ size_t ccurl_write_memory_callback(void *ptr, size_t size, size_t nmemb, void *data) { @@ -98,37 +124,90 @@ void ccurl_fetch_data(thread_handle &handle, const ccurl_location_ptr &curloc) { CURL *curl = NULL; CURLcode res; + struct curl_slist *headers = NULL; - // curl temps + /* curl temps */ ccurl_memory_t chunk; + ccurl_headers_t response_headers; chunk.memory = NULL; chunk.size = 0; + memset(&response_headers, 0, sizeof(ccurl_headers_t)); curl = curl_easy_init(); if (curl) { - DBGP("reading curl data from '%s'", curloc->uri); - curl_easy_setopt(curl, CURLOPT_URL, curloc->uri); + DBGP("reading curl data from '%s'", curloc->uri.c_str()); + curl_easy_setopt(curl, CURLOPT_URL, curloc->uri.c_str()); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, ccurl_parse_header_callback); + curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *) &response_headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ccurl_write_memory_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &chunk); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-curl/1.0"); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "conky-curl/1.1"); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1000); + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 60); + + if (!curloc->last_modified.empty()) { + const char *header = "If-Modified-Since: "; + int len = strlen(header) + curloc->last_modified.size() + 1; + char *str = (char*) malloc(len); + snprintf(str, len, "%s%s", header, curloc->last_modified.c_str()); + headers = curl_slist_append(headers, str); + free(str); + } + if (!curloc->etag.empty()) { + const char *header = "If-None-Match: "; + int len = strlen(header) + curloc->etag.size() + 1; + char *str = (char*) malloc(len); + snprintf(str, len, "%s%s", header, curloc->etag.c_str()); + headers = curl_slist_append(headers, str); + free(str); + } + if (headers) { + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + } res = curl_easy_perform(curl); - if (res == CURLE_OK && chunk.size) { + if (res == CURLE_OK) { long http_status_code; - if(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status_code) == CURLE_OK && http_status_code == 200) { - std::lock_guard lock(handle.mutex()); - curloc->process_function(curloc->result, chunk.memory); + if (curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, + &http_status_code) == CURLE_OK) { + switch (http_status_code) { + case 200: + { + std::lock_guard lock(handle.mutex()); + curloc->last_modified.clear(); + curloc->etag.clear(); + if (response_headers.last_modified) { + curloc->last_modified = + std::string(response_headers.last_modified); + } + if (response_headers.etag) { + curloc->etag = std::string(response_headers.etag); + } + curloc->process_function(curloc->result, chunk.memory); + } + break; + case 304: + break; + default: + NORM_ERR("curl: no data from server, got HTTP status %ld", + http_status_code); + break; + } } else { - NORM_ERR("curl: no data from server"); + NORM_ERR("curl: no HTTP status from server"); } free(chunk.memory); } else { - NORM_ERR("curl: no data from server"); + NORM_ERR("curl: could not retrieve data from server"); } + free_and_zero(response_headers.last_modified); + free_and_zero(response_headers.etag); + curl_slist_free_all(headers); curl_easy_cleanup(curl); } } @@ -186,7 +265,7 @@ static void ccurl_parse_data(char *result, const char *data) } /* prints result data to text buffer, used by $curl */ -void ccurl_process_info(char *p, int p_max_size, char *uri, int interval) +void ccurl_process_info(char *p, int p_max_size, const std::string &uri, int interval) { ccurl_location_ptr curloc = ccurl_find_location(ccurl_locations, uri); if (!curloc->p_timed_thread) { diff --git a/src/ccurl_thread.h b/src/ccurl_thread.h index 3d468917..4aff43ab 100644 --- a/src/ccurl_thread.h +++ b/src/ccurl_thread.h @@ -32,9 +32,11 @@ /* curl thread lib exports begin */ struct ccurl_location_t { - ccurl_location_t() : uri(0), result(0) {} + ccurl_location_t() : result(0) {} /* uri of location */ - char *uri; + std::string uri; + std::string last_modified; + std::string etag; /* a pointer to some arbitrary data, will be freed by ccurl_free_info() if * non-null */ char *result; @@ -50,7 +52,7 @@ typedef std::shared_ptr ccurl_location_ptr; typedef std::list ccurl_location_list; /* find an existing location for the uri specified */ -ccurl_location_ptr ccurl_find_location(ccurl_location_list &locations, char *uri); +ccurl_location_ptr ccurl_find_location(ccurl_location_list &locations, const std::string &uri); /* free all locations (as well as location->uri and location->result if * non-null) */ void ccurl_free_locations(ccurl_location_list &locations); @@ -66,7 +68,7 @@ void ccurl_init_thread(const ccurl_location_ptr &curloc, int interval); /* for $curl, free internal list pointer */ void ccurl_free_info(void); /* runs instance of $curl */ -void ccurl_process_info(char *p, int p_max_size, char *uri, int interval); +void ccurl_process_info(char *p, int p_max_size, const std::string &uri, int interval); void curl_parse_arg(struct text_object *, const char *); void curl_print(struct text_object *, char *, int); diff --git a/src/colours.cc b/src/colours.cc index 495c4647..16d0b619 100644 --- a/src/colours.cc +++ b/src/colours.cc @@ -119,7 +119,7 @@ unsigned long *do_gradient(int width, unsigned long first_colour, unsigned long for (i = 0; i < width; i++) { int red3 = 0, green3 = 0, blue3 = 0; // colour components - float factor = ((float)(i + 1) / width); + float factor = ((float) i / (width - 1)); /* the '+ 0.5' bit rounds our floats to ints properly */ if (red1 >= red2) { diff --git a/src/conky.cc b/src/conky.cc index 05fa95ab..2a69653d 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -74,6 +74,8 @@ #ifdef BUILD_CURL #include #endif +#define _(string) gettext(string) +#define _nop(string) string /* local headers */ #include "core.h" @@ -338,7 +340,9 @@ static void print_version(void) ; } -static const char *suffixes[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "" }; +static const char *suffixes[] = { + _nop("B"), _nop("KiB"), _nop("MiB"), _nop("GiB"), _nop("TiB"), _nop("PiB"), "" +}; #ifdef BUILD_X11 @@ -682,7 +686,7 @@ void human_readable(long long num, char *buf, int size) spaced_print(buf, size, "%d", 6, round_to_int(num)); return; } - if (short_units.get(*state)) { + if (short_units.get(*state) || llabs(num) < 1000LL) { width = 5; format = "%.*f%.1s"; } else { @@ -691,7 +695,7 @@ void human_readable(long long num, char *buf, int size) } if (llabs(num) < 1000LL) { - spaced_print(buf, size, format, width, 0, (float)num, *suffix); + spaced_print(buf, size, format, width, 0, (float)num, _(*suffix)); return; } @@ -726,7 +730,7 @@ void human_readable(long long num, char *buf, int size) if (fnum < 9.995) precision = 2; /* print 0-9 with two decimal places */ - spaced_print(buf, size, format, width, precision, fnum, *suffix); + spaced_print(buf, size, format, width, precision, fnum, _(*suffix)); } /* global object list root element */ @@ -1576,12 +1580,12 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) ); } #endif /* DEBUG_lol */ - XSetForeground(display, window.gc, tmpcolour[ + set_foreground_color(tmpcolour[ (int)((float)(w - 2) - current->graph[j] * (w - 2) / (float)current->scale) ]); } else { - XSetForeground(display, window.gc, tmpcolour[colour_idx++]); + set_foreground_color(tmpcolour[colour_idx++]); } } /* this is mugfugly, but it works */ @@ -1613,28 +1617,28 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) if (seconds != 0) { timeunits = seconds / 86400; seconds %= 86400; if (timeunits <= 0 || - asprintf(&tmp_day_str, "%dd", timeunits) == -1) { + asprintf(&tmp_day_str, _("%dd"), timeunits) == -1) { tmp_day_str = strdup(""); } timeunits = seconds / 3600; seconds %= 3600; if (timeunits <= 0 || - asprintf(&tmp_hour_str, "%dh", timeunits) == -1) { + asprintf(&tmp_hour_str, _("%dh"), timeunits) == -1) { tmp_hour_str = strdup(""); } timeunits = seconds / 60; seconds %= 60; if (timeunits <= 0 || - asprintf(&tmp_min_str, "%dm", timeunits) == -1) { + asprintf(&tmp_min_str, _("%dm"), timeunits) == -1) { tmp_min_str = strdup(""); } if (seconds <= 0 || - asprintf(&tmp_sec_str, "%ds", seconds) == -1) { + asprintf(&tmp_sec_str, _("%ds"), seconds) == -1) { tmp_sec_str = strdup(""); } if (asprintf(&tmp_str, "%s%s%s%s", tmp_day_str, tmp_hour_str, tmp_min_str, tmp_sec_str) == -1) tmp_str = strdup(""); free(tmp_day_str); free(tmp_hour_str); free(tmp_min_str); free(tmp_sec_str); } else { - tmp_str = strdup("Range not possible"); // should never happen, but better safe then sorry + tmp_str = strdup(_("Range not possible")); // should never happen, but better safe then sorry } cur_x += (w / 2) - (font_ascent() * (strlen(tmp_str) / 2)); cur_y += font_h / 2; @@ -2116,7 +2120,7 @@ static void main_loop(void) if (changed && own_window_type.get(*state) == TYPE_PANEL) { int sidenum = -1; - fprintf(stderr, PACKAGE_NAME": defining struts\n"); + fprintf(stderr, _(PACKAGE_NAME": defining struts\n")); fflush(stderr); switch (text_alignment.get(*state)) { @@ -2506,6 +2510,11 @@ void clean_up_without_threads(void *memtofree1, void* memtofree2) { free_and_zero(memtofree1); free_and_zero(memtofree2); + +#if defined BUILD_WEATHER_METAR || defined BUILD_WEATHER_XOAP + weather_free_info(); +#endif + timed_thread::destroy_registered_threads(); free_and_zero(info.cpu_usage); @@ -2536,9 +2545,6 @@ void clean_up_without_threads(void *memtofree1, void* memtofree2) #ifdef BUILD_RSS rss_free_info(); #endif -#if defined BUILD_WEATHER_METAR || defined BUILD_WEATHER_XOAP - weather_free_info(); -#endif #ifdef BUILD_LUA llua_shutdown_hook(); #endif /* BUILD_LUA */ @@ -2981,6 +2987,9 @@ void initialisation(int argc, char **argv) { int main(int argc, char **argv) { + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE_NAME, LOCALE_DIR); + textdomain(PACKAGE_NAME); argc_copy = argc; argv_copy = argv; g_signal_pending = 0; @@ -3079,6 +3088,8 @@ int main(int argc, char **argv) main_loop(); + disk_cleanup(); + #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) kvm_close(kd); #endif diff --git a/src/conky.h b/src/conky.h index 98f391eb..de29d871 100644 --- a/src/conky.h +++ b/src/conky.h @@ -31,6 +31,8 @@ #ifndef _conky_h_ #define _conky_h_ +#define __STDC_FORMAT_MACROS + #include /* defines */ #include "common.h" /* at least for struct dns_data */ #include /* struct uname_s */ diff --git a/src/core.cc b/src/core.cc index cb34d54a..69e708fb 100644 --- a/src/core.cc +++ b/src/core.cc @@ -40,7 +40,9 @@ #include "entropy.h" #include "exec.h" #include "i8k.h" +#ifdef BUILD_IMLIB2 #include "imlib2.h" +#endif #include "proc.h" #ifdef BUILD_MYSQL #include "mysql.h" diff --git a/src/diskio.h b/src/diskio.h index 15009214..866b528f 100644 --- a/src/diskio.h +++ b/src/diskio.h @@ -63,6 +63,7 @@ struct diskio_stat { extern struct diskio_stat stats; struct diskio_stat *prepare_diskio_stat(const char *); +void disk_cleanup(void); int update_diskio(void); void clear_diskio_stats(void); void update_diskio_values(struct diskio_stat *, unsigned int, unsigned int); diff --git a/src/linux.cc b/src/linux.cc index 4b04e419..57b74b4c 100644 --- a/src/linux.cc +++ b/src/linux.cc @@ -1445,26 +1445,20 @@ critical (S5): 73 C passive: 73 C: tc1=4 tc2=3 tsp=40 devices=0xcdf6e6c0 */ -#define ACPI_THERMAL_DIR "/proc/acpi/thermal_zone/" -#define ACPI_THERMAL_FORMAT "/proc/acpi/thermal_zone/%s/temperature" +#define ACPI_THERMAL_ZONE_DEFAULT "thermal_zone0" +#define ACPI_THERMAL_FORMAT "/sys/class/thermal/%s/temp" int open_acpi_temperature(const char *name) { char path[256]; - char buf[256]; int fd; if (name == NULL || strcmp(name, "*") == 0) { - static int rep = 0; - - if (!get_first_file_in_a_directory(ACPI_THERMAL_DIR, buf, &rep)) { - return -1; - } - name = buf; + snprintf(path, 255, ACPI_THERMAL_FORMAT, ACPI_THERMAL_ZONE_DEFAULT); + } else { + snprintf(path, 255, ACPI_THERMAL_FORMAT, name); } - snprintf(path, 255, ACPI_THERMAL_FORMAT, name); - fd = open(path, O_RDONLY); if (fd < 0) { NORM_ERR("can't open '%s': %s", path, strerror(errno)); @@ -1476,6 +1470,9 @@ int open_acpi_temperature(const char *name) static double last_acpi_temp; static double last_acpi_temp_time; +//the maximum length of the string inside a ACPI_THERMAL_FORMAT file including the ending 0 +#define MAXTHERMZONELEN 6 + double get_acpi_temperature(int fd) { if (fd <= 0) { @@ -1493,15 +1490,16 @@ double get_acpi_temperature(int fd) /* read */ { - char buf[256]; + char buf[MAXTHERMZONELEN]; int n; - n = read(fd, buf, 255); + n = read(fd, buf, MAXTHERMZONELEN-1); if (n < 0) { NORM_ERR("can't read fd %d: %s", fd, strerror(errno)); } else { buf[n] = '\0'; - sscanf(buf, "temperature: %lf", &last_acpi_temp); + sscanf(buf, "%lf", &last_acpi_temp); + last_acpi_temp /= 1000; } } @@ -2289,12 +2287,25 @@ typedef struct DEV_LIST_TYPE } DEV_LIST, *DEV_LIST_PTR; +DEV_LIST_PTR dev_head = NULL; + +void disk_cleanup() { + DEV_LIST_PTR dev_next, dev_cur = dev_head; + + while(dev_cur) { + dev_next = dev_cur->next; + free(dev_cur->dev_name); + free(dev_cur); + dev_cur = dev_next; + } + dev_head = NULL; +} + /* Same as sf #2942117 but memoized using a linked list */ int is_disk(char *dev) { char syspath[PATH_MAX]; char *slash; - static DEV_LIST_PTR dev_head = NULL; DEV_LIST_PTR dev_cur, dev_last; dev_cur = dev_head; diff --git a/src/llua.cc b/src/llua.cc index cfeabe13..2423fdf8 100644 --- a/src/llua.cc +++ b/src/llua.cc @@ -44,8 +44,6 @@ static int llua_block_notify = 0; static void llua_load(const char *script); -#define MIN(a, b) ( (a) < (b) ? (a) : (b) ) - lua_State *lua_L = NULL; namespace { @@ -263,7 +261,7 @@ static char *llua_do_call(const char *string, int retc) snprintf(func, sizeof func, "%s", LUAPREFIX); } else *func = 0; - strncat(func, ptr, MIN(len, sizeof(func) - strlen(func) - 1)); + strncat(func, ptr, std::min(len, sizeof(func) - strlen(func) - 1)); /* push the function name to stack */ lua_getglobal(lua_L, func); diff --git a/src/logging.h b/src/logging.h index 95f48064..e390f80f 100644 --- a/src/logging.h +++ b/src/logging.h @@ -30,14 +30,26 @@ #ifndef _LOGGING_H #define _LOGGING_H +#include +#include + void clean_up(void *memtofree1, void* memtofree2); void clean_up_without_threads(void *memtofree1, void* memtofree2); -#define NORM_ERR(...) { \ +template +void gettextize_format(const char *format, Args&&... args) +{ fprintf(stderr, gettext(format), args...); } + +// explicit specialization for no arguments to avoid the +// "format not a string literal and no format arguments" warning +inline void gettextize_format(const char *format) +{ fputs(gettext(format), stderr); } + +#define NORM_ERR(...) do { \ fprintf(stderr, PACKAGE_NAME": "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ -} + gettextize_format(__VA_ARGS__); \ + fputs("\n", stderr); \ +} while(0) /* critical error */ #define CRIT_ERR(memtofree1, memtofree2, ...) \ @@ -48,12 +60,13 @@ void clean_up_without_threads(void *memtofree1, void* memtofree2); /* debugging output */ extern int global_debug_level; -#define __DBGP(level, ...) \ +#define __DBGP(level, ...) do {\ if (global_debug_level > level) { \ fprintf(stderr, "DEBUG(%d) [" __FILE__ ":%d]: ", level, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } + gettextize_format(__VA_ARGS__); \ + fputs("\n", stderr); \ + } \ +} while(0) #define DBGP(...) __DBGP(0, __VA_ARGS__) #define DBGP2(...) __DBGP(1, __VA_ARGS__) diff --git a/src/read_tcpip.cc b/src/read_tcpip.cc index 13b1bdc6..4f59c430 100644 --- a/src/read_tcpip.cc +++ b/src/read_tcpip.cc @@ -187,7 +187,9 @@ void print_read_tcpip(struct text_object *obj, char *p, int p_max_size, int prot } if(protocol == IPPROTO_UDP) { //when using udp send a zero-length packet to let the other end know of our existence - (void) write(sock, NULL, 0); + if(write(sock, NULL, 0) < 0) { + NORM_ERR("read_udp: Couldn't create a empty package"); + } } FD_ZERO(&readfds); FD_SET(sock, &readfds); diff --git a/src/rss.cc b/src/rss.cc index 79b73b2c..e8605846 100644 --- a/src/rss.cc +++ b/src/rss.cc @@ -52,7 +52,7 @@ void rss_free_info(void) ccurl_free_locations(locations_rss); } -static void rss_process_info(char *p, int p_max_size, char *uri, char *action, int +static void rss_process_info(char *p, int p_max_size, const std::string &uri, char *action, int act_par, int interval, unsigned int nrspaces) { PRSS *data; diff --git a/src/specials.cc b/src/specials.cc index da0001f3..eff36928 100644 --- a/src/specials.cc +++ b/src/specials.cc @@ -243,6 +243,19 @@ char *scan_graph(struct text_object *obj, const char *args, double defscale) //TODO: check the return value and throw an error? sscanf(args, "%1023s %d,%d", buf, &g->height, &g->width); } + + /* escape quotes at end in case of execgraph */ + if (*buf == '"') { + char *_ptr; + size_t _size; + if ((_ptr = const_cast(strrchr(args, '"')))) { + _size = _ptr - args - 1; + } + _size = _size < 1024 ? _size : 1023; + strncpy(buf, args + 1, _size); + buf[_size] = 0; + } + #undef g return strndup(buf, text_buffer_size.get(*state)); diff --git a/src/timed-thread.cc b/src/timed-thread.cc index e85d405d..76439f13 100644 --- a/src/timed-thread.cc +++ b/src/timed-thread.cc @@ -24,9 +24,7 @@ * */ -#ifdef HAVE_CONFIG_H #include -#endif #include #include @@ -79,7 +77,7 @@ timed_thread::timed_thread(const std::function &start_rou { #ifdef DEBUG - assert(interval_usecs >= MINIMUM_INTERVAL_USECS); + assert(interval_usecs >= std::chrono::microseconds(MINIMUM_INTERVAL_USECS)); #endif /* DEBUG */ /* create thread pipe (used to tell threads to die) */ @@ -104,7 +102,7 @@ timed_thread::timed_thread(const std::function &start_rou } /* destroy a timed thread. */ -void timed_thread::destroy(bool deregister_this) +void timed_thread::destroy() { DBGP("destroying thread %ld", (long)p_timed_thread->thread.get()); #ifdef DEBUG @@ -127,9 +125,6 @@ void timed_thread::destroy(bool deregister_this) close(p_timed_thread->pipefd[1]); running = false; - - if (deregister_this) deregister(this); - } /* lock a timed thread for critical section activity */ diff --git a/src/timed-thread.h b/src/timed-thread.h index c2c3059e..8c4d723b 100644 --- a/src/timed-thread.h +++ b/src/timed-thread.h @@ -102,7 +102,7 @@ class timed_thread { int test(int override_wait_time); /* destroy a timed thread */ - void destroy(bool deregister_this = true); + void destroy(); /* register a timed thread for destruction */ static int register_(const timed_thread_ptr &timed_thread); diff --git a/src/user.cc b/src/user.cc index 2b463714..2651efcc 100644 --- a/src/user.cc +++ b/src/user.cc @@ -28,6 +28,8 @@ * */ +#include + #include "logging.h" #include #include @@ -50,10 +52,10 @@ void print_uid_name(struct text_object *obj, char *p, int p_max_size) { if(pw != NULL) { snprintf(p, p_max_size, "%s", pw->pw_name); } else { - NORM_ERR("The uid %d doesn't exist", uid) + NORM_ERR("The uid %d doesn't exist", uid); } } else { - NORM_ERR("$uid_name didn't receive a uid as argument") + NORM_ERR("$uid_name didn't receive a uid as argument"); } } @@ -72,9 +74,9 @@ void print_gid_name(struct text_object *obj, char *p, int p_max_size) { if(grp != NULL) { snprintf(p, p_max_size, "%s", grp->gr_name); } else { - NORM_ERR("The gid %d doesn't exist", gid) + NORM_ERR("The gid %d doesn't exist", gid); } } else { - NORM_ERR("$gid_name didn't receive a gid as argument") + NORM_ERR("$gid_name didn't receive a gid as argument"); } } diff --git a/src/weather.cc b/src/weather.cc index c56bbc4f..0f55d0dc 100644 --- a/src/weather.cc +++ b/src/weather.cc @@ -709,7 +709,8 @@ void wind_deg_to_dir(char *p, int p_max_size, int wind_deg) { } #ifdef BUILD_WEATHER_XOAP -static void weather_forecast_process_info(char *p, int p_max_size, char *uri, unsigned int day, char *data_type, int interval) +static void weather_forecast_process_info(char *p, int p_max_size, const + std::string &uri, unsigned int day, char *data_type, int interval) { PWEATHER_FORECAST *data; @@ -754,7 +755,7 @@ static void weather_forecast_process_info(char *p, int p_max_size, char *uri, un } #endif /* BUILD_WEATHER_XOAP */ -static void weather_process_info(char *p, int p_max_size, char *uri, char *data_type, int interval) +static void weather_process_info(char *p, int p_max_size, const std::string &uri, char *data_type, int interval) { static const char *wc[] = { "", "drizzle", "rain", "hail", "soft hail", diff --git a/src/x11.h b/src/x11.h index c2f81678..bc137b87 100644 --- a/src/x11.h +++ b/src/x11.h @@ -27,7 +27,6 @@ #ifndef X11_H_ #define X11_H_ -#include #include #include