RSS was not really disabled when it was supposed to be. Experimental wireless support.
[monky] / src / conky.c
index b9cef5b..34a24b2 100644 (file)
@@ -93,14 +93,18 @@ static void print_version()
 #ifdef TCP_PORT_MONITOR
        "  * portmon\n"
 #endif /* TCP_PORT_MONITOR */
-#ifdef HAVE_LIBDEXTER
-  "  * network\n"
-#endif
+#ifdef RSS
+       "  * rss\n"
+#endif /* RSS */
        "\n");  
 
        exit(0);
 }
 
+#if defined(__linux__)
+int post_21_kernel;
+#endif /* __linux__ */
+
 #ifdef X11
 
 /*
@@ -316,16 +320,25 @@ static int maximum_width;
 
 #endif /* X11 */
 
+#ifdef __OpenBSD__
+static int sensor_device;
+#endif
+
+static long color0, color1, color2, color3, color4, color5, color6, color7, color8, color9;
+
 /* maximum number of special things, e.g. fonts, offsets, aligns, etc. */
 static unsigned int max_specials = MAX_SPECIALS_DEFAULT;
 
 /* maximum size of config TEXT buffer, i.e. below TEXT line. */
 static unsigned int max_user_text = MAX_USER_TEXT_DEFAULT;
 
+/* maximum size of individual text buffers, ie $exec buffer size */
+unsigned int text_buffer_size = TEXT_BUFFER_SIZE;
+
 #ifdef HAVE_ICONV
 #define CODEPAGE_LENGTH 20
 long iconv_selected;
-long iconv_count;
+long iconv_count = 0;
 char iconv_converting;
 static iconv_t **iconv_cd = 0;
 
@@ -352,8 +365,9 @@ void free_iconv(void)
 {
        if (iconv_cd) {
                long i;
-               for (i = iconv_count; i < 0; i++) {
+               for (i = 0; i < iconv_count; i++) {
                        if (iconv_cd[i]) {
+                               iconv_close(*iconv_cd[i]);
                                free(iconv_cd[i]);
                        }
                }
@@ -378,11 +392,6 @@ static int pad_percents = 0;
 tcp_port_monitor_args_t        tcp_port_monitor_args;
 #endif
 
-#ifdef HAVE_LIBDEXTER
-/* private config items for libdexter */
-static char *dexter_config = NULL;
-#endif
-
 /* Text that is shown */
 static char original_text[] =
     "$nodename - $sysname $kernel on $machine\n"
@@ -425,36 +434,24 @@ static int blockdepth = 0;
 static int if_jumped = 0;
 static int blockstart[MAX_IF_BLOCK_DEPTH];
 
-int check_mount(char *s)
+int check_contains(char *f, char *s)
 {
-#if defined(__linux__)
        int ret = 0;
-       FILE *mtab = fopen("/etc/mtab", "r");
-       if (mtab) {
-               char buf1[256], buf2[128];
-               while (fgets(buf1, 256, mtab)) {
-                       sscanf(buf1, "%*s %128s", buf2);
-                       if (!strcmp(s, buf2)) {
+       FILE *where = fopen(f, "r");
+       if (where) {
+               char buf1[256], buf2[256];
+               while (fgets(buf1, 256, where)) {
+                       sscanf(buf1, "%255s", buf2);
+                       if (strstr(buf2, s)) {
                                ret = 1;
                                break;
                        }
                }
-               fclose(mtab);
+               fclose(where);
        } else {
-               ERR("Could not open mtab");
+               ERR("Could not open the file");
        }
        return ret;
-#elif defined(__FreeBSD__)
-       struct statfs *mntbuf;
-       int i, mntsize;
-
-       mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
-       for (i = mntsize - 1; i >= 0; i--)
-               if (strcmp(mntbuf[i].f_mntonname, s) == 0)
-                       return 1;
-
-       return 0;
-#endif
 }
 
 
@@ -570,6 +567,18 @@ long fwd_fcharfind(FILE* fp, char val, unsigned int step) {
 #undef BUFSZ
 }
 
+#ifndef HAVE_MEMRCHR
+void *
+memrchr (const void *buffer, int c, size_t n)
+{
+       const unsigned char *p = buffer;
+
+       for (p += n; n ; n--)
+               if (*--p == c)
+                       return (void *)p;
+       return NULL;
+}
+#endif
 long rev_fcharfind(FILE* fp, char val, unsigned int step) {
 #define BUFSZ 0x1000
        long ret = -1;
@@ -639,9 +648,9 @@ static const char *scan_bar(const char *args, int *w, int *h)
 
 static char *scan_font(const char *args)
 {
-       if (args && sizeof(args) < 127) {
+  if (args && *args)
                return strdup(args);
-       }
+  
        return NULL;
 }
 
@@ -916,9 +925,21 @@ enum text_object_type {
        OBJ_acpitempf,
        OBJ_battery,
        OBJ_battery_time,
+       OBJ_battery_percent,
+       OBJ_battery_bar,
        OBJ_buffers,
        OBJ_cached,
        OBJ_color,
+       OBJ_color0,
+       OBJ_color1,
+       OBJ_color2,
+       OBJ_color3,
+       OBJ_color4,
+       OBJ_color5,
+       OBJ_color6,
+       OBJ_color7,
+       OBJ_color8,
+       OBJ_color9,
        OBJ_font,
        OBJ_cpu,
        OBJ_cpubar,
@@ -980,7 +1001,15 @@ enum text_object_type {
         OBJ_pb_battery,
        OBJ_voltage_mv,
        OBJ_voltage_v,
+       OBJ_wireless_essid,
+       OBJ_wireless_mode,
+       OBJ_wireless_bitrate,
+       OBJ_wireless_link_qual,
+       OBJ_wireless_link_qual_max,
+       OBJ_wireless_link_bar,
+       OBJ_wireless_ap,
 #endif /* __linux__ */
+       OBJ_if_empty,
        OBJ_if_existing,
        OBJ_if_mounted,
        OBJ_if_running,
@@ -992,6 +1021,7 @@ enum text_object_type {
        OBJ_loadavg,
        OBJ_machine,
        OBJ_mails,
+       OBJ_mboxscan,
        OBJ_mem,
        OBJ_membar,
        OBJ_memgraph,
@@ -1036,11 +1066,18 @@ enum text_object_type {
        OBJ_pop3,
        OBJ_pop3_unseen,
        OBJ_pop3_used,
-#if defined(__FreeBSD__) && (defined(i386) || defined(__i386__))
+#if (defined(__FreeBSD__) || defined(__OpenBSD__)) && (defined(i386) || defined(__i386__))
        OBJ_apm_adapter,
        OBJ_apm_battery_time,
        OBJ_apm_battery_life,
-#endif /* __FreeBSD__ */
+#endif /* __FreeBSD__ __OpenBSD__ */
+#ifdef __OpenBSD__
+       OBJ_obsd_sensors_temp,
+       OBJ_obsd_sensors_fan,
+       OBJ_obsd_sensors_volt,
+       OBJ_obsd_vendor,
+       OBJ_obsd_product,
+#endif /* __OpenBSD__ */
 #ifdef MPD
        OBJ_mpd_title,
        OBJ_mpd_artist,
@@ -1106,6 +1143,9 @@ enum text_object_type {
        OBJ_bmpx_uri,
        OBJ_bmpx_bitrate,
 #endif
+#ifdef RSS
+       OBJ_rss,
+#endif
 #ifdef TCP_PORT_MONITOR
        OBJ_tcp_portmon,
 #endif
@@ -1140,6 +1180,11 @@ struct text_object {
                struct mail_s *mail;
 
                struct {
+                       char *args;
+                       char *output;
+               } mboxscan;
+
+               struct {
                        char *tz;    /* timezone variable */
                        char *fmt;   /* time display formatting */
                } tztime;
@@ -1160,10 +1205,13 @@ struct text_object {
                        char devtype[256];
                        char type[64];
                } i2c;          /* 2 */
+
                struct {
                        int pos;
                        char *s;
+                       char *str;
                } ifblock;
+
                struct {
                        int num;
                        int type;
@@ -1212,6 +1260,14 @@ struct text_object {
                        char *dev;
                } hddtemp; /* 2 */
 #endif
+#ifdef RSS
+               struct {
+                       char *uri;
+                       char *action;
+                       int act_par;
+                       int delay;
+               } rss;
+#endif
        } data;
 };
 
@@ -1694,7 +1750,7 @@ void *threaded_exec(struct text_object *obj) {
                char *p2 = obj->data.texeci.buffer;
                FILE *fp = popen(obj->data.texeci.cmd,"r");
                timed_thread_lock (obj->data.texeci.p_timed_thread);
-               int n2 = fread(p2, 1, TEXT_BUFFER_SIZE, fp);
+               int n2 = fread(p2, 1, text_buffer_size, fp);
                (void) pclose(fp);
                p2[n2] = '\0';
                if (n2 && p2[n2 - 1] == '\n') {
@@ -1744,6 +1800,10 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                                free(objs[i].data.tztime.tz);
                                free(objs[i].data.tztime.fmt);
                                break;
+                       case OBJ_mboxscan:
+                               free(objs[i].data.mboxscan.args);
+                               free(objs[i].data.mboxscan.output);
+                               break;
                        case OBJ_imap:
                                free(info.mail);
                                break;
@@ -1770,16 +1830,19 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                                        free(objs[i].data.mail);
                                }
                                break;
+                       case OBJ_if_empty:
                        case OBJ_if_existing:
                        case OBJ_if_mounted:
                        case OBJ_if_running:
                                free(objs[i].data.ifblock.s);
+                               free(objs[i].data.ifblock.str);
                                break;
                        case OBJ_tail:
                                free(objs[i].data.tail.logfile);
                                free(objs[i].data.tail.buffer);
                                break;
-                       case OBJ_text: case OBJ_font:
+                       case OBJ_text:
+                       case OBJ_font:
                                free(objs[i].data.s);
                                break;
                        case OBJ_image:
@@ -1960,6 +2023,12 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                        case OBJ_bmpx_uri:
                        case OBJ_bmpx_bitrate:
 #endif
+#ifdef RSS
+                       case OBJ_rss:
+                               free(objs[i].data.rss.uri);
+                               free(objs[i].data.rss.action);
+                               break;
+#endif
                        case OBJ_pre_exec:
                        case OBJ_battery:
                                free(objs[i].data.s);
@@ -2103,6 +2172,46 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
            obj->data.cpu_index=atoi(&arg[0]);
        }
        obj->a = 1;
+
+#ifdef HAVE_IWLIB
+       END OBJ(wireless_essid, INFO_NET)
+       if(arg)
+               obj->data.net = get_net_stat(arg);
+       else
+               CRIT_ERR("wireless_essid: needs an argument");
+       END OBJ(wireless_mode, INFO_NET)
+       if(arg)
+               obj->data.net = get_net_stat(arg);
+       else
+               CRIT_ERR("wireless_mode: needs an argument");
+       END OBJ(wireless_ap, INFO_NET)
+       if(arg)
+               obj->data.net = get_net_stat(arg);
+       else
+               CRIT_ERR("wireless_ap: needs an argument");
+       END OBJ(wireless_bitrate, INFO_NET)
+       if(arg)
+               obj->data.net = get_net_stat(arg);
+       else
+               CRIT_ERR("wireless_bitrate: needs an argument");
+       END OBJ(wireless_link_qual, INFO_NET)
+       if(arg)
+               obj->data.net = get_net_stat(arg);
+       else
+               CRIT_ERR("wireless_link_qual: needs an argument");
+       END OBJ(wireless_link_qual_max, INFO_NET)
+       if(arg)
+               obj->data.net = get_net_stat(arg);
+       else
+               CRIT_ERR("wireless_link_qual_max: needs an argument");
+       END OBJ(wireless_link_bar, INFO_NET)
+       if(arg) {
+               arg = scan_bar(arg, &obj->a, &obj->b);
+               obj->data.net = get_net_stat(arg);
+       } else
+               CRIT_ERR("wireless_link_bar: needs an argument");
+#endif /* HAVE_IWLIB */
+
 #endif /* __linux__ */
        END OBJ(freq_dyn, 0);
        END OBJ(freq_dyn_g, 0);
@@ -2121,6 +2230,22 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
        else
                strcpy(bat, "BAT0");
        obj->data.s = strdup(bat);
+       END OBJ(battery_percent, 0);
+       char bat[64];
+       if (arg)
+               sscanf(arg, "%63s", bat);
+       else
+               strcpy(bat, "BAT0");
+       obj->data.s = strdup(bat);
+       END OBJ(battery_bar, 0);
+       char bat[64];
+       if (arg) {
+               arg = scan_bar(arg, &obj->a, &obj->b);
+               sscanf(arg, "%63s", bat);
+       } else {
+               strcpy(bat, "BAT0");
+       }
+       obj->data.s = strdup(bat);
 #if defined(__linux__)
        END OBJ(i8k_version, INFO_I8K)
                END OBJ(i8k_bios, INFO_I8K)
@@ -2162,6 +2287,37 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                 }
 
 #endif /* __linux__ */
+#if defined(__OpenBSD__)
+       END OBJ(obsd_sensors_temp, 0);
+               if(!arg) {
+                       CRIT_ERR("obsd_sensors_temp: needs an argument");
+               }
+               if(!isdigit(arg[0]) || atoi(&arg[0]) < 0 || atoi(&arg[0]) > OBSD_MAX_SENSORS-1) {
+                       obj->data.sensor=0;
+                       ERR("Invalid temperature sensor number!");
+               }
+                       obj->data.sensor = atoi(&arg[0]);
+       END OBJ(obsd_sensors_fan, 0);
+               if(!arg) {
+                       CRIT_ERR("obsd_sensors_fan: needs 2 arguments (device and sensor number)");
+               }
+               if(!isdigit(arg[0]) || atoi(&arg[0]) < 0 || atoi(&arg[0]) > OBSD_MAX_SENSORS-1) {
+                       obj->data.sensor=0;
+                       ERR("Invalid fan sensor number!");
+               }
+                       obj->data.sensor = atoi(&arg[0]);
+       END OBJ(obsd_sensors_volt, 0);
+               if(!arg) {
+                       CRIT_ERR("obsd_sensors_volt: needs 2 arguments (device and sensor number)");
+               }
+               if(!isdigit(arg[0]) || atoi(&arg[0]) < 0 || atoi(&arg[0]) > OBSD_MAX_SENSORS-1) {
+                       obj->data.sensor=0;
+                       ERR("Invalid voltage sensor number!");
+               }
+                       obj->data.sensor = atoi(&arg[0]);
+       END OBJ(obsd_vendor, 0);
+       END OBJ(obsd_product, 0);
+#endif /* __OpenBSD__ */
                END OBJ(buffers, INFO_BUFFERS)
                END OBJ(cached, INFO_BUFFERS)
                END OBJ(cpu, INFO_CPU)
@@ -2206,11 +2362,29 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
 #ifdef X11
                obj->data.l = arg ? get_x11_color(arg) : default_fg_color;
 #endif /* X11 */
-       END
-               OBJ(font, 0)
+       END OBJ(color0, 0)
+               obj->data.l = color0;
+       END OBJ(color1, 0)
+               obj->data.l = color1;
+       END OBJ(color2, 0)
+               obj->data.l = color2;
+       END OBJ(color3, 0)
+               obj->data.l = color3;
+       END OBJ(color4, 0)
+               obj->data.l = color4;
+       END OBJ(color5, 0)
+               obj->data.l = color5;
+       END OBJ(color6, 0)
+               obj->data.l = color6;
+       END OBJ(color7, 0)
+               obj->data.l = color7;
+       END OBJ(color8, 0)
+               obj->data.l = color8;
+       END OBJ(color9, 0)
+               obj->data.l = color9;
+       END OBJ(font, 0)
                obj->data.s = scan_font(arg);
-       END
-               OBJ(downspeed, INFO_NET) 
+       END OBJ(downspeed, INFO_NET) 
                if(arg) {
                        obj->data.net = get_net_stat(arg);
                }
@@ -2287,7 +2461,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
        } else {
                obj->data.execi.cmd = strdup(arg + n);
                obj->data.execi.buffer =
-                       (char *) calloc(1, TEXT_BUFFER_SIZE);
+                       (char *) calloc(1, text_buffer_size);
        }
        END OBJ(texeci, 0) unsigned int n;
        if (!arg || sscanf(arg, "%f %n", &obj->data.texeci.interval, &n) <= 0) {
@@ -2299,7 +2473,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
        } else {
                obj->data.texeci.cmd = strdup(arg + n);
                obj->data.texeci.buffer =
-                       (char *) calloc(1, TEXT_BUFFER_SIZE);
+                       (char *) calloc(1, text_buffer_size);
        }
        obj->data.texeci.p_timed_thread = NULL;
        END OBJ(pre_exec, 0) obj->type = OBJ_text;
@@ -2477,6 +2651,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                else {
                        CRIT_ERR("addr needs argument");
                }
+#if 0
        END OBJ(linkstatus, INFO_WIFI) 
                if(arg) {
                        obj->data.net = get_net_stat(arg);
@@ -2484,6 +2659,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                else {
                        CRIT_ERR("linkstatus needs argument");
                }
+#endif
        END OBJ(tail, 0)
                char buf[64];
        int n1, n2;
@@ -2502,7 +2678,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                        fp = fopen(buf, "r");
                        if (fp) {
                                obj->data.tail.logfile =
-                                       malloc(TEXT_BUFFER_SIZE);
+                                       malloc(text_buffer_size);
                                strcpy(obj->data.tail.logfile, buf);
                                obj->data.tail.wantedlines = n1;
                                obj->data.tail.interval =
@@ -2527,7 +2703,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                        fp = fopen(buf, "r");
                        if (fp != NULL) {
                                obj->data.tail.logfile =
-                                       malloc(TEXT_BUFFER_SIZE);
+                                       malloc(text_buffer_size);
                                strcpy(obj->data.tail.logfile, buf);
                                obj->data.tail.wantedlines = n1;
                                obj->data.tail.interval = n2;
@@ -2543,7 +2719,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                ERR("invalid args given for tail");
                return NULL;
        }
-       obj->data.tail.buffer = malloc(TEXT_BUFFER_SIZE * 20); /* asumming all else worked */
+       obj->data.tail.buffer = malloc(text_buffer_size * 20); /* asumming all else worked */
        END OBJ(head, 0)
                char buf[64];
        int n1, n2;
@@ -2562,7 +2738,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                        fp = fopen(buf, "r");
                        if (fp != NULL) {
                                obj->data.tail.logfile =
-                                       malloc(TEXT_BUFFER_SIZE);
+                                       malloc(text_buffer_size);
                                strcpy(obj->data.tail.logfile, buf);
                                obj->data.tail.wantedlines = n1;
                                obj->data.tail.interval =
@@ -2587,7 +2763,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                        fp = fopen(buf, "r");
                        if (fp != NULL) {
                                obj->data.tail.logfile =
-                                       malloc(TEXT_BUFFER_SIZE);
+                                       malloc(text_buffer_size);
                                strcpy(obj->data.tail.logfile, buf);
                                obj->data.tail.wantedlines = n1;
                                obj->data.tail.interval = n2;
@@ -2603,7 +2779,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                ERR("invalid args given for head");
                return NULL;
        }
-       obj->data.tail.buffer = malloc(TEXT_BUFFER_SIZE * 20); /* asumming all else worked */
+       obj->data.tail.buffer = malloc(text_buffer_size * 20); /* asumming all else worked */
        END OBJ(loadavg, INFO_LOADAVG) int a = 1, b = 2, c = 3, r = 3;
        if (arg) {
                r = sscanf(arg, "%d %d %d", &a, &b, &c);
@@ -2617,18 +2793,40 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
        obj->data.loadavg[0] = (r >= 1) ? (unsigned char) a : 0;
        obj->data.loadavg[1] = (r >= 2) ? (unsigned char) b : 0;
        obj->data.loadavg[2] = (r >= 3) ? (unsigned char) c : 0;
-       END OBJ(if_existing, 0)
+       END OBJ(if_empty, 0)
                if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
                        CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
                }
        if (!arg) {
-               ERR("if_existing needs an argument");
+               ERR("if_empty needs an argument");
                obj->data.ifblock.s = 0;
        } else
                obj->data.ifblock.s = strdup(arg);
        blockstart[blockdepth] = object_count;
        obj->data.ifblock.pos = object_count + 2;
        blockdepth++;
+       END OBJ(if_existing, 0)
+               if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
+                       CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
+               }
+       if (!arg) {
+               ERR("if_existing needs an argument or two");
+               obj->data.ifblock.s = NULL;
+               obj->data.ifblock.str = NULL;       
+       } else {
+               char buf1[256], buf2[256];
+               int r = sscanf(arg, "%255s %255[^\n]", buf1, buf2);
+               if (r == 1) {
+                       obj->data.ifblock.s = strdup(buf1);             
+                       obj->data.ifblock.str = NULL;       
+               } else {
+                       obj->data.ifblock.s = strdup(buf1);
+                       obj->data.ifblock.str = strdup(buf2);
+               }
+       }               
+       blockstart[blockdepth] = object_count;
+       obj->data.ifblock.pos = object_count + 2;
+       blockdepth++;
        END OBJ(if_mounted, 0)
                if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
                        CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
@@ -2659,6 +2857,12 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
        END OBJ(kernel, 0)
                END OBJ(machine, 0)
                END OBJ(mails, INFO_MAIL)
+               END OBJ(mboxscan, 0)
+               obj->data.mboxscan.args = (char*)malloc(TEXT_BUFFER_SIZE);
+               obj->data.mboxscan.output = (char*)malloc(text_buffer_size);
+               /* if '1' (in mboxscan.c) then there was SIGUSR1, hmm */
+               obj->data.mboxscan.output[0] = 1;
+               strncpy(obj->data.mboxscan.args, arg, TEXT_BUFFER_SIZE);
                END OBJ(mem, INFO_MEM)
                END OBJ(memmax, INFO_MEM)
                END OBJ(memperc, INFO_MEM)
@@ -2805,7 +3009,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
        }
        END OBJ(uptime_short, INFO_UPTIME) END OBJ(uptime, INFO_UPTIME) END
                OBJ(adt746xcpu, 0) END OBJ(adt746xfan, 0) END
-#if defined(__FreeBSD__) && (defined(i386) || defined(__i386__))
+#if (defined(__FreeBSD__) || defined(__OpenBSD__)) && (defined(i386) || defined(__i386__))
                OBJ(apm_adapter, 0) END
                OBJ(apm_battery_life, 0) END
                OBJ(apm_battery_time, 0) END
@@ -2847,8 +3051,18 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                }
                END
 #ifdef MPD
-               OBJ(mpd_artist, INFO_MPD)
-               END OBJ(mpd_title, INFO_MPD)
+               OBJ(mpd_artist, INFO_MPD) END
+               OBJ(mpd_title, INFO_MPD)
+               {
+                       if (arg)
+                       {
+                           sscanf (arg, "%d", &info.mpd.max_title_len);
+                           if (info.mpd.max_title_len > 0)
+                               info.mpd.max_title_len++;
+                           else
+                               CRIT_ERR ("mpd_title: invalid length argument");
+                       }
+               }
                END OBJ(mpd_random, INFO_MPD)
                END OBJ(mpd_repeat, INFO_MPD)
                END OBJ(mpd_elapsed, INFO_MPD)
@@ -2936,6 +3150,25 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                memset(&(info.bmpx), 0, sizeof(struct bmpx_s));
        END
 #endif
+#ifdef RSS
+       OBJ(rss, 0) 
+               if (arg) {
+                       int argc, delay, act_par;
+                       char *uri = (char *)malloc(128 * sizeof(char));
+                       char *action = (char *)malloc(64 * sizeof(char));
+
+                       argc = sscanf(arg, "%127s %d %63s %d", uri, &delay, action, &act_par);
+                       obj->data.rss.uri = uri;
+                       obj->data.rss.delay = delay;
+                       obj->data.rss.action = action;
+                       obj->data.rss.act_par = act_par;
+
+                       init_rss_info();
+               } else
+                       CRIT_ERR("rss needs arguments: <uri> <delay in minutes> <action> [act_par]");
+
+       END
+#endif
 #ifdef HDDTEMP
        OBJ(hddtemp, 0)
                if (!arg || scan_hddtemp(arg, &obj->data.hddtemp.dev, 
@@ -3107,10 +3340,15 @@ static struct text_object_list *extract_variable_text_internal(const char *p)
 
                                /* variable is either $foo or ${foo} */
                                if (*p == '{') {
+                                       unsigned int brl = 1, brr = 0;
                                        p++;
                                        s = p;
-                                       while (*p && *p != '}')
+                                       while (*p && brl != brr) {
+                                               if (*p == '{') brl++;
+                                               if (*p == '}') brr++;
                                                p++;
+                                       }
+                                       p--;
                                } else {
                                        s = p;
                                        if (*p == '#')
@@ -3291,6 +3529,30 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                obj->a = get_voltage(p, p_max_size, "%'.3f", 1000, obj->data.cpu_index);
                                        }
                                }
+#ifdef HAVE_IWLIB
+                               OBJ(wireless_essid) {
+                                       snprintf(p, p_max_size, "%s", obj->data.net->essid);
+                               }
+                               OBJ(wireless_mode) {
+                                       snprintf(p, p_max_size, "%s", obj->data.net->mode);
+                               }
+                               OBJ(wireless_bitrate) {
+                                       snprintf(p, p_max_size, "%s", obj->data.net->bitrate);
+                               }
+                               OBJ(wireless_ap) {
+                                       snprintf(p, p_max_size, "%s", obj->data.net->ap);
+                               }
+                               OBJ(wireless_link_qual) {
+                                       snprintf(p, p_max_size, "%d", obj->data.net->link_qual);
+                               }
+                               OBJ(wireless_link_qual_max) {
+                                       snprintf(p, p_max_size, "%d", obj->data.net->link_qual_max);
+                               }
+                               OBJ(wireless_link_bar) {
+                                       new_bar(p, obj->a, obj->b, ((double)obj->data.net->link_qual/obj->data.net->link_qual_max)*255.0);
+                               }
+#endif /* HAVE_IWLIB */
+
 #endif /* __linux__ */
 
                                OBJ(freq_dyn) {
@@ -3325,6 +3587,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                OBJ(battery_time) {
                                        get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_TIME);
                                }
+                               OBJ(battery_percent) {
+                                       snprintf(p, p_max_size, "%d", 
+                                               get_battery_perct(obj->data.s));
+                               }
+                               OBJ(battery_bar) {
+                                       new_bar(p, obj->a, obj->b, get_battery_perct_bar(obj->data.s));
+                               }
                                OBJ(buffers) {
                                        human_readable(cur->buffers * 1024, p, 255);
                                }
@@ -3360,6 +3629,36 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                OBJ(color) {
                                        new_fg(p, obj->data.l);
                                }
+                               OBJ(color0) {
+                                       new_fg(p, color0);
+                               }
+                               OBJ(color1) {
+                                       new_fg(p, color1);
+                               }
+                               OBJ(color2) {
+                                       new_fg(p, color2);
+                               }
+                               OBJ(color3) {
+                                       new_fg(p, color3);
+                               }
+                               OBJ(color4) {
+                                       new_fg(p, color4);
+                               }
+                               OBJ(color5) {
+                                       new_fg(p, color5);
+                               }
+                               OBJ(color6) {
+                                       new_fg(p, color6);
+                               }
+                               OBJ(color7) {
+                                       new_fg(p, color7);
+                               }
+                               OBJ(color8) {
+                                       new_fg(p, color8);
+                               }
+                               OBJ(color9) {
+                                       new_fg(p, color9);
+                               }
 #if defined(__linux__)
                                OBJ(i8k_version) {
                                        snprintf(p, p_max_size, "%s", i8k.version);
@@ -3441,11 +3740,42 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                 }
 #endif /* __linux__ */
 
-#ifdef X11
+#ifdef __OpenBSD__
+                               OBJ(obsd_sensors_temp) {
+                                       obsd_sensors.device = sensor_device;
+                                       update_obsd_sensors();
+                                       snprintf(p, p_max_size, "%.1f",
+                                               obsd_sensors.temp[obsd_sensors.device][obj->data.sensor]);
+                               }
+
+                               OBJ(obsd_sensors_fan) {
+                                       obsd_sensors.device = sensor_device;
+                                       update_obsd_sensors();
+                                       snprintf(p, p_max_size, "%d",
+                                               obsd_sensors.fan[obsd_sensors.device][obj->data.sensor]);
+                               }
+
+                               OBJ(obsd_sensors_volt) {
+                                       obsd_sensors.device = sensor_device;
+                                       update_obsd_sensors();
+                                       snprintf(p, p_max_size, "%.2f",
+                                               obsd_sensors.volt[obsd_sensors.device][obj->data.sensor]);
+                               }
+
+                               OBJ(obsd_vendor) {
+                                       get_obsd_vendor(p, p_max_size);
+                               }
+
+                               OBJ(obsd_product) {
+                                       get_obsd_product(p, p_max_size);
+                               }
+#endif /* __OpenBSD__ */
+
                                OBJ(font) {
+#ifdef X11
                                        new_font(p, obj->data.s);
-                               }
 #endif /* X11 */
+                               }
                                void format_diskio(unsigned int diskio_value)
                                {
                                        if (!use_spacer) {
@@ -3727,8 +4057,8 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                        } else {
                                                char *output = obj->data.execi.buffer;
                                                FILE *fp = popen(obj->data.execi.cmd, "r");
-                                               //int length = fread(output, 1, TEXT_BUFFER_SIZE, fp);
-                                               int length = fread(output, 1, TEXT_BUFFER_SIZE, fp);
+                                               //int length = fread(output, 1, text_buffer_size, fp);
+                                               int length = fread(output, 1, text_buffer_size, fp);
                                                (void) pclose(fp);
 
                                                output[length] = '\0';
@@ -3849,7 +4179,7 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                {
                                                    obj->data.mail->p_timed_thread = 
                                                    timed_thread_create ((void*)pop3_thread,
-                                                                        (void*)info.mail,
+                                                                        (void*)obj->data.mail,
                                                                         obj->data.mail->interval * 1000000);
                                                    if (!obj->data.mail->p_timed_thread)
                                                        ERR("Error starting pop3 thread");
@@ -4017,6 +4347,56 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                        OBJ(hr) {
                                new_hr(p, obj->data.i);
                        }
+#ifdef RSS
+                       OBJ(rss) {
+                               PRSS* data = get_rss_info(obj->data.rss.uri, obj->data.rss.delay);
+                               char *str;
+                               if(data == NULL)
+                                       snprintf(p, p_max_size, "prss: Error reading RSS data\n");
+                               else {
+                                       if(!strcmp(obj->data.rss.action, "feed_title")) {
+                                                       str = data->title;
+                                                       if(str[strlen(str)-1] == '\n')
+                                                               str[strlen(str)-1] = 0; // remove trailing new line if one exists
+                                                       snprintf(p, p_max_size, "%s", str);
+                                       } else if(!strcmp(obj->data.rss.action, "item_title")) {
+                                               if(obj->data.rss.act_par < data->item_count) {
+                                                       str = data->items[obj->data.rss.act_par].title;
+                                                       if(str[strlen(str)-1] == '\n')
+                                                               str[strlen(str)-1] = 0; // remove trailing new line if one exists
+                                                       snprintf(p, p_max_size, "%s", str);
+                                               }
+                                       } else if(!strcmp(obj->data.rss.action, "item_desc")) {
+                                               if(obj->data.rss.act_par < data->item_count) {
+                                                       str = data->items[obj->data.rss.act_par].description;
+                                                       if(str[strlen(str)-1] == '\n')
+                                                               str[strlen(str)-1] = 0; // remove trailing new line if one exists
+                                                       snprintf(p, p_max_size, "%s", str);
+                                               }
+                                       } else if(!strcmp(obj->data.rss.action, "item_titles")) {
+                                               if(data->item_count > 0) {
+                                                       int itmp;
+                                                       p[0] = 0;
+                                                       int show;
+                                                       if(obj->data.rss.act_par > data->item_count)
+                                                               show = data->item_count;
+                                                       else    show = obj->data.rss.act_par;
+                                                       for(itmp = 0; itmp < show; itmp++) {
+                                                               PRSS_Item *item = &data->items[itmp];
+                                                               str = item->title;
+                                                               if(str) {
+                                                                       if(itmp>0) // don't add new line before first item
+                                                                               strncat(p, "\n", p_max_size);
+                                                                       if(str[strlen(str)-1] == '\n')
+                                                                               str[strlen(str)-1] = 0; // remove trailing new line if one exists, we have our own
+                                                                       strncat(p, str, p_max_size);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+#endif
 #ifdef HDDTEMP
                        OBJ(hddtemp) {
                                char *temp;
@@ -4058,6 +4438,20 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                        OBJ(alignc) {
                                new_alignc(p, obj->data.i);
                        }
+                       OBJ(if_empty) {
+                               struct information *my_info =
+                                   malloc(sizeof(struct information));
+                               memcpy(my_info, cur, sizeof(struct information));
+                               parse_conky_vars(obj->data.ifblock.s, p, my_info);
+                               if (strlen(p) != 0) {
+                                       i = obj->data.ifblock.pos;
+                                       if_jumped = 1;
+                               } else {
+                                       if_jumped = 0;
+                               }
+                               p[0] = '\0';
+                               free(my_info);
+                       }
                        OBJ(if_existing) {
                                struct stat tmp;
                                if ((obj->data.ifblock.s)
@@ -4066,7 +4460,15 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                        i = obj->data.ifblock.pos;
                                        if_jumped = 1;
                                } else {
-                                       if_jumped = 0;
+                                       if (obj->data.ifblock.str) {
+                                               if (!check_contains(obj->data.ifblock.s, 
+                                                       obj->data.ifblock.str)) {
+                                                       i = obj->data.ifblock.pos;
+                                                       if_jumped = 1;
+                                               } else 
+                                                       if_jumped = 0;
+                                       } else 
+                                               if_jumped = 0;
                                }
                        }
                        OBJ(if_mounted) {
@@ -4164,6 +4566,10 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                        OBJ(mails) {
                                snprintf(p, p_max_size, "%d", cur->mail_count);
                        }
+                       OBJ(mboxscan) {
+                mbox_scan(obj->data.mboxscan.args, obj->data.mboxscan.output, TEXT_BUFFER_SIZE);
+                               snprintf(p, p_max_size, "%s", obj->data.mboxscan.output);
+                       }
                        OBJ(new_mails) {
                                snprintf(p, p_max_size, "%d", cur->new_mail_count);
                        }
@@ -4282,7 +4688,7 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                        trans_speed /
                                                        1024));
                                else
-                                       snprintf(p, 5, "%d     ",
+                                       snprintf(p, 6, "%d     ",
                                                 (int) (obj->data.net->
                                                        trans_speed /
                                                        1024));
@@ -4314,9 +4720,12 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                format_seconds(p, p_max_size, (int) cur->uptime);
                        }
 
-#if defined(__FreeBSD__) && (defined(i386) || defined(__i386__))
+#if (defined(__FreeBSD__) || defined(__OpenBSD__)) && (defined(i386) || defined(__i386__))
                        OBJ(apm_adapter) {
-                               snprintf(p, p_max_size, "%s", get_apm_adapter());
+                               char    *msg;
+                               msg = get_apm_adapter();
+                               snprintf(p, p_max_size, "%s", msg);
+                               free(msg);
                        }
                        OBJ(apm_battery_life) {
                                char    *msg;
@@ -4330,11 +4739,13 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                snprintf(p, p_max_size, "%s", msg);
                                free(msg);
                        }
-#endif /* __FreeBSD__ */
+#endif /* __FreeBSD__ __OpenBSD__ */
 
 #ifdef MPD
                        OBJ(mpd_title) {
-                               snprintf(p, p_max_size, "%s", cur->mpd.title);
+                           snprintf(p, cur->mpd.max_title_len > 0 ?
+                                       cur->mpd.max_title_len : p_max_size, "%s", 
+                                    cur->mpd.title);
                        }
                        OBJ(mpd_artist) {
                                snprintf(p, p_max_size, "%s", cur->mpd.artist);
@@ -4583,25 +4994,23 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                if (obj->data.top.type == TOP_NAME
                                    && obj->data.top.num >= 0
                                    && obj->data.top.num < 10) {
-                                       // if we limit the buffer and add a bunch of space after, it stops the thing from
-                                       // moving other shit around, which is really fucking annoying
-                                       snprintf(p, 17, "%s                              ", cur->cpu[obj->data.top.num]->name);
+                                       snprintf(p, 17, "%-17s", cur->cpu[obj->data.top.num]->name);
                                } else if (obj->data.top.type == TOP_CPU
                                           && obj->data.top.num >= 0
                                           && obj->data.top.num < 10) {
-                                       snprintf(p, 7, "%3.2f      ",
+                                       snprintf(p, 7, "%7.3f",
                                                 cur->cpu[obj->data.top.
                                                          num]->amount);
                                } else if (obj->data.top.type == TOP_PID
                                           && obj->data.top.num >= 0
                                           && obj->data.top.num < 10) {
-                                       snprintf(p, 8, "%i           ",
+                                       snprintf(p, 8, "%7i",
                                                 cur->cpu[obj->data.top.
                                                          num]->pid);
                                } else if (obj->data.top.type == TOP_MEM
                                           && obj->data.top.num >= 0
                                           && obj->data.top.num < 10) {
-                                       snprintf(p, 7, "%3.2f       ",
+                                       snprintf(p, 7, "%7.3f",
                                                 cur->cpu[obj->data.top.
                                                          num]->totalmem);
                                }
@@ -4610,28 +5019,25 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                if (obj->data.top.type == TOP_NAME
                                    && obj->data.top.num >= 0
                                    && obj->data.top.num < 10) {
-                                       // if we limit the buffer and add a bunch of space after, it stops the thing from
-                                       // moving other shit around, which is really fucking annoying
-                                       snprintf(p, 17,
-                                                "%s                              ",
+                                       snprintf(p, 17, "%-17s",
                                                 cur->memu[obj->data.top.
                                                           num]->name);
                                } else if (obj->data.top.type == TOP_CPU
                                           && obj->data.top.num >= 0
                                           && obj->data.top.num < 10) {
-                                       snprintf(p, 7, "%3.2f      ",
+                                       snprintf(p, 7, "%7.3f",
                                                 cur->memu[obj->data.top.
                                                           num]->amount);
                                } else if (obj->data.top.type == TOP_PID
                                           && obj->data.top.num >= 0
                                           && obj->data.top.num < 10) {
-                                       snprintf(p, 8, "%i           ",
+                                       snprintf(p, 8, "%7i",
                                                 cur->memu[obj->data.top.
                                                           num]->pid);
                                } else if (obj->data.top.type == TOP_MEM
                                           && obj->data.top.num >= 0
                                           && obj->data.top.num < 10) {
-                                       snprintf(p, 7, "%3.2f       ",
+                                       snprintf(p, 7, "%7.3f",
                                                 cur->memu[obj->data.top.
                                                           num]->totalmem);
                                }
@@ -4644,7 +5050,7 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                } else {
                                        obj->data.tail.last_update = current_update_time;
                                        FILE *fp;
-                                       long nl, bsize;
+                                       long nl=0, bsize;
                                        int iter;
                                        fp = fopen(obj->data.tail.logfile, "rt");
                                        if (fp == NULL) {
@@ -4677,9 +5083,9 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                }
                                                /* Make sure bsize is at least 1 byte smaller than
                                                 * the buffer max size. */
-                                               if(bsize > TEXT_BUFFER_SIZE*20 - 1) {
-                                                       fseek(fp, bsize - TEXT_BUFFER_SIZE*20 - 1, SEEK_CUR);
-                                                       bsize = TEXT_BUFFER_SIZE*20 - 1;
+                                               if(bsize > (long)((text_buffer_size*20) - 1)) {
+                                                       fseek(fp, bsize - text_buffer_size*20 - 1, SEEK_CUR);
+                                                       bsize = text_buffer_size*20 - 1;
                                                }
                                                bsize = fread(obj->data.tail.buffer, 1, bsize, fp);
                                                fclose(fp);
@@ -4708,7 +5114,7 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                } else {
                                        obj->data.tail.last_update = current_update_time;
                                        FILE *fp;
-                                       long nl;
+                                       long nl=0;
                                        int iter;
                                        fp = fopen(obj->data.tail.logfile, "rt");
                                        if (fp == NULL) {
@@ -4730,8 +5136,8 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                obj->data.tail.readlines = iter;
                                                /* Make sure nl is at least 1 byte smaller than
                                                 * the buffer max size. */
-                                               if(nl > TEXT_BUFFER_SIZE*20 - 1) {
-                                                       nl = TEXT_BUFFER_SIZE*20 - 1;
+                                               if(nl > (long)((text_buffer_size*20) - 1)) {
+                                                       nl = text_buffer_size*20 - 1;
                                                }
                                                nl = fread(obj->data.tail.buffer, 1, nl, fp);
                                                fclose(fp);
@@ -6170,17 +6576,18 @@ void clean_up(void)
        destroy_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
        info.p_tcp_port_monitor_collection = NULL;
 #endif
+#ifdef RSS
+       free_rss_info();
+#endif
 
        if (specials) {
-           free (specials);
-           specials=NULL;
+               unsigned int i;
+               for(i=0;i<special_count;i++)
+                       if(specials[i].type == GRAPH)
+                               free(specials[i].graph);
+               free (specials);
+               specials=NULL;
        }
-
-#ifdef HAVE_LIBDEXTER
-  dexter_library_exit ();
-  if (dexter_config)
-    free (dexter_config);
-#endif
 }
 
 static int string_to_bool(const char *s)
@@ -6254,6 +6661,9 @@ static void set_default_configurations(void)
     info.xmms2.status = NULL;
 #endif
        use_spacer = 0;
+#if defined(__linux__)
+       post_21_kernel = 0;
+#endif /* __linux__ */
 #ifdef X11
        out_to_console = 0;
 #else
@@ -6263,6 +6673,16 @@ static void set_default_configurations(void)
        default_fg_color = WhitePixel(display, screen);
        default_bg_color = BlackPixel(display, screen);
        default_out_color = BlackPixel(display, screen);
+       color0 = default_fg_color;
+       color1 = default_fg_color;
+       color2 = default_fg_color;
+       color3 = default_fg_color;
+       color4 = default_fg_color;
+       color5 = default_fg_color;
+       color6 = default_fg_color;
+       color7 = default_fg_color;
+       color8 = default_fg_color;
+       color9 = default_fg_color;
        draw_shades = 1;
        draw_borders = 0;
        draw_graph_borders = 1;
@@ -6399,6 +6819,66 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
                        else
                                CONF_ERR;
                }
+               CONF("color0") {
+                       if (value)
+                               color0 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("color1") {
+                       if (value)
+                               color1 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("color2") {
+                       if (value)
+                               color2 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("color3") {
+                       if (value)
+                               color3 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("color4") {
+                       if (value)
+                               color4 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("color5") {
+                       if (value)
+                               color5 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("color6") {
+                       if (value)
+                               color6 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("color7") {
+                       if (value)
+                               color7 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("color8") {
+                       if (value)
+                               color8 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
+               CONF("color9") {
+                       if (value)
+                               color9 = get_x11_color(value);
+                       else
+                               CONF_ERR;
+               }
                CONF("default_color") {
                        if (value)
                                default_fg_color = get_x11_color(value);
@@ -6454,6 +6934,14 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
                                CONF_ERR;
                }
 #endif
+#ifdef __OpenBSD__
+               CONF("sensor_device") {
+                       if(value)
+                               sensor_device = strtol(value, 0, 0);
+                       else
+                               CONF_ERR;
+               }
+#endif
                CONF("cpu_avg_samples") {
                        if (value) {
                                cpu_avg_samples = strtol(value, 0, 0);
@@ -6508,6 +6996,11 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
                CONF("draw_outline") {
                        draw_outline = string_to_bool(value);
                }
+#if defined(__linux__)
+               CONF("post_21_kernel") {
+                       post_21_kernel = string_to_bool(value);
+               }
+#endif /* __linux__ */
 #endif /* X11 */
                CONF("out_to_console") {
                        out_to_console = string_to_bool(value);
@@ -6735,6 +7228,12 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
                        else
                                CONF_ERR;
                }
+               CONF("text_buffer_size") {
+                       if (value)
+                               text_buffer_size = atoi(value);
+                       else
+                               CONF_ERR;
+               }
                CONF("text") {
                        if (text != original_text)
                                free(text);
@@ -6782,29 +7281,6 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
                        /* else tcp_port_monitor_args.max_port_monitor_connections > 0 as per config */
                }
 #endif
-#ifdef HAVE_LIBDEXTER
-    CONF("dexter_client")
-    {
-      if (value)
-        dexter_client = string_to_bool (value);
-      else
-        CONF_ERR;
-    }
-    CONF("dexter_server")
-    {
-      if (value)
-        dexter_server = string_to_bool (value);
-      else 
-        CONF_ERR;
-    }
-    CONF("dexter_config")
-    {
-      if (value)
-        dexter_config = strdup (value);
-      else
-        CONF_ERR;
-    }
-#endif
 
                else
                ERR("%s: %d: no such configuration: '%s'", f, line, name);
@@ -6858,6 +7334,7 @@ int main(int argc, char **argv)
                for (x = 0; x < strlen(s); x++) {
                        temp[x] = tolower(s[x]);
                }
+               temp[x] = 0;
                if (strstr(temp, "utf-8") || strstr(temp, "utf8")) {
                        utf8_mode = 1;
                }
@@ -7071,48 +7548,6 @@ int main(int argc, char **argv)
                }
        }
 
-#ifdef HAVE_LIBDEXTER
-  memset (&packet_arrival_time, 0, sizeof (struct timespec));
-  dexter_library_init ();
-  if (dexter_client)
-  {
-    /* wait until some data packets arrive, else conky complains
-     * bittery that /proc filesystems cannot be opened and, worse,
-     * will likely segfault when it references unchecked pointers
-     * in get_text_internal() -- those should be cleaned up.
-     */
-    int try;
-    const int max_tries=30;
-    gboolean got_packet;
-    GTimeVal timeval;
-    fprintf (stderr, "Conky: waiting for data packets to arrive ...\n");
-    for (try=0;try<max_tries;try++)
-    {
-      /* pause main thread for 1 sec */
-      g_get_current_time (&timeval);
-      g_time_val_add (&timeval, G_USEC_PER_SEC); 
-      g_mutex_lock (packet_mutex);
-      /* mutex released before sleeping; re-acquired after time elapses */
-      g_cond_timed_wait (packet_cond, packet_mutex, &timeval);
-      got_packet = packet_arrival_time.tv_sec>0;
-      g_mutex_unlock (packet_mutex);
-
-      if (got_packet)
-        break;
-    }
-    if (got_packet)
-    {
-      fprintf(stderr, "Conky: packets arriving ...\n");
-    }
-    else
-    {
-      fprintf(stderr, "Conky: no data packets ...\n");
-      dexter_library_exit ();
-      exit(1);
-    }
-  }
-#endif
-
 #ifdef X11
        selected_font = 0;
        update_text_area();     /* to get initial size of the window */
@@ -7187,119 +7622,3 @@ void signal_handler(int sig)
         * and do any signal processing there, NOT here. */
        g_signal_pending=sig;
 }
-
-#ifdef HAVE_LIBDEXTER
-void dexter_library_init (void)
-{
-  /* start libdexter */
-  if (dexter_client || dexter_server)
-  {
-    GError *error = NULL;
-    dexter_init (dexter_config, &error);
-    if (error)
-      CRIT_ERR ("%s", error->message);
-
-    if (dexter_client)
-    {
-      if (!(info.dexter.channel = dexter_channel_new (NULL, NULL, NULL, dexter_channel_events)))
-        CRIT_ERR("unable to create channel to server");
-      dexter_channel_open (info.dexter.channel, &error);
-      if (error)
-        CRIT_ERR ("%s", error->message);
-      dexter_channel_greet (info.dexter.channel, &error);
-      if (error)
-        CRIT_ERR ("%s", error->message);
-      if (dexter_client_init () < 0)
-        CRIT_ERR ("error initializing dexter client");
-
-      packet_mutex = g_mutex_new ();
-      packet_cond = g_cond_new ();
-    }
-
-    if (dexter_server)
-    {
-      if (!(info.dexter.server = dexter_server_new (NULL, NULL, NULL)))
-        CRIT_ERR("unable to create server");
-      dexter_server_start (info.dexter.server, &error);
-      if (error)
-        CRIT_ERR ("%s", error->message);
-    }
-
-  }
-}
-
-void dexter_library_exit (void)
-{
-  /* shutdown libdexter */
-  if (dexter_client || dexter_server)
-  {
-    GError *error = NULL;
-
-    if (dexter_client)
-    {
-      if (dexter_client_exit () < 0)
-        ERR ("error de-initializing dexter client");
-      if (info.dexter.channel)
-      {
-        dexter_channel_part (info.dexter.channel, &error);
-        if (error)
-        {
-          ERR("%s", error->message);
-          g_clear_error (&error);
-        }
-        dexter_channel_close (info.dexter.channel, &error);
-        if (error)
-        {
-          ERR("%s", error->message);
-          g_clear_error (&error);
-        }
-        dexter_channel_free (info.dexter.channel);
-        info.dexter.channel=NULL;
-      }
-
-      if (packet_mutex)
-      {
-        g_mutex_free (packet_mutex);
-        packet_mutex=NULL;
-      }
-      if (packet_cond)
-      {
-        g_cond_free (packet_cond);
-        packet_cond=NULL;
-      }
-    }
-
-    if (dexter_server)
-    {
-      if (info.dexter.server)
-      {
-        dexter_server_stop (info.dexter.server, &error);
-        if (error)
-        {
-          ERR("%s", error->message);
-          g_clear_error (&error);
-        }
-        dexter_server_free (info.dexter.server);
-        info.dexter.server=NULL;
-      }
-    }
-
-    dexter_exit ();
-  }
-}
-
-void dexter_channel_events (DexterChannel *channel, gint event)
-{
-  if (!channel)
-    return;
-
-  /* if server disconnects we get this event.  we also get it normally
-   * following dexter_channel_part(). */
-  if (event == DEXTER_CHANNEL_EVENT_NOCONN)
-  {
-    fprintf (stderr, "Conky: channel to server closed\n");
-    if (dexter_client && (dexter_client_exit () < 0))
-      ERR ("error de-initializing dexter client");
-  }
-}
-#endif