diff --git a/cmake/ConkyPlatformChecks.cmake b/cmake/ConkyPlatformChecks.cmake index 0abc8180..6d26b971 100644 --- a/cmake/ConkyPlatformChecks.cmake +++ b/cmake/ConkyPlatformChecks.cmake @@ -43,6 +43,7 @@ endif(CMAKE_SYSTEM_NAME MATCHES "Linux") if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") set(OS_FREEBSD true) + set(conky_libs ${conky_libs} -lkvm -ldevstat) endif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") if(CMAKE_SYSTEM_NAME MATCHES "OpenBSD") diff --git a/doc/variables.xml b/doc/variables.xml index ba3daca1..ccc692dc 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -1600,8 +1600,7 @@ digits. stringArgument is enclosed in - quotation mark or the checks for double and long failed - before. + quotation marks (") Valid operands are: '>', '<', '>=', '<=', '==', '!='. @@ -3075,12 +3074,14 @@ - + - Scroll 'text' by 'step' characters showing + Scroll 'text' by 'step' characters to the left + or right (set 'direction' to 'left' or 'right') showing 'length' number of characters at the same time. The text may also contain variables. 'step' is optional and defaults - to 1 if not set. If a var creates output on multiple lines + to 1 if not set. 'direction' is optional and defaults to left + if not set. If a var creates output on multiple lines then the lines are placed behind each other separated with a '|'-sign. If you change the textcolor inside $scroll it will automatically have it's old value back at the end of diff --git a/src/algebra.cc b/src/algebra.cc index 4ab5c790..a4ae3656 100644 --- a/src/algebra.cc +++ b/src/algebra.cc @@ -126,11 +126,9 @@ enum arg_type get_arg_type(const char *arg) const char *p, *e; p = arg; - e = arg + strlen(arg); + e = arg + strlen(arg)-1; - if (*(e - 1) == ' ') - e--; - while (*e && *e == ' ') + while (p != e && *e && *e == ' ') e--; while (p != e && *p == ' ') p++; @@ -140,23 +138,23 @@ enum arg_type get_arg_type(const char *arg) if (*p == '-') //allow negative values p++; - while (p != e) { + while (p <= e) { if (!isdigit(*p)) break; p++; } - if (p == e) + if (p == e+1) return ARG_LONG; if (*p == '.') { p++; - while (p != e) { + while (p <= e) { if (!isdigit(*p)) - return ARG_STRING; + return ARG_BAD; p++; } return ARG_DOUBLE; } - return ARG_STRING; + return ARG_BAD; } char *arg_to_string(const char *arg) @@ -197,6 +195,8 @@ int compare(const char *expr) char *expr_dup; int idx, mtype; enum arg_type type1, type2; + long lng_a, lng_b; + double dbl_a, dbl_b; idx = find_match_op(expr); mtype = get_match_type(expr); @@ -213,6 +213,11 @@ int compare(const char *expr) type1 = get_arg_type(expr_dup); type2 = get_arg_type(expr_dup + idx + 1); + if (type1 == ARG_BAD || type2 == ARG_BAD) { + NORM_ERR("Bad arguments: '%s' and '%s'", expr_dup, (expr_dup + idx + 1)); + free(expr_dup); + return -2; + } if (type1 == ARG_LONG && type2 == ARG_DOUBLE) type1 = ARG_DOUBLE; if (type1 == ARG_DOUBLE && type2 == ARG_LONG) @@ -220,6 +225,7 @@ int compare(const char *expr) if (type1 != type2) { NORM_ERR("trying to compare args '%s' and '%s' of different type", expr_dup, (expr_dup + idx + 1)); + free(expr_dup); return -2; } switch (type1) { @@ -231,16 +237,23 @@ int compare(const char *expr) idx = scompare(a, (enum match_type) mtype, b); free(a); free(b); + free(expr_dup); return idx; } case ARG_LONG: - return lcompare(arg_to_long(expr_dup), (enum match_type) mtype, - arg_to_long(expr_dup + idx + 1)); + lng_a = arg_to_long(expr_dup); + lng_b = arg_to_long(expr_dup + idx + 1); + free(expr_dup); + return lcompare(lng_a, (enum match_type) mtype, lng_b); case ARG_DOUBLE: - return dcompare(arg_to_double(expr_dup), (enum match_type) mtype, - arg_to_double(expr_dup + idx + 1)); + dbl_a = arg_to_double(expr_dup); + dbl_b = arg_to_double(expr_dup + idx + 1); + free(expr_dup); + return dcompare(dbl_a, (enum match_type) mtype, dbl_b); + case ARG_BAD: /* make_gcc_happy() */; } /* not reached */ + free(expr_dup); return -2; } diff --git a/src/algebra.h b/src/algebra.h index e1830cf0..5f4cf248 100644 --- a/src/algebra.h +++ b/src/algebra.h @@ -44,6 +44,7 @@ enum match_type { }; enum arg_type { + ARG_BAD = 0, /* something strange */ ARG_STRING = 1, /* "asdf" */ ARG_LONG = 2, /* 123456 */ ARG_DOUBLE = 3 /* 12.456 */ diff --git a/src/bsdapm.cc b/src/bsdapm.cc index 830ed32d..89fb60fb 100644 --- a/src/bsdapm.cc +++ b/src/bsdapm.cc @@ -33,6 +33,7 @@ #include #include #include +#include #define APMDEV "/dev/apm" #define APM_UNKNOWN 255 diff --git a/src/bsdapm.h b/src/bsdapm.h index ffbf8853..c80127bf 100644 --- a/src/bsdapm.h +++ b/src/bsdapm.h @@ -30,16 +30,8 @@ #ifndef _BSDAPM_H #define _BSDAPM_H -#ifdef __cplusplus -extern "C" { -#endif - void print_apm_adapter(struct text_object *, char *, int); void print_apm_battery_life(struct text_object *, char *, int); void print_apm_battery_time(struct text_object *, char *, int); -#ifdef __cplusplus -} -#endif - #endif /* _BSDAPM_H */ diff --git a/src/conky.cc b/src/conky.cc index 44acc0e7..cba180ea 100644 --- a/src/conky.cc +++ b/src/conky.cc @@ -64,7 +64,7 @@ #include #include #include -#ifdef NCURSES +#ifdef BUILD_NCURSES #include #endif #ifdef BUILD_WEATHER_XOAP @@ -161,6 +161,10 @@ void *global_cpu = NULL; unsigned int max_text_width = 0; int ifup_strictness = IFUP_UP; +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +extern kvm_t *kd; +#endif + int argc_copy; char** argv_copy; @@ -554,6 +558,13 @@ int percent_print(char *buf, int size, unsigned value) return spaced_print(buf, size, "%u", pad_percents, value); } +#if defined(__FreeBSD__) +unsigned long long llabs(long long num) { + if(num < 0) return -num; + else return num; +} +#endif + /* converts from bytes to human readable format (K, M, G, T) * * The algorithm always divides by 1024, as unit-conversion of byte @@ -1114,11 +1125,11 @@ static inline void set_foreground_color(long c) XSetForeground(display, window.gc, current_color); } #endif /* BUILD_X11 */ -#ifdef NCURSES +#ifdef BUILD_NCURSES if (output_methods & TO_NCURSES) { attron(COLOR_PAIR(c)); } -#endif /* NCURSES */ +#endif /* BUILD_NCURSES */ UNUSED(c); return; } @@ -1156,7 +1167,7 @@ static void draw_string(const char *s) if ((output_methods & APPEND_FILE) && draw_mode == FG && append_fpointer) { fprintf(append_fpointer, "%s\n", s_with_newlines); } -#ifdef NCURSES +#ifdef BUILD_NCURSES if ((output_methods & TO_NCURSES) && draw_mode == FG) { printw("%s", s_with_newlines); } @@ -1687,11 +1698,11 @@ int draw_each_line_inner(char *s, int special_index, int last_special_applied) cur_y += cur_y_add; #endif /* BUILD_X11 */ draw_string(s); -#ifdef NCURSES +#ifdef BUILD_NCURSES if (output_methods & TO_NCURSES) { printw("\n"); } -#endif /* NCURSES */ +#endif /* BUILD_NCURSES */ #ifdef BUILD_X11 if (output_methods & TO_X) cur_y += font_descent(); @@ -1710,11 +1721,11 @@ static int draw_line(char *s, int special_index) return draw_each_line_inner(s, special_index, -1); } #endif /* BUILD_X11 */ -#ifdef NCURSES +#ifdef BUILD_NCURSES if (output_methods & TO_NCURSES) { return draw_each_line_inner(s, special_index, -1); } -#endif /* NCURSES */ +#endif /* BUILD_NCURSES */ draw_string(s); UNUSED(special_index); return 0; @@ -1752,10 +1763,10 @@ static void draw_text(void) } setup_fonts(); #endif /* BUILD_X11 */ -#ifdef NCURSES +#ifdef BUILD_NCURSES init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK); attron(COLOR_PAIR(COLOR_WHITE)); -#endif /* NCURSES */ +#endif /* BUILD_NCURSES */ for_each_line(text_buffer, draw_line); #if defined(BUILD_LUA) && defined(BUILD_X11) llua_draw_post_hook(); @@ -2221,7 +2232,7 @@ static void main_loop(void) if(t > 0) usleep((useconds_t)t); update_text(); draw_stuff(); -#ifdef NCURSES +#ifdef BUILD_NCURSES if(output_methods & TO_NCURSES) { refresh(); clear(); @@ -2369,7 +2380,7 @@ void clean_up(void *memtofree1, void* memtofree2) free_update_callbacks(); -#ifdef NCURSES +#ifdef BUILD_NCURSES if(output_methods & TO_NCURSES) { endwin(); } @@ -2904,6 +2915,7 @@ static int do_config_step(int *line, FILE *fp, char *buf, char **name, char **va return 0; } +#ifdef BUILD_X11 void setalignment(int* text_alignment, unsigned int windowtype, const char* value, const char *f, int line, bool conffile) { #ifdef OWN_WINDOW if (windowtype == TYPE_DOCK) { @@ -2924,6 +2936,7 @@ void setalignment(int* text_alignment, unsigned int windowtype, const char* valu CONF_ERR; } } +#endif /* BUILD_X11 */ char load_config_file(const char *f) { @@ -3199,7 +3212,7 @@ char load_config_file(const char *f) if(string_to_bool(value)) output_methods |= TO_STDERR; } -#ifdef NCURSES +#ifdef BUILD_NCURSES CONF("out_to_ncurses") { if(string_to_bool(value)) { initscr(); @@ -3702,7 +3715,7 @@ char load_config_file(const char *f) if (!output_methods) { CRIT_ERR(0, 0, "no output_methods have been selected; exiting"); } -#if defined(NCURSES) +#if defined(BUILD_NCURSES) #if defined(BUILD_X11) if ((output_methods & TO_X) && (output_methods & TO_NCURSES)) { NORM_ERR("out_to_x and out_to_ncurses are incompatible, turning out_to_ncurses off"); @@ -3714,7 +3727,7 @@ char load_config_file(const char *f) NORM_ERR("out_to_ncurses conflicts with out_to_console and out_to_stderr, disabling the later ones"); output_methods &= ~(TO_STDOUT | TO_STDERR); } -#endif /* NCURSES */ +#endif /* BUILD_NCURSES */ return TRUE; } diff --git a/src/core.cc b/src/core.cc index f854edd0..4277ad64 100644 --- a/src/core.cc +++ b/src/core.cc @@ -136,7 +136,7 @@ static struct text_object *create_plain_text(const char *s) } /* construct_text_object() creates a new text_object */ -struct text_object *construct_text_object(const char *s, const char *arg, long +struct text_object *construct_text_object(char *s, const char *arg, long line, void **ifblock_opaque, void *free_at_crash) { // struct text_object *obj = new_text_object(); @@ -1563,9 +1563,8 @@ struct text_object *construct_text_object(const char *s, const char *arg, long END OBJ(scroll, 0) #ifdef BUILD_X11 /* allocate a follower to reset any color changes */ - obj->next = new_text_object_internal(); #endif /* BUILD_X11 */ - parse_scroll_arg(obj, arg, free_at_crash); + parse_scroll_arg(obj, arg, free_at_crash, s); obj->callbacks.print = &print_scroll; obj->callbacks.free = &free_scroll; END OBJ_ARG(combine, 0, "combine needs arguments: ") diff --git a/src/freebsd.cc b/src/freebsd.cc index 9cef5856..e53ec7b4 100644 --- a/src/freebsd.cc +++ b/src/freebsd.cc @@ -67,6 +67,8 @@ #define FREEBSD_DEBUG #endif +kvm_t *kd; + __attribute__((gnu_inline)) inline void proc_find_top(struct process **cpu, struct process **mem); @@ -302,7 +304,7 @@ void get_cpu_count(void) info.cpu_count = 0; } - info.cpu_usage = malloc((info.cpu_count + 1) * sizeof(float)); + info.cpu_usage = (float *) malloc((info.cpu_count + 1) * sizeof(float)); if (info.cpu_usage == NULL) { CRIT_ERR(NULL, NULL, "malloc"); } @@ -331,14 +333,14 @@ void update_cpu_usage(void) if (!global_cpu) { malloc_cpu_size = (info.cpu_count + 1) * sizeof(struct cpu_info); - cpu = malloc(malloc_cpu_size); + cpu = (cpu_info *) malloc(malloc_cpu_size); memset(cpu, 0, malloc_cpu_size); global_cpu = cpu; } /* cpu[0] is overall stats, get it from separate sysctl */ cp_len = CPUSTATES * sizeof(long); - cp_time = malloc(cp_len); + cp_time = (long int *) malloc(cp_len); if (sysctlbyname("kern.cp_time", cp_time, &cp_len, NULL, 0) < 0) { fprintf(stderr, "Cannot get kern.cp_time\n"); @@ -364,7 +366,7 @@ void update_cpu_usage(void) /* per-core stats */ cp_len = CPUSTATES * sizeof(long) * info.cpu_count; - cp_time = malloc(cp_len); + cp_time = (long int *) malloc(cp_len); /* on e.g. i386 SMP we may have more values than actual cpus; this will just drop extra values */ if (sysctlbyname("kern.cp_times", cp_time, &cp_len, NULL, 0) < 0 && errno != ENOMEM) { @@ -734,7 +736,7 @@ proc_find_top(struct process **cpu, struct process **mem) } p = kvm_getprocs(kd, KERN_PROC_PROC, 0, &n_processes); - processes = malloc(n_processes * sizeof(struct process)); + processes = (process *) malloc(n_processes * sizeof(struct process)); for (i = 0; i < n_processes; i++) { if (!((p[i].ki_flag & P_SYSTEM)) && p[i].ki_comm != NULL) { @@ -751,7 +753,7 @@ proc_find_top(struct process **cpu, struct process **mem) for (i = 0; i < 10 && i < n_processes; i++) { struct process *tmp, *ttmp; - tmp = malloc(sizeof(struct process)); + tmp = (process *) malloc(sizeof(struct process)); tmp->pid = processes[i].pid; tmp->amount = processes[i].amount; tmp->name = strndup(processes[i].name, text_buffer_size); @@ -770,7 +772,7 @@ proc_find_top(struct process **cpu, struct process **mem) for (i = 0; i < 10 && i < n_processes; i++) { struct process *tmp, *ttmp; - tmp = malloc(sizeof(struct process)); + tmp = (process *) malloc(sizeof(struct process)); tmp->pid = processes[i].pid; tmp->amount = processes[i].amount; tmp->name = strndup(processes[i].name, text_buffer_size); diff --git a/src/freebsd.h b/src/freebsd.h index c7ce372c..833e9e35 100644 --- a/src/freebsd.h +++ b/src/freebsd.h @@ -17,8 +17,6 @@ extern "C" { #endif -kvm_t *kd; - int get_entropy_avail(unsigned int *); int get_entropy_poolsize(unsigned int *); diff --git a/src/fs.cc b/src/fs.cc index 2503c164..1ace9c36 100644 --- a/src/fs.cc +++ b/src/fs.cc @@ -51,6 +51,10 @@ #ifdef HAVE_SYS_MOUNT_H #include #endif +#if defined(__FreeBSD__) +#include "freebsd.h" +#endif + #if !defined(HAVE_STRUCT_STATFS_F_FSTYPENAME) && !defined (__OpenBSD__) && !defined(__FreeBSD__) #include diff --git a/src/libmpdclient.cc b/src/libmpdclient.cc index df7a16a3..92156a13 100644 --- a/src/libmpdclient.cc +++ b/src/libmpdclient.cc @@ -52,6 +52,7 @@ # include # include # include +# include # include #endif @@ -119,6 +120,38 @@ static int do_connect_fail(mpd_Connection *connection, } #endif /* !WIN32 */ +static int uds_connect(mpd_Connection *connection, const char *host, + float timeout) +{ + struct sockaddr_un addr; + + strncpy(addr.sun_path, host, sizeof(addr.sun_path)-1); + addr.sun_family = AF_UNIX; + addr.sun_path[sizeof(addr.sun_path)-1] = 0; + connection->sock = socket(AF_UNIX, SOCK_STREAM, 0); + + if (connection->sock < 0) { + snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, + "problems creating socket: %s", strerror(errno)); + connection->error = MPD_ERROR_SYSTEM; + return -1; + } + + mpd_setConnectionTimeout(connection, timeout); + + /* connect stuff */ + if (do_connect_fail(connection, (struct sockaddr *)&addr, SUN_LEN(&addr))) { + snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, + "problems cconnecting socket: %s", strerror(errno)); + closesocket(connection->sock); + connection->sock = -1; + connection->error = MPD_ERROR_SYSTEM; + return -1; + } + + return 0; +} + #ifdef MPD_HAVE_GAI static int mpd_connect(mpd_Connection *connection, const char *host, int port, float timeout) @@ -129,6 +162,9 @@ static int mpd_connect(mpd_Connection *connection, const char *host, int port, struct addrinfo *res = NULL; struct addrinfo *addrinfo = NULL; + if (*host == '/') + return uds_connect(connection, host, timeout); + /* Setup hints */ hints.ai_flags = AI_ADDRCONFIG; hints.ai_family = AF_UNSPEC; @@ -200,6 +236,9 @@ static int mpd_connect(mpd_Connection *connection, const char *host, int port, int destlen; struct sockaddr_in sin; + if (*host == '/') + return uds_connect(connection, host, timeout); + #ifdef HAVE_GETHOSTBYNAME_R if (gethostbyname_r(rhost, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info snprintf(connection->errorStr, MPD_ERRORSTR_MAX_LENGTH, diff --git a/src/scroll.cc b/src/scroll.cc index 43a0203e..2255a7b3 100644 --- a/src/scroll.cc +++ b/src/scroll.cc @@ -34,29 +34,49 @@ #include "text_object.h" #include +#define SCROLL_LEFT true +#define SCROLL_RIGHT false + struct scroll_data { char *text; unsigned int show; unsigned int step; - unsigned int start; + signed int start; long resetcolor; + bool direction; }; -void parse_scroll_arg(struct text_object *obj, const char *arg, void *free_at_crash) +void parse_scroll_arg(struct text_object *obj, const char *arg, void *free_at_crash, char *free_at_crash2) { struct scroll_data *sd; int n1 = 0, n2 = 0; + char dirarg[6]; sd = (struct scroll_data *)malloc(sizeof(struct scroll_data)); memset(sd, 0, sizeof(struct scroll_data)); sd->resetcolor = get_current_text_color(); sd->step = 1; - if (!arg || sscanf(arg, "%u %n", &sd->show, &n1) <= 0) - CRIT_ERR(obj, free_at_crash, "scroll needs arguments: [] "); + sd->direction = SCROLL_LEFT; - sscanf(arg + n1, "%u %n", &sd->step, &n2); - if (*(arg + n1 + n2)) { + if (arg && sscanf(arg, "%5s %n", dirarg, &n1) == 1) { + if (strcasecmp(dirarg, "right") == 0 || strcasecmp(dirarg, "r") == 0) + sd->direction = SCROLL_RIGHT; + else if ( strcasecmp(dirarg, "left") != 0 && strcasecmp(dirarg, "l") != 0) + n1 = 0; + } + + if (!arg || sscanf(arg + n1, "%u %n", &sd->show, &n2) <= 0) { + free(sd); +#ifdef BUILD_X11 + free(obj->next); +#endif + free(free_at_crash2); + CRIT_ERR(obj, free_at_crash, "scroll needs arguments: [left|right] [] "); + } + n1 += n2; + + if(sscanf(arg + n1, "%u %n", &sd->step, &n2) == 1) { n1 += n2; } else { sd->step = 1; @@ -81,8 +101,6 @@ void parse_scroll_arg(struct text_object *obj, const char *arg, void *free_at_cr #ifdef BUILD_X11 /* add a color object right after scroll to reset any color changes */ - obj->next->data.l = sd->resetcolor; - obj->next->callbacks.print = &new_fg; #endif /* BUILD_X11 */ } @@ -131,7 +149,7 @@ void print_scroll(struct text_object *obj, char *p, int p_max_size) } p[j] = 0; //count colorchanges in front of the visible part and place that many colorchanges in front of the visible part - for(j = 0; j < sd->start; j++) { + for(j = 0; j < (unsigned) sd->start; j++) { if(buf[j] == SPECIAL_CHAR) frontcolorchanges++; } pwithcolors=(char*)malloc(strlen(p) + 1 + colorchanges - visibcolorchanges); @@ -149,10 +167,22 @@ void print_scroll(struct text_object *obj, char *p, int p_max_size) strcpy(p, pwithcolors); free(pwithcolors); //scroll - sd->start += sd->step; - if(buf[sd->start] == 0 || sd->start > strlen(&(buf[0]))){ - sd->start = 0; + if(sd->direction == SCROLL_LEFT) { + sd->start += sd->step; + if(buf[sd->start] == 0 || (unsigned) sd->start > strlen(&(buf[0]))) { + sd->start = 0; + } + } else { + if(sd->start < 1) { + sd->start = strlen(&(buf[0])); + } + sd->start -= sd->step; } +#ifdef BUILD_X11 + //reset color when scroll is finished + if (output_methods & TO_X) + new_special(p + strlen(p), FG)->arg = sd->resetcolor; +#endif } void free_scroll(struct text_object *obj) diff --git a/src/scroll.h b/src/scroll.h index b11331b5..8d2d6777 100644 --- a/src/scroll.h +++ b/src/scroll.h @@ -30,7 +30,7 @@ #ifndef _SCROLL_H #define _SCROLL_H -void parse_scroll_arg(struct text_object *, const char *, void *); +void parse_scroll_arg(struct text_object *, const char *, void *, char *); void print_scroll(struct text_object *, char *, int); void free_scroll(struct text_object *); diff --git a/src/specials.cc b/src/specials.cc index 833f9836..60cc141f 100644 --- a/src/specials.cc +++ b/src/specials.cc @@ -251,7 +251,7 @@ char *scan_graph(struct text_object *obj, const char *args, double defscale) * Printing various special text objects */ -static struct special_t *new_special(char *buf, enum special_types t) +struct special_t *new_special(char *buf, enum special_types t) { if (special_count >= max_specials) { CRIT_ERR(NULL, NULL, "too many special things in text"); @@ -472,10 +472,10 @@ void new_fg(struct text_object *obj, char *p, int p_max_size) if (output_methods & TO_X) new_special(p, FG)->arg = obj->data.l; #endif /* BUILD_X11 */ -#ifdef NCURSES +#ifdef BUILD_NCURSES if (output_methods & TO_NCURSES) new_special(p, FG)->arg = obj->data.l; -#endif /* NCURSES */ +#endif /* BUILD_NCURSES */ UNUSED(obj); UNUSED(p); UNUSED(p_max_size); diff --git a/src/specials.h b/src/specials.h index 743d157a..a3d9783f 100644 --- a/src/specials.h +++ b/src/specials.h @@ -121,4 +121,6 @@ void new_alignc(struct text_object *, char *, int); void new_goto(struct text_object *, char *, int); void new_tab(struct text_object *, char *, int); +struct special_t *new_special(char *buf, enum special_types t); + #endif /* _SPECIALS_H */