RSS was not really disabled when it was supposed to be. Experimental wireless support.
[monky] / src / conky.c
index 62b063e..34a24b2 100644 (file)
@@ -9,13 +9,11 @@
 #include "conky.h"
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <ctype.h>
 #include <time.h>
 #include <locale.h>
 #include <signal.h>
 #include <unistd.h>
-#include <string.h>
 #include <errno.h>
 #include <termios.h>
 #include <string.h>
 #include <netinet/in.h>
 #include <netdb.h>
 
-
 #ifdef HAVE_ICONV
 #include <iconv.h>
 #endif
 
 #include "build.h"
 
+#ifndef S_ISSOCK
+#define S_ISSOCK(x)   ((x & S_IFMT) == S_IFSOCK)
+#endif
+
 #define CONFIG_FILE "$HOME/.conkyrc"
 #define MAIL_FILE "$MAIL"
 #define MAX_IF_BLOCK_DEPTH 5
@@ -92,11 +93,18 @@ static void print_version()
 #ifdef TCP_PORT_MONITOR
        "  * portmon\n"
 #endif /* TCP_PORT_MONITOR */
+#ifdef RSS
+       "  * rss\n"
+#endif /* RSS */
        "\n");  
 
        exit(0);
 }
 
+#if defined(__linux__)
+int post_21_kernel;
+#endif /* __linux__ */
+
 #ifdef X11
 
 /*
@@ -271,9 +279,6 @@ static char *current_config;
 /* set to 1 if you want all text to be in uppercase */
 static unsigned int stuff_in_upper_case;
 
-/* Update interval */
-static double update_interval;
-
 /* Run how many times? */
 static unsigned long total_run_times;
 
@@ -315,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;
 
@@ -351,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]);
                        }
                }
@@ -419,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
 }
 
 
@@ -533,53 +536,91 @@ static struct special_t *new_special(char *buf, int t)
        return &specials[special_count++];
 }
 
-typedef struct tailstring_list {
-       char data[TEXT_BUFFER_SIZE];
-       struct tailstring_list *next;
-       struct tailstring_list *first;
-} tailstring;
-
-void addtail(tailstring ** head, char *data_in)
-{
-       tailstring *tmp;
-       if ((tmp = malloc(sizeof(*tmp))) == NULL) {
-               CRIT_ERR("malloc");
-       }
-       if (*head == NULL) {
-               tmp->first = tmp;
-       } else {
-               tmp->first = (*head)->first;
+long fwd_fcharfind(FILE* fp, char val, unsigned int step) {
+#define BUFSZ 0x1000
+       long ret = -1;
+       unsigned int count = 0;
+       static char buf[BUFSZ];
+       long orig_pos = ftell(fp);
+       long buf_pos = -1;
+       long buf_size = BUFSZ;
+       char* cur_found = NULL;
+       while(count < step) {
+               if(cur_found == NULL) {
+                       buf_size = fread(buf, 1, buf_size, fp);
+                       buf_pos = 0;
+               }
+               cur_found = memchr(buf+buf_pos, val, buf_size-buf_pos);
+               if(cur_found != NULL) {
+                       buf_pos = cur_found-buf+1;
+                       count++;
+               }
+               else {
+                       if(feof(fp))
+                               break;
+               }
        }
-       strncpy(tmp->data, data_in, TEXT_BUFFER_SIZE);
-       tmp->next = *head;
-       *head = tmp;
+       if(count == step)
+               ret = ftell(fp) - buf_size + buf_pos - 1;
+       fseek(fp, orig_pos, SEEK_SET);
+       return ret;
+#undef BUFSZ
 }
 
-void freetail(tailstring * head)
+#ifndef HAVE_MEMRCHR
+void *
+memrchr (const void *buffer, int c, size_t n)
 {
-       tailstring *tmp;
-       while (head != NULL) {
-               tmp = head->next;
-               free(head);
-               head = tmp;
-       }
-}
+       const unsigned char *p = buffer;
 
-void freelasttail(tailstring * head)
-{
-       tailstring * tmp = head;
-       while(tmp != NULL) {
-               if (tmp->next == head->first) {
-                       tmp->next = NULL;
-                       break;
+       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;
+       unsigned int count = 0;
+       static char buf[BUFSZ];
+       long orig_pos = ftell(fp);
+       long buf_pos = -1;
+       long file_pos = orig_pos;
+       long buf_size = BUFSZ;
+       char* cur_found;
+       while(count < step) {
+               if(buf_pos <= 0) {
+                       if(file_pos > BUFSZ) {
+                               fseek(fp, file_pos-BUFSZ, SEEK_SET);
+                       }
+                       else {
+                               buf_size = file_pos;
+                               fseek(fp, 0, SEEK_SET);
+                       }
+                       file_pos = ftell(fp);
+                       buf_pos = fread(buf, 1, buf_size, fp);
+               }
+               cur_found = 
+                       memrchr(
+                                       buf,
+                                       (int)val,
+                                       (size_t)buf_pos);
+               if(cur_found != NULL) {
+                       buf_pos = cur_found-buf;
+                       count++;
+               } else {
+                       buf_pos = -1;
+                       if(file_pos == 0) {
+                               break;
+                       }
                }
-               tmp = tmp->next;
-       }
-       free(head->first);
-       while(head != NULL && tmp != NULL) {
-               head->first = tmp;
-               head = head->next;
        }
+       fseek(fp, orig_pos, SEEK_SET);
+       if(count == step)
+               ret = file_pos + buf_pos;
+       return ret;
+#undef BUFSZ
 }
 
 static void new_bar(char *buf, int w, int h, int usage)
@@ -607,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;
 }
 
@@ -883,15 +924,32 @@ enum text_object_type {
        OBJ_acpitemp,
        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,
        OBJ_cpugraph,
        OBJ_diskio,
+       OBJ_diskio_read,
+       OBJ_diskio_write,
        OBJ_diskiograph,
+       OBJ_diskiograph_read,
+       OBJ_diskiograph_write,
        OBJ_downspeed,
        OBJ_downspeedf,
        OBJ_downspeedgraph,
@@ -943,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,
@@ -955,6 +1021,7 @@ enum text_object_type {
        OBJ_loadavg,
        OBJ_machine,
        OBJ_mails,
+       OBJ_mboxscan,
        OBJ_mem,
        OBJ_membar,
        OBJ_memgraph,
@@ -999,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,
@@ -1069,10 +1143,12 @@ enum text_object_type {
        OBJ_bmpx_uri,
        OBJ_bmpx_bitrate,
 #endif
+#ifdef RSS
+       OBJ_rss,
+#endif
 #ifdef TCP_PORT_MONITOR
        OBJ_tcp_portmon,
 #endif
-
 #ifdef HAVE_ICONV
        OBJ_iconv_start,
        OBJ_iconv_stop,
@@ -1104,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;
@@ -1124,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;
@@ -1176,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;
 };
 
@@ -1272,6 +1364,7 @@ void *imap_thread(struct mail_s* mail)
        int fail = 0;
        unsigned int old_unseen = UINT_MAX;
        unsigned int old_messages = UINT_MAX;
+       struct stat stat_buf;
        struct hostent *he;
        struct sockaddr_in their_addr;  // connector's address information
        if ((he = gethostbyname(mail->host)) == NULL) { // get the host info 
@@ -1430,7 +1523,6 @@ void *imap_thread(struct mail_s* mail)
                        fail++;
                        goto next_iteration;
                }
-               close(sockfd);
                if (strlen(mail->command) > 1 && (mail->unseen > old_unseen || (mail->messages > old_messages && mail->unseen > 0))) {  // new mail goodie
                        if (system(mail->command) == -1) {
                                perror("system()");
@@ -1440,6 +1532,9 @@ void *imap_thread(struct mail_s* mail)
                old_unseen = mail->unseen;
                old_messages = mail->messages;
 next_iteration:
+               if ((fstat(sockfd, &stat_buf)==0) && S_ISSOCK(stat_buf.st_mode))
+                   /* if a valid socket, close it */
+                   close(sockfd);
                if (timed_thread_test (mail->p_timed_thread))
                    timed_thread_exit (mail->p_timed_thread);
        }
@@ -1454,6 +1549,7 @@ void *pop3_thread(struct mail_s *mail)
        char *reply;
        int fail = 0;
        unsigned int old_unseen = UINT_MAX;
+       struct stat stat_buf;
        struct hostent *he;
        struct sockaddr_in their_addr;  // connector's address information
        if ((he = gethostbyname(mail->host)) == NULL) { // get the host info 
@@ -1631,7 +1727,6 @@ void *pop3_thread(struct mail_s *mail)
                        fail++;
                        goto next_iteration;
                }
-               close(sockfd);
                if (strlen(mail->command) > 1 && mail->unseen > old_unseen) {   // new mail goodie
                        if (system(mail->command) == -1) {
                                perror("system()");
@@ -1640,6 +1735,9 @@ void *pop3_thread(struct mail_s *mail)
                fail = 0;
                old_unseen = mail->unseen;
 next_iteration:
+               if ((fstat(sockfd, &stat_buf)==0) && S_ISSOCK(stat_buf.st_mode))  
+                   /* if a valid socket, close it */
+                   close(sockfd);
                if (timed_thread_test (mail->p_timed_thread))
                    timed_thread_exit (mail->p_timed_thread);
        }
@@ -1652,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') {
@@ -1702,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;
@@ -1728,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:
@@ -1918,11 +2023,19 @@ 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);
                                break;
-
+                       case OBJ_battery_time:
+                               free(objs[i].data.s);
+                               break;
                        case OBJ_execi:
                                free(objs[i].data.execi.cmd);
                                free(objs[i].data.execi.buffer);
@@ -1994,7 +2107,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                OBJ(acpitemp, 0) obj->data.i = open_acpi_temperature(arg);
        END OBJ(acpitempf, 0) obj->data.i = open_acpi_temperature(arg);
        END OBJ(acpiacadapter, 0)
-       END OBJ(freq, 0)
+       END OBJ(freq, INFO_FREQ)
            get_cpu_count();
        if (!arg
            || !isdigit(arg[0])
@@ -2010,7 +2123,7 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
            obj->data.cpu_index=atoi(&arg[0]);
        }
        obj->a = 1;
-       END OBJ(freq_g, 0)
+       END OBJ(freq_g, INFO_FREQ)
            get_cpu_count();
        if (!arg
            || !isdigit(arg[0])
@@ -2059,9 +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;
-#else 
-       END OBJ(freq, 0);
-       END OBJ(freq_g, 0);
+
+#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);
@@ -2073,6 +2223,29 @@ 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_time, 0);
+       char bat[64];
+       if (arg)
+               sscanf(arg, "%63s", bat);
+       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)
@@ -2114,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)
@@ -2149,16 +2353,38 @@ static struct text_object *construct_text_object(const char *s, const char *arg,
                        obj->data.cpu_index = 0;
                }
        END OBJ(diskio, INFO_DISKIO)
-               END OBJ(diskiograph, INFO_DISKIO) (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
+       END OBJ(diskio_read, INFO_DISKIO)
+       END OBJ(diskio_write, INFO_DISKIO)
+       END OBJ(diskiograph, INFO_DISKIO) (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
+       END OBJ(diskiograph_read, INFO_DISKIO) (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
+       END OBJ(diskiograph_write, INFO_DISKIO) (void) scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d, &obj->e);
        END OBJ(color, 0) 
 #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);
                }
@@ -2235,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) {
@@ -2247,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;
@@ -2425,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);
@@ -2432,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;
@@ -2450,9 +2678,9 @@ 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 - 1;
+                               obj->data.tail.wantedlines = n1;
                                obj->data.tail.interval =
                                        update_interval * 2;
                                fclose(fp);
@@ -2475,9 +2703,9 @@ 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 - 1;
+                               obj->data.tail.wantedlines = n1;
                                obj->data.tail.interval = n2;
                                fclose(fp);
                        } else {
@@ -2491,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;
@@ -2510,9 +2738,9 @@ 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 - 1;
+                               obj->data.tail.wantedlines = n1;
                                obj->data.tail.interval =
                                        update_interval * 2;
                                fclose(fp);
@@ -2535,9 +2763,9 @@ 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 - 1;
+                               obj->data.tail.wantedlines = n1;
                                obj->data.tail.interval = n2;
                                fclose(fp);
                        } else {
@@ -2551,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);
@@ -2565,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");
@@ -2607,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)
@@ -2753,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
@@ -2795,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)
@@ -2884,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, 
@@ -3055,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 == '#')
@@ -3239,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) {
@@ -3268,7 +3582,17 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                        get_acpi_ac_adapter(p, p_max_size); 
                                }
                                OBJ(battery) {
-                                       get_battery_stuff(p, p_max_size, obj->data.s);
+                                       get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_STATUS);
+                               }
+                               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);
@@ -3305,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);
@@ -3386,12 +3740,44 @@ 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 */
-                               OBJ(diskio) {
+                               }
+                               void format_diskio(unsigned int diskio_value)
+                               {
                                        if (!use_spacer) {
                                                if (diskio_value > 1024*1024) {
                                                        snprintf(p, p_max_size, "%.1fGiB",
@@ -3406,24 +3792,42 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                }
                                        } else {
                                                if (diskio_value > 1024*1024) {
-                                                       snprintf(p, 6, "%.1fGiB   ",
+                                                       snprintf(p, 12, "%.1fGiB   ",
                                                                        (double)diskio_value/1024/1024);
                                                } else if (diskio_value > 1024) {
-                                                       snprintf(p, 6, "%.1fMiB   ",
+                                                       snprintf(p, 12, "%.1fMiB   ",
                                                                        (double)diskio_value/1024);
                                                } else if (diskio_value > 0) {
-                                                       snprintf(p, 6, "%dKiB ", diskio_value);
+                                                       snprintf(p, 12, "%dKiB ", diskio_value);
                                                } else {
-                                                       snprintf(p, 6, "%dB     ", diskio_value);
+                                                       snprintf(p, 12, "%dB     ", diskio_value);
                                                }
                                        }
                                }
-                               OBJ(diskiograph) {
-                                       new_graph(p, obj->a,
-                                                       obj->b, obj->c, obj->d,
-                                                       diskio_value, obj->e, 1);
-                               }
-
+                               OBJ(diskio) {
+                                       format_diskio(diskio_value);
+                               }
+                               OBJ(diskio_write) {
+                                       format_diskio(diskio_write_value);
+                               }
+                               OBJ(diskio_read) {
+                                       format_diskio(diskio_read_value);
+                               }
+                               OBJ(diskiograph) {
+                                       new_graph(p, obj->a,
+                                                       obj->b, obj->c, obj->d,
+                                                       diskio_value, obj->e, 1);
+                               }
+                               OBJ(diskiograph_read) {
+                                       new_graph(p, obj->a,
+                                                       obj->b, obj->c, obj->d,
+                                                       diskio_read_value, obj->e, 1);
+                               }
+                               OBJ(diskiograph_write) {
+                                       new_graph(p, obj->a,
+                                                       obj->b, obj->c, obj->d,
+                                                       diskio_write_value, obj->e, 1);
+                               }
                                OBJ(downspeed) {
                                        if (!use_spacer) {
                                                snprintf(p, p_max_size, "%d",
@@ -3447,8 +3851,10 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                                recv_speed / 1024.0);
                                }
                                OBJ(downspeedgraph) {
-                                       if (obj->data.net->recv_speed == 0)     // this is just to make the ugliness at start go away
+          /*
+                                       if (obj->data.net->recv_speed == 0)     
                                                obj->data.net->recv_speed = 0.01;
+            */
                                        new_graph(p, obj->a, obj->b, obj->c, obj->d,
                                                        (obj->data.net->recv_speed /
                                                         1024.0), obj->e, 1);
@@ -3651,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';
@@ -3773,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");
@@ -3941,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;
@@ -3982,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)
@@ -3990,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) {
@@ -4088,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);
                        }
@@ -4206,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));
@@ -4222,8 +4704,10 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object *
                                                 trans_speed / 1024.0);
                        }
                        OBJ(upspeedgraph) {
-                               if (obj->data.net->trans_speed == 0)    // this is just to make the ugliness at start go away
+        /*
+                               if (obj->data.net->trans_speed == 0)
                                        obj->data.net->trans_speed = 0.01;
+          */
                                new_graph(p, obj->a, obj->b, obj->c, obj->d,
                                          (obj->data.net->trans_speed /
                                1024.0), obj->e, 1);
@@ -4236,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;
@@ -4252,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);
@@ -4505,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);
                                }
@@ -4532,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);
                                }
@@ -4566,108 +5050,112 @@ 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;
-                                       int i;
-                                       int added = 0;
-                                       tailstring *head = NULL;
-                                       tailstring *headtmp = NULL;
-                                       tailstring *freetmp = NULL;
+                                       long nl=0, bsize;
+                                       int iter;
                                        fp = fopen(obj->data.tail.logfile, "rt");
                                        if (fp == NULL) {
-                                               ERR("tail logfile failed to open");
+                                               /* Send one message, but do not consistently spam on
+                                                * missing logfiles. */
+                                               if(obj->data.tail.readlines != 0) {
+                                                       ERR("tail logfile failed to open");
+                                                       strcpy(obj->data.tail.buffer, "Logfile Missing");
+                                               }
+                                               obj->data.tail.readlines = 0;
+                                               snprintf(p, p_max_size, "Logfile Missing");
                                        }
                                        else {
                                                obj->data.tail.readlines = 0;
-
-                                               while (fgets(obj->data.tail.buffer, TEXT_BUFFER_SIZE*20, fp) != NULL) {
-                                                       if (added >= 30) {
-                                                               freelasttail(head);
-                                                       }
-                                                       else {
-                                                               added++;
-                                                       }
-                                                       addtail(&head, obj->data.tail.buffer);
-                                                       obj->data.tail.readlines++;
+                                               /* -1 instead of 0 to avoid counting a trailing newline */
+                                               fseek(fp, -1, SEEK_END); 
+                                               bsize = ftell(fp) + 1;
+                                               for(iter = obj->data.tail.wantedlines; iter > 0; iter--) {
+                                                       nl = rev_fcharfind(fp, '\n', iter);
+                                                       if(nl >= 0)
+                                                               break;
                                                }
-
+                                               obj->data.tail.readlines = iter;
+                                               if(obj->data.tail.readlines < obj->data.tail.wantedlines) {
+                                                       fseek(fp, 0, SEEK_SET);
+                                               }
+                                               else {
+                                                       fseek(fp, nl+1, SEEK_SET);
+                                                       bsize -= ftell(fp);
+                                               }
+                                               /* Make sure bsize is at least 1 byte smaller than
+                                                * the buffer max size. */
+                                               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);
-                                               freetmp = head;
-
-                                               if (obj->data.tail.readlines > 0) {
-                                                       for (i = 0;i < obj->data.tail.wantedlines + 1 && i < obj->data.tail.readlines; i++) {
-                                                               addtail(&headtmp, head->data);
-                                                               head = head->next;
-                                                       }
-                                                       freetail(freetmp);
-                                                       freetmp = headtmp;
-                                                       strcpy(obj->data.tail.buffer, headtmp->data);
-                                                       headtmp = headtmp->next;
-                                                       for (i = 1;i < obj->data.tail.wantedlines + 1 && i < obj->data.tail.readlines; i++) {
-                                                               if (headtmp) {
-                                                                       strncat(obj->data.tail.buffer, headtmp->data, (TEXT_BUFFER_SIZE * 20) - strlen(obj->data.tail.buffer)); /* without strlen() at the end this becomes a possible */
-                                                                       headtmp = headtmp->next;
-                                                               }
-                                                       }
-
-                                                       /* get rid of any ugly newlines at the end */
-                                                       if (obj->data.tail.buffer[strlen(obj->data.tail.buffer)-1] == '\n') {
-                                                               obj->data.tail.buffer[strlen(obj->data.tail.buffer)-1] = '\0';
-                                                       }
+                                               if(bsize > 0) {
+                                                       /* Clean up trailing newline, make sure the buffer
+                                                        * is null terminated. */
+                                                       if(obj->data.tail.buffer[bsize-1] == '\n')
+                                                               obj->data.tail.buffer[bsize-1] = '\0';
+                                                       else
+                                                               obj->data.tail.buffer[bsize] = '\0';
                                                        snprintf(p, p_max_size, "%s", obj->data.tail.buffer);
-
-                                                       freetail(freetmp);
-                                               } else {
+                                               }
+                                               else {
                                                        strcpy(obj->data.tail.buffer, "Logfile Empty");
                                                        snprintf(p, p_max_size, "Logfile Empty");
-                                               }  /* if readlines */
+                                               } /* bsize > 0 */
                                        } /*  fp == NULL  */
                                } /* if cur_upd_time >= */
-       
+
                                //parse_conky_vars(obj->data.tail.buffer, p, cur);
 
                        }
                        OBJ(head) {
                                if (current_update_time -obj->data.tail.last_update < obj->data.tail.interval) {
-                                                       snprintf(p, p_max_size, "%s", obj->data.tail.buffer);
+                                       snprintf(p, p_max_size, "%s", obj->data.tail.buffer);
                                } else {
                                        obj->data.tail.last_update = current_update_time;
                                        FILE *fp;
-                                       tailstring *head = NULL;
-                                       tailstring *headtmp = NULL;
-                                       tailstring *freetmp = NULL;
+                                       long nl=0;
+                                       int iter;
                                        fp = fopen(obj->data.tail.logfile, "rt");
                                        if (fp == NULL) {
-                                               ERR("head logfile failed to open");
+                                               /* Send one message, but do not consistently spam on
+                                                * missing logfiles. */
+                                               if(obj->data.tail.readlines != 0) {
+                                                       ERR("head logfile failed to open");
+                                                       strcpy(obj->data.tail.buffer, "Logfile Missing");
+                                               }
+                                               obj->data.tail.readlines = 0;
+                                               snprintf(p, p_max_size, "Logfile Missing");
                                        } else {
                                                obj->data.tail.readlines = 0;
-                                               while (fgets(obj->data.tail.buffer, TEXT_BUFFER_SIZE*20, fp) != NULL && obj->data.tail.readlines <= obj->data.tail.wantedlines) {
-                                                       addtail(&head, obj->data.tail.buffer);
-                                                       obj->data.tail.readlines++;
+                                               for(iter = obj->data.tail.wantedlines; iter > 0; iter--) {
+                                                       nl = fwd_fcharfind(fp, '\n', iter);
+                                                       if(nl >= 0)
+                                                               break;
                                                }
+                                               obj->data.tail.readlines = iter;
+                                               /* Make sure nl is at least 1 byte smaller than
+                                                * the buffer max size. */
+                                               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);
-                                               freetmp = head;
-                                               if (obj->data.tail.readlines > 0) {
-                                                       while (head) {
-                                                               addtail(&headtmp, head->data);
-                                                               head = head->next;
-                                                       }
-                                                       freetail(freetmp);
-                                                       freetmp = headtmp;
-                                                       strcpy(obj->data.tail.buffer, headtmp->data);
-                                                       headtmp = headtmp->next;
-                                                       while (headtmp) {
-                                                               strncat(obj->data.tail.buffer, headtmp->data, (TEXT_BUFFER_SIZE * 20) - strlen(obj->data.tail.buffer)); /* without strlen() at the end this becomes a possible */
-                                                               headtmp = headtmp->next;
+                                               if(nl > 0) {
+                                                       /* Clean up trailing newline, make sure the buffer
+                                                        * is null terminated. */
+                                                       if (obj->data.tail.buffer[nl-1] == '\n') {
+                                                               obj->data.tail.buffer[nl-1] = '\0';
                                                        }
-                                                       freetail(freetmp);
-                                                       /* get rid of any ugly newlines at the end */
-                                                       if (obj->data.tail.buffer[strlen(obj->data.tail.buffer)-1] == '\n') {
-                                                               obj->data.tail.buffer[strlen(obj->data.tail.buffer)-1] = '\0';
+                                                       else {
+                                                               obj->data.tail.buffer[nl] = '\0';
                                                        }
                                                        snprintf(p, p_max_size, "%s", obj->data.tail.buffer);
-                                               } else {
+                                               } 
+                                               else {
                                                        strcpy(obj->data.tail.buffer, "Logfile Empty");
                                                        snprintf(p, p_max_size, "Logfile Empty");
-                                               } /* if readlines > 0 */
+                                               } /* nl > 0 */
                                        } /* if fp == null */
                                } /* cur_upd_time >= */
 
@@ -4781,6 +5269,11 @@ static void generate_text()
        current_update_time = get_time();
 
        update_stuff(cur);
+       /* fix diskio rates to b/s (use update_interval */
+       diskio_read_value = diskio_read_value / update_interval;
+       diskio_write_value = diskio_write_value / update_interval;
+       diskio_value = diskio_value / update_interval;
+       
 
        /* add things to the buffer */
 
@@ -5043,7 +5536,6 @@ static void draw_string(const char *s)
                printf("%s\n", s);
                fflush(stdout);   /* output immediately, don't buffer */
        }
-       /* daemon_run(s);  the daemon can be called here, but we need to have a buffer in daemon_run() and we need to tell it when everything is ready to be sent */
        memset(tmpstring1,0,TEXT_BUFFER_SIZE);
        memset(tmpstring2,0,TEXT_BUFFER_SIZE);
        strncpy(tmpstring1, s, TEXT_BUFFER_SIZE-1);
@@ -5859,22 +6351,41 @@ static void main_loop()
 
                        case ButtonPress:
                                if (own_window)
-                               {
+        {
+          /* if an ordinary window with decorations */
+          if ((window.type==TYPE_NORMAL) && (!TEST_HINT(window.hints,HINT_UNDECORATED)))
+          {
+            /* allow conky to hold input focus.*/
+            break;
+          }
+          else
+                                 {
                                    /* forward the click to the desktop window */
                                    XUngrabPointer(display, ev.xbutton.time);
                                    ev.xbutton.window = window.desktop;
                                    XSendEvent(display, ev.xbutton.window, False, ButtonPressMask, &ev);
-                               }
+            XSetInputFocus(display, ev.xbutton.window,RevertToParent,ev.xbutton.time);
+                                 }
+        }
                                break;
 
                        case ButtonRelease:
-                                if (own_window)
-                                {
-                                    /* forward the release to the desktop window */
-                                    ev.xbutton.window = window.desktop;
-                                    XSendEvent(display, ev.xbutton.window, False, ButtonReleaseMask, &ev);
-                                }
-                                break;
+        if (own_window)
+        {
+          /* if an ordinary window with decorations */
+          if ((window.type==TYPE_NORMAL) && (!TEST_HINT(window.hints,HINT_UNDECORATED)))
+          {
+            /* allow conky to hold input focus.*/
+            break;
+          }
+          else
+          {
+            /* forward the release to the desktop window */
+            ev.xbutton.window = window.desktop;
+            XSendEvent(display, ev.xbutton.window, False, ButtonReleaseMask, &ev);
+          }
+        }
+        break;
 
 #endif
 
@@ -6065,10 +6576,17 @@ 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;
        }
 }
 
@@ -6143,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
@@ -6152,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;
@@ -6166,7 +6697,9 @@ static void set_default_configurations(void)
        own_window = 0;
        window.type=TYPE_NORMAL;
        window.hints=0;
-       strcpy(window.wm_class_name, "conky");  
+  strcpy(window.class_name, "Conky");  
+  update_uname();
+  sprintf(window.title,"%s - conky",info.uname_s.nodename);
 #endif
        stippled_borders = 0;
        border_margin = 3;
@@ -6286,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);
@@ -6341,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);
@@ -6395,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);
@@ -6500,14 +7106,34 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
 #ifdef X11
 #ifdef OWN_WINDOW
                CONF("own_window") {
-                       own_window = string_to_bool(value);
-               }
-               CONF("wm_class_name") {
-                       memset(window.wm_class_name,0,sizeof(window.wm_class_name));
-                       strncpy(window.wm_class_name, value, sizeof(window.wm_class_name)-1);
-               }
+      if (value)
+                         own_window = string_to_bool(value);
+      else
+        CONF_ERR;
+               }
+               CONF("own_window_class") {
+      if (value)
+      {
+                         memset(window.class_name,0,sizeof(window.class_name));
+                         strncpy(window.class_name, value, sizeof(window.class_name)-1);
+      }
+      else 
+        CONF_ERR;
+               }
+    CONF("own_window_title") {
+      if (value)
+      {
+        memset(window.title,0,sizeof(window.title));
+        strncpy(window.title, value, sizeof(window.title)-1);
+      }
+      else
+        CONF_ERR;
+    }
                CONF("own_window_transparent") {
-                       set_transparent = string_to_bool(value);
+      if (value)
+                         set_transparent = string_to_bool(value);
+      else
+        CONF_ERR;
                }
                CONF("own_window_colour") {
                        if (value) {
@@ -6544,6 +7170,8 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
                                }
                                while (p_hint!=NULL);
                        }
+      else
+        CONF_ERR;
                }
                CONF("own_window_type") {
                        if (value) {
@@ -6554,8 +7182,10 @@ else if (strcasecmp(name, a) == 0 || strcasecmp(name, b) == 0)
                                else if (strncmp(value,"override",8)==0)
                                        window.type = TYPE_OVERRIDE;
                                else
-                                       CONF_ERR;
+                                 CONF_ERR;
                        }
+      else
+        CONF_ERR;
                }
 #endif
                CONF("stippled_borders") {
@@ -6598,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);
@@ -6698,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;
                }
@@ -6911,9 +7548,6 @@ int main(int argc, char **argv)
                }
        }
 
-       update_uname();
-
-       generate_text();
 #ifdef X11
        selected_font = 0;
        update_text_area();     /* to get initial size of the window */
@@ -6922,7 +7556,7 @@ int main(int argc, char **argv)
                (own_window,
                 text_width + border_margin * 2 + 1,
                 text_height + border_margin * 2 + 1,
-                set_transparent, background_colour, info.uname_s.nodename, argv, argc);
+                set_transparent, background_colour, argv, argc);
        
        selected_font = 0;
        update_text_area();     /* to position text/window on screen */
@@ -6966,7 +7600,13 @@ int main(int argc, char **argv)
        timed_thread_register (info.audacious.p_timed_thread, &info.audacious.p_timed_thread);
 #endif
 
-       main_loop();
+  /*
+   * ***************
+   * MAIN CONKY LOOP
+   * ***************
+   *
+   */
+  main_loop();
 
 #if defined(__FreeBSD__)
        kvm_close(kd);