the big relocation patch
[monky] / src / conky.c
index 6993452..8edbc24 100644 (file)
 /* #define SIGNAL_BLOCKING */
 #undef SIGNAL_BLOCKING
 
-static void print_version()
+static void print_version(void)
 {
        printf("Conky %s compiled %s for %s\n", VERSION, BUILD_DATE, BUILD_ARCH);
 
        printf("\nCompiled in features:\n\n"
-                  "system config file: %s\n\n"
+                  "System config file: %s\n\n"
 #ifdef X11
                   " X11:\n"
 # ifdef HAVE_XDAMAGE
@@ -127,6 +127,8 @@ static void print_version()
        exit(0);
 }
 
+static const char *suffixes[] = { "B", "kiB", "MiB", "GiB", "TiB", "PiB", "" };
+
 #ifdef X11
 
 /* text size */
@@ -164,8 +166,6 @@ static int selected_font = 0;
 static int font_count = -1;
 struct font_list *fonts = NULL;
 
-static char *suffixes[] = { "B", "kiB", "MiB", "GiB", "TiB", "PiB", "" };
-
 #ifdef XFT
 
 #define font_height() (use_xft ? (fonts[selected_font].xftfont->ascent + \
@@ -188,7 +188,7 @@ static char *suffixes[] = { "B", "kiB", "MiB", "GiB", "TiB", "PiB", "" };
 
 #define MAX_FONTS 64 // hmm, no particular reason, just makes sense.
 
-static void set_font();
+static void set_font(void);
 
 int addfont(const char *data_in)
 {
@@ -207,14 +207,13 @@ int addfont(const char *data_in)
                memset(fonts, 0, sizeof(struct font_list));
        }
        fonts = realloc(fonts, (sizeof(struct font_list) * (font_count + 1)));
-       memset(fonts + (sizeof(struct font_list) * font_count), 0, sizeof(struct font_list));
+       memset(&fonts[font_count], 0, sizeof(struct font_list));
        if (fonts == NULL) {
                CRIT_ERR("realloc in addfont");
        }
        // must account for null terminator
        if (strlen(data_in) < DEFAULT_TEXT_BUFFER_SIZE) {
                strncpy(fonts[font_count].name, data_in, DEFAULT_TEXT_BUFFER_SIZE);
-               printf("adding font %s\n", fonts[font_count].name);
 #ifdef XFT
                fonts[font_count].font_alpha = 0xffff;
 #endif
@@ -242,7 +241,7 @@ void set_first_font(const char *data_in)
        }
 }
 
-void free_fonts()
+void free_fonts(void)
 {
        int i;
 
@@ -264,26 +263,22 @@ void free_fonts()
        selected_font = 0;
 }
 
-static void load_fonts()
+static void load_fonts(void)
 {
        int i;
 
        for (i = 0; i <= font_count; i++) {
 #ifdef XFT
                /* load Xft font */
-/*             if (use_xft && fonts[i].xftfont) {
+               if (use_xft && fonts[i].xftfont) {
                        continue;
-               } else*/ if (use_xft) {
+               } else if (use_xft) {
                        /* if (fonts[i].xftfont != NULL && selected_font == 0) {
                                XftFontClose(display, fonts[i].xftfont);
                        } */
-                       if (fonts[i].xftfont) {
-                               printf("lol, %i\n", fonts[i].xftfont);
-                       }
                        fonts[i].xftfont = XftFontOpenName(display, screen,
                                        fonts[i].name);
                        if (fonts[i].xftfont != NULL) {
-                               printf("loaded %s, %i\n", fonts[i].name, font_count);
                                continue;
                        }
 
@@ -308,7 +303,7 @@ static void load_fonts()
                        XFreeFont(display, fonts[i].font);
                } */
 
-               if ((fonts[i].font = XLoadQueryFont(display, fonts[i].name)) == NULL) {
+               if (fonts[i].font || (fonts[i].font = XLoadQueryFont(display, fonts[i].name)) == NULL) {
                        ERR("can't load font '%s'", fonts[i].name);
                        if ((fonts[i].font = XLoadQueryFont(display, "fixed")) == NULL) {
                                CRIT_ERR("can't load font '%s'", "fixed");
@@ -381,9 +376,7 @@ static unsigned int max_specials = MAX_SPECIALS_DEFAULT;
 static unsigned int max_user_text = MAX_USER_TEXT_DEFAULT;
 
 /* maximum size of individual text buffers, ie $exec buffer size */
-unsigned int small_text_buffer_size = DEFAULT_TEXT_BUFFER_SIZE;
-unsigned int large_text_buffer_size = DEFAULT_TEXT_BUFFER_SIZE * 8;
-unsigned int p_p_max_size = DEFAULT_TEXT_BUFFER_SIZE * 8; // sorry I couldn't come up with a better var name
+unsigned int text_buffer_size = DEFAULT_TEXT_BUFFER_SIZE;
 
 #ifdef HAVE_ICONV
 #define CODEPAGE_LENGTH 20
@@ -483,10 +476,10 @@ static inline int calc_text_width(const char *s, int l)
 
                if (utf8_mode) {
                        XftTextExtentsUtf8(display, fonts[selected_font].xftfont,
-                               (FcChar8 *) s, l, &gi);
+                               (const FcChar8 *) s, l, &gi);
                } else {
                        XftTextExtents8(display, fonts[selected_font].xftfont,
-                               (FcChar8 *) s, l, &gi);
+                               (const FcChar8 *) s, l, &gi);
                }
                return gi.xOff;
        } else
@@ -714,10 +707,11 @@ static void new_font(char *buf, char *args)
 
 inline void graph_append(struct special_t *graph, double f)
 {
+       int i;
+
        if (!graph->scaled && f > graph->graph_scale) {
                f = graph->graph_scale;
        }
-       int i;
 
        if (graph->scaled) {
                graph->graph_scale = 1;
@@ -734,7 +728,7 @@ inline void graph_append(struct special_t *graph, double f)
 }
 
 short colour_depth = 0;
-void set_up_gradient();
+void set_up_gradient(void);
 
 /* precalculated: 31/255, and 63/255 */
 #define CONST_8_TO_5_BITS 0.12156862745098
@@ -811,7 +805,7 @@ static char *scan_graph(const char *args, int *w, int *h,
        *scale = 0;
        /* graph's argument is either height or height,width */
        if (args) {
-               if (sscanf(args, "%d,%d %x %x %i", h, w, first_colour, last_colour,
+               if (sscanf(args, "%d,%d %x %x %u", h, w, first_colour, last_colour,
                                scale) == 5) {
                        return NULL;
                }
@@ -819,7 +813,7 @@ static char *scan_graph(const char *args, int *w, int *h,
                if (sscanf(args, "%d,%d %x %x", h, w, first_colour, last_colour) == 4) {
                        return NULL;
                }
-               if (sscanf(args, "%63s %d,%d %x %x %i", buf, h, w, first_colour,
+               if (sscanf(args, "%63s %d,%d %x %x %u", buf, h, w, first_colour,
                                last_colour, scale) == 6) {
                        return strdup(buf);
                }
@@ -831,14 +825,14 @@ static char *scan_graph(const char *args, int *w, int *h,
                buf[0] = '\0';
                *h = 25;
                *w = 0;
-               if (sscanf(args, "%x %x %i", first_colour, last_colour, scale) == 3) {
+               if (sscanf(args, "%x %x %u", first_colour, last_colour, scale) == 3) {
                        return NULL;
                }
                *scale = 0;
                if (sscanf(args, "%x %x", first_colour, last_colour) == 2) {
                        return NULL;
                }
-               if (sscanf(args, "%63s %x %x %i", buf, first_colour, last_colour,
+               if (sscanf(args, "%63s %x %x %u", buf, first_colour, last_colour,
                                scale) == 4) {
                        return strdup(buf);
                }
@@ -849,14 +843,14 @@ static char *scan_graph(const char *args, int *w, int *h,
                buf[0] = '\0';
                *first_colour = 0;
                *last_colour = 0;
-               if (sscanf(args, "%d,%d %i", h, w, scale) == 3) {
+               if (sscanf(args, "%d,%d %u", h, w, scale) == 3) {
                        return NULL;
                }
                *scale = 0;
                if (sscanf(args, "%d,%d", h, w) == 2) {
                        return NULL;
                }
-               if (sscanf(args, "%63s %d,%d %i", buf, h, w, scale) < 4) {
+               if (sscanf(args, "%63s %d,%d %u", buf, h, w, scale) < 4) {
                        *scale = 0;
                        //TODO: check the return value and throw an error?
                        sscanf(args, "%63s %d,%d", buf, h, w);
@@ -976,11 +970,16 @@ static void convert_escapes(char *buf)
 /* Prints anything normally printed with snprintf according to the current value
  * of use_spacer.  Actually slightly more flexible than snprintf, as you can
  * safely specify the destination buffer as one of your inputs.  */
-static int spaced_print(char *buf, int size, char *format, int width,
-               char *func_name, ...) {
+static int spaced_print(char *buf, int size, const char *format, int width,
+               const char *func_name, ...) {
        int len;
        va_list argp;
-       char *tempbuf = malloc(size * sizeof(char));
+       char *tempbuf;
+
+       if (size < 1) {
+               return 0;
+       }
+       tempbuf = malloc(size * sizeof(char));
 
        // Passes the varargs along to vsnprintf
        va_start(argp, func_name);
@@ -992,10 +991,10 @@ static int spaced_print(char *buf, int size, char *format, int width,
                        len = snprintf(buf, size, "%s", tempbuf);
                        break;
                case LEFT_SPACER:
-                       len = snprintf(buf, width, "%*s", width - 1, tempbuf);
+                       len = snprintf(buf, size, "%*s", width - 1, tempbuf);
                        break;
                case RIGHT_SPACER:
-                       len = snprintf(buf, width, "%-*s", width - 1, tempbuf);
+                       len = snprintf(buf, size, "%-*s", width - 1, tempbuf);
                        break;
                default:
                        CRIT_ERR("%s encountered invalid use_spacer value (%d)", func_name,
@@ -1008,9 +1007,9 @@ static int spaced_print(char *buf, int size, char *format, int width,
 }
 
 /* converts from bytes to human readable format (k, M, G, T) */
-static void human_readable(long long num, char *buf, int size, char *func_name)
+static void human_readable(long long num, char *buf, int size, const char *func_name)
 {
-       char **suffix = suffixes;
+       const char **suffix = suffixes;
        float fnum;
        int precision, len;
        static const int WIDTH = 10, SHORT_WIDTH = 8;
@@ -1107,6 +1106,8 @@ enum text_object_type {
        OBJ_execgraph,
        OBJ_execibar,
        OBJ_execigraph,
+       OBJ_execp,
+       OBJ_execpi,
        OBJ_freq,
        OBJ_freq_g,
        OBJ_freq_dyn,
@@ -1130,6 +1131,7 @@ enum text_object_type {
        OBJ_platform,
        OBJ_hwmon,
 #if defined(__linux__)
+       OBJ_disk_protect,
        OBJ_i8k_version,
        OBJ_i8k_bios,
        OBJ_i8k_serial,
@@ -1146,6 +1148,11 @@ enum text_object_type {
        OBJ_ibm_volume,
        OBJ_ibm_brightness,
        OBJ_if_up,
+       OBJ_if_gw,
+       OBJ_ioscheduler,
+       OBJ_gw_iface,
+       OBJ_gw_ip,
+       OBJ_laptop_mode,
        OBJ_pb_battery,
        OBJ_voltage_mv,
        OBJ_voltage_v,
@@ -1182,6 +1189,7 @@ enum text_object_type {
        OBJ_mixerbar,
        OBJ_mixerlbar,
        OBJ_mixerrbar,
+       OBJ_nameserver,
        OBJ_new_mails,
        OBJ_nodename,
        OBJ_pre_exec,
@@ -1446,8 +1454,8 @@ struct text_object_list {
        struct text_object *text_objects;
 };
 
-static unsigned int text_object_count;
-static struct text_object *text_objects;
+static unsigned int global_text_object_count;
+static struct text_object *global_text_objects;
 static void generate_text_internal(char *p, int p_max_size,
        struct text_object *objs, unsigned int object_count,
        struct information *cur);
@@ -1459,9 +1467,10 @@ static void generate_text_internal(char *p, int p_max_size,
 struct mail_s *parse_mail_args(char type, const char *arg)
 {
        struct mail_s *mail;
+       char *tmp;
+
        mail = malloc(sizeof(struct mail_s));
        memset(mail, 0, sizeof(struct mail_s));
-       char *tmp;
 
        if (sscanf(arg, "%128s %128s %128s", mail->host, mail->user, mail->pass)
                        != 3) {
@@ -1515,8 +1524,8 @@ struct mail_s *parse_mail_args(char type, const char *arg)
        }
        tmp = strstr(arg, "-e ");
        if (tmp) {
-               tmp += 3;
                int len = 1024;
+               tmp += 3;
 
                if (tmp[0] == '\'') {
                        len = strstr(tmp + 1, "'") - tmp - 1;
@@ -1532,7 +1541,7 @@ struct mail_s *parse_mail_args(char type, const char *arg)
        return mail;
 }
 
-void *imap_thread(struct mail_s *mail)
+void *imap_thread(void *arg)
 {
        int sockfd, numbytes;
        char recvbuf[MAXDATASIZE];
@@ -1544,12 +1553,17 @@ void *imap_thread(struct mail_s *mail)
        struct stat stat_buf;
        struct hostent *he;
        struct sockaddr_in their_addr;  // connector's address information
+       struct mail_s *mail = (struct mail_s *)arg;
 
        if ((he = gethostbyname(mail->host)) == NULL) { // get the host info
                herror("gethostbyname");
                exit(1);
        }
        while (fail < 5) {
+               struct timeval timeout;
+               int res;
+               fd_set fdset;
+
                if (fail > 0) {
                        ERR("Trying IMAP connection again for %s@%s (try %i/5)",
                                mail->user, mail->host, fail + 1);
@@ -1574,9 +1588,6 @@ void *imap_thread(struct mail_s *mail)
                        fail++;
                        goto next_iteration;
                }
-               struct timeval timeout;
-               int res;
-               fd_set fdset;
 
                timeout.tv_sec = 60;    // 60 second timeout i guess
                timeout.tv_usec = 0;
@@ -1604,7 +1615,7 @@ void *imap_thread(struct mail_s *mail)
                strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1);
                strncat(sendbuf, " ", MAXDATASIZE - strlen(sendbuf) - 1);
                strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1);
-               strncat(sendbuf, "\n", MAXDATASIZE - strlen(sendbuf) - 1);
+               strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1);
                if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
                        perror("send a1");
                        fail++;
@@ -1630,7 +1641,7 @@ void *imap_thread(struct mail_s *mail)
                }
                strncpy(sendbuf, "a2 STATUS ", MAXDATASIZE);
                strncat(sendbuf, mail->folder, MAXDATASIZE - strlen(sendbuf) - 1);
-               strncat(sendbuf, " (MESSAGES UNSEEN)\n",
+               strncat(sendbuf, " (MESSAGES UNSEEN)\r\n",
                        MAXDATASIZE - strlen(sendbuf) - 1);
                if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
                        perror("send a2");
@@ -1669,7 +1680,7 @@ void *imap_thread(struct mail_s *mail)
                                &mail->unseen);
                        timed_thread_unlock(mail->p_timed_thread);
                }
-               strncpy(sendbuf, "a3 logout\n", MAXDATASIZE);
+               strncpy(sendbuf, "a3 logout\r\n", MAXDATASIZE);
                if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
                        perror("send a3");
                        fail++;
@@ -1717,7 +1728,7 @@ next_iteration:
        return 0;
 }
 
-void *pop3_thread(struct mail_s *mail)
+void *pop3_thread(void *arg)
 {
        int sockfd, numbytes;
        char recvbuf[MAXDATASIZE];
@@ -1728,12 +1739,17 @@ void *pop3_thread(struct mail_s *mail)
        struct stat stat_buf;
        struct hostent *he;
        struct sockaddr_in their_addr;  // connector's address information
+       struct mail_s *mail = (struct mail_s *)arg;
 
        if ((he = gethostbyname(mail->host)) == NULL) { // get the host info
                herror("gethostbyname");
                exit(1);
        }
        while (fail < 5) {
+               struct timeval timeout;
+               int res;
+               fd_set fdset;
+
                if (fail > 0) {
                        ERR("Trying POP3 connection again for %s@%s (try %i/5)",
                                mail->user, mail->host, fail + 1);
@@ -1758,9 +1774,6 @@ void *pop3_thread(struct mail_s *mail)
                        fail++;
                        goto next_iteration;
                }
-               struct timeval timeout;
-               int res;
-               fd_set fdset;
 
                timeout.tv_sec = 60;    // 60 second timeout i guess
                timeout.tv_usec = 0;
@@ -1786,7 +1799,7 @@ void *pop3_thread(struct mail_s *mail)
                }
                strncpy(sendbuf, "USER ", MAXDATASIZE);
                strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1);
-               strncat(sendbuf, "\n", MAXDATASIZE - strlen(sendbuf) - 1);
+               strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1);
                if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
                        perror("send USER");
                        fail++;
@@ -1812,7 +1825,7 @@ void *pop3_thread(struct mail_s *mail)
                }
                strncpy(sendbuf, "PASS ", MAXDATASIZE);
                strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1);
-               strncat(sendbuf, "\n", MAXDATASIZE - strlen(sendbuf) - 1);
+               strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1);
                if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
                        perror("send PASS");
                        fail++;
@@ -1836,7 +1849,7 @@ void *pop3_thread(struct mail_s *mail)
                        fail++;
                        goto next_iteration;
                }
-               strncpy(sendbuf, "STAT\n", MAXDATASIZE);
+               strncpy(sendbuf, "STAT\r\n", MAXDATASIZE);
                if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
                        perror("send STAT");
                        fail++;
@@ -1871,7 +1884,7 @@ void *pop3_thread(struct mail_s *mail)
                        sscanf(reply, "%lu %lu", &mail->unseen, &mail->used);
                        timed_thread_unlock(mail->p_timed_thread);
                }
-               strncpy(sendbuf, "QUIT\n", MAXDATASIZE);
+               strncpy(sendbuf, "QUIT\r\n", MAXDATASIZE);
                if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
                        perror("send QUIT");
                        fail++;
@@ -1917,14 +1930,18 @@ next_iteration:
        return 0;
 }
 
-void *threaded_exec(struct text_object *obj)
+void *threaded_exec(void *arg)
 {
+       FILE *fp;
+       char *p2;
+       int n2;
+       struct text_object *obj = (struct text_object *)arg;
        while (1) {
-               char *p2 = obj->data.texeci.buffer;
-               FILE *fp = popen(obj->data.texeci.cmd, "r");
+               p2 = obj->data.texeci.buffer;
+               fp = popen(obj->data.texeci.cmd, "r");
 
                timed_thread_lock(obj->data.texeci.p_timed_thread);
-               int n2 = fread(p2, 1, small_text_buffer_size, fp);
+               n2 = fread(p2, 1, text_buffer_size, fp);
 
                pclose(fp);
                p2[n2] = '\0';
@@ -1945,7 +1962,7 @@ void *threaded_exec(struct text_object *obj)
        return 0;
 }
 
-static struct text_object *new_text_object_internal()
+static struct text_object *new_text_object_internal(void)
 {
        struct text_object *obj = malloc(sizeof(struct text_object));
        memset(obj, 0, sizeof(struct text_object));
@@ -1960,24 +1977,16 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                switch (objs[i].type) {
 #ifndef __OpenBSD__
                        case OBJ_acpitemp:
-                               close(objs[i].data.i);
-                               break;
                        case OBJ_acpitempf:
                                close(objs[i].data.i);
                                break;
                        case OBJ_i2c:
-                               close(objs[i].data.sysfs.fd);
-                               break;
                        case OBJ_platform:
-                               close(objs[i].data.sysfs.fd);
-                               break;
                        case OBJ_hwmon:
                                close(objs[i].data.sysfs.fd);
                                break;
 #endif /* !__OpenBSD__ */
                        case OBJ_time:
-                               free(objs[i].data.s);
-                               break;
                        case OBJ_utime:
                                free(objs[i].data.s);
                                break;
@@ -2032,36 +2041,44 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                                break;
                        case OBJ_text:
                        case OBJ_font:
-                               free(objs[i].data.s);
-                               break;
                        case OBJ_image:
-                               free(objs[i].data.s);
-                               break;
                        case OBJ_exec:
-                               free(objs[i].data.s);
-                               break;
                        case OBJ_execbar:
-                               free(objs[i].data.s);
-                               break;
                        case OBJ_execgraph:
+                       case OBJ_execp:
                                free(objs[i].data.s);
                                break;
-                       /* case OBJ_execibar:
-                               free(objs[i].data.s);
-                               break;
-                       case OBJ_execigraph:
-                               free(objs[i].data.s);
-                               break; */
 #ifdef HAVE_ICONV
                        case OBJ_iconv_start:
                                free_iconv();
                                break;
 #endif
 #ifdef __LINUX__
+                       case OBJ_disk_protect:
+                               free(objs[i].data.s);
+                               break;
                        case OBJ_if_up:
                                free(objs[i].data.ifblock.s);
                                free(objs[i].data.ifblock.str);
                                break;
+                       case OBJ_if_gw:
+                               free(objs[i].data.ifblock.s);
+                               free(objs[i].data.ifblock.str);
+                       case OBJ_gw_iface:
+                       case OBJ_gw_ip:
+                               if (info.gw_info.iface) {
+                                       free(info.gw_info.iface);
+                                       info.gw_info.iface = 0;
+                               }
+                               if (info.gw_info.ip) {
+                                       free(info.gw_info.ip);
+                                       info.gw_info.ip = 0;
+                               }
+                               break;
+                       case OBJ_ioscheduler:
+                               if(objs[i].data.s)
+                                       free(objs[i].data.s);
+                               break;
 #endif
 #ifdef XMMS2
                        case OBJ_xmms2_artist:
@@ -2158,7 +2175,10 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                                free(objs[i].data.s);
                                break;
 #endif /* !__OpenBSD__ */
+                       case OBJ_execpi:
                        case OBJ_execi:
+                       case OBJ_execibar:
+                       case OBJ_execigraph:
                                free(objs[i].data.execi.cmd);
                                free(objs[i].data.execi.buffer);
                                break;
@@ -2166,12 +2186,10 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                                free(objs[i].data.texeci.cmd);
                                free(objs[i].data.texeci.buffer);
                                break;
-                       case OBJ_top:
-                               if (info.first_process) {
-                                       free_all_processes();
-                                       info.first_process = NULL;
-                               }
+                       case OBJ_nameserver:
+                               free_dns_data();
                                break;
+                       case OBJ_top:
                        case OBJ_top_mem:
                                if (info.first_process) {
                                        free_all_processes();
@@ -2206,26 +2224,44 @@ static void free_text_objects(unsigned int count, struct text_object *objs)
                                        info.users.times = 0;
                                }
                                break;
+#ifdef SMAPI
+                       case OBJ_smapi:
+                       case OBJ_smapi_bat_perc:
+                               free(objs[i].data.s);
+                               break;
+                       case OBJ_if_smapi_bat_installed:
+                               free(objs[i].data.ifblock.s);
+                               free(objs[i].data.ifblock.str);
+                               break;
+#endif
+#ifdef MPD
+                       case OBJ_mpd_title:
+                       case OBJ_mpd_artist:
+                       case OBJ_mpd_album:
+                       case OBJ_mpd_random:
+                       case OBJ_mpd_repeat:
+                       case OBJ_mpd_vol:
+                       case OBJ_mpd_bitrate:
+                       case OBJ_mpd_status:
+                       case OBJ_mpd_host:
+                       case OBJ_mpd_port:
+                       case OBJ_mpd_password:
+                       case OBJ_mpd_bar:
+                       case OBJ_mpd_elapsed:
+                       case OBJ_mpd_length:
+                       case OBJ_mpd_track:
+                       case OBJ_mpd_name:
+                       case OBJ_mpd_file:
+                       case OBJ_mpd_percent:
+                       case OBJ_mpd_smart:
+                               free_mpd_vars(&info);
+                               break;
+#endif
                }
        }
        free(objs);
-#ifdef MPD
-       free_mpd_vars(&info);
-#endif
        /* text_objects = NULL;
           text_object_count = 0; */
-       if (tmpstring1) {
-               free(tmpstring1);
-               tmpstring1 = 0;
-       }
-       if (tmpstring2) {
-               free(tmpstring2);
-               tmpstring2 = 0;
-       }
-       if (text_buffer) {
-               free(text_buffer);
-               text_buffer = 0;
-       }
 }
 
 void scan_mixer_bar(const char *arg, int *a, int *w, int *h)
@@ -2404,7 +2440,7 @@ static struct text_object *construct_text_object(const char *s,
                obj->data.s = strdup(bat);
        END OBJ(battery_bar, 0)
                char bat[64];
-
+               obj->b = 6;
                if (arg) {
                        arg = scan_bar(arg, &obj->a, &obj->b);
                        sscanf(arg, "%63s", bat);
@@ -2415,6 +2451,11 @@ static struct text_object *construct_text_object(const char *s,
 #endif /* !__OpenBSD__ */
 
 #if defined(__linux__)
+       END OBJ(disk_protect, 0)
+               if (arg)
+                       obj->data.s = strdup(arg);
+               else
+                       CRIT_ERR("disk_protect needs an argument");
        END OBJ(i8k_version, INFO_I8K)
        END OBJ(i8k_bios, INFO_I8K)
        END OBJ(i8k_serial, INFO_I8K)
@@ -2451,6 +2492,20 @@ static struct text_object *construct_text_object(const char *s,
                blockstart[blockdepth] = object_count;
                obj->data.ifblock.pos = object_count + 2;
                blockdepth++;
+       END OBJ(if_gw, 0)
+               if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
+                       CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
+               }
+               blockstart[blockdepth] = object_count;
+               obj->data.ifblock.pos = object_count + 2;
+               blockdepth++;
+       END OBJ(ioscheduler, 0)
+               if (!arg) {
+                       CRIT_ERR("get_ioscheduler needs an argument (e.g. hda)");
+                       obj->data.s = 0;
+               } else
+                       obj->data.s = strdup(arg);
+       END OBJ(laptop_mode, 0)
        END OBJ(pb_battery, 0)
                if (arg && strcmp(arg, "status") == 0) {
                        obj->data.i = PB_BATT_STATUS;
@@ -2658,12 +2713,14 @@ static struct text_object *construct_text_object(const char *s,
 #ifdef HAVE_POPEN
        END OBJ(exec, 0)
                obj->data.s = strdup(arg ? arg : "");
+       END OBJ(execp, 0)
+               obj->data.s = strdup(arg ? arg : "");
        END OBJ(execbar, 0)
                obj->data.s = strdup(arg ? arg : "");
        END OBJ(execgraph, 0)
                obj->data.s = strdup(arg ? arg : "");
        END OBJ(execibar, 0)
-               unsigned int n;
+               int n;
 
                if (!arg || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
                        char buf[256];
@@ -2676,7 +2733,7 @@ static struct text_object *construct_text_object(const char *s,
                        obj->data.execi.cmd = strdup(arg + n);
                }
        END OBJ(execigraph, 0)
-               unsigned int n;
+               int n;
 
                if (!arg || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
                        char buf[256];
@@ -2689,7 +2746,21 @@ static struct text_object *construct_text_object(const char *s,
                        obj->data.execi.cmd = strdup(arg + n);
                }
        END OBJ(execi, 0)
-               unsigned int n;
+               int n;
+
+               if (!arg || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
+                       char buf[256];
+
+                       ERR("${execi <interval> command}");
+                       obj->type = OBJ_text;
+                       snprintf(buf, 256, "${%s}", s);
+                       obj->data.s = strdup(buf);
+               } else {
+                       obj->data.execi.cmd = strdup(arg + n);
+                       obj->data.execi.buffer = malloc(text_buffer_size);
+               }
+       END OBJ(execpi, 0)
+               int n;
 
                if (!arg || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
                        char buf[256];
@@ -2700,10 +2771,10 @@ static struct text_object *construct_text_object(const char *s,
                        obj->data.s = strdup(buf);
                } else {
                        obj->data.execi.cmd = strdup(arg + n);
-                       obj->data.execi.buffer = (char *) calloc(1, small_text_buffer_size);
+                       obj->data.execi.buffer = malloc(text_buffer_size);
                }
        END OBJ(texeci, 0)
-               unsigned int n;
+               int n;
 
                if (!arg || sscanf(arg, "%f %n", &obj->data.texeci.interval, &n) <= 0) {
                        char buf[256];
@@ -2714,7 +2785,7 @@ static struct text_object *construct_text_object(const char *s,
                        obj->data.s = strdup(buf);
                } else {
                        obj->data.texeci.cmd = strdup(arg + n);
-                       obj->data.texeci.buffer = (char *) calloc(1, small_text_buffer_size);
+                       obj->data.texeci.buffer = malloc(text_buffer_size);
                }
                obj->data.texeci.p_timed_thread = NULL;
        END OBJ(pre_exec, 0)
@@ -2739,7 +2810,6 @@ static struct text_object *construct_text_object(const char *s,
                }
 #endif
        END OBJ(fs_bar, INFO_FS)
-               obj->data.fsbar.h = 4;
                arg = scan_bar(arg, &obj->data.fsbar.w, &obj->data.fsbar.h);
                if (arg) {
                        while (isspace(*arg)) {
@@ -2753,16 +2823,18 @@ static struct text_object *construct_text_object(const char *s,
                }
                obj->data.fsbar.fs = prepare_fs_stat(arg);
        END OBJ(fs_bar_free, INFO_FS)
-               obj->data.fsbar.h = 4;
+               arg = scan_bar(arg, &obj->data.fsbar.w, &obj->data.fsbar.h);
                if (arg) {
-                       unsigned int n;
-
-                       if (sscanf(arg, "%d %n", &obj->data.fsbar.h, &n) >= 1) {
-                               arg += n;
+                       while (isspace(*arg)) {
+                               arg++;
+                       }
+                       if (*arg == '\0') {
+                               arg = "/";
                        }
                } else {
                        arg = "/";
                }
+
                obj->data.fsbar.fs = prepare_fs_stat(arg);
        END OBJ(fs_free, INFO_FS)
                if (!arg) {
@@ -2796,6 +2868,8 @@ static struct text_object *construct_text_object(const char *s,
                obj->data.fs = prepare_fs_stat(arg);
        END OBJ(hr, 0)
                obj->data.i = arg ? atoi(arg) : 1;
+       END OBJ(nameserver, INFO_DNS)
+               obj->data.i = arg ? atoi(arg) : 0;
        END OBJ(offset, 0)
                obj->data.i = arg ? atoi(arg) : 1;
        END OBJ(voffset, 0)
@@ -3021,7 +3095,7 @@ static struct text_object *construct_text_object(const char *s,
                                }
 
                                if (fp || obj->data.tail.fd != -1) {
-                                       obj->data.tail.logfile = malloc(small_text_buffer_size);
+                                       obj->data.tail.logfile = malloc(text_buffer_size);
                                        strcpy(obj->data.tail.logfile, buf);
                                        obj->data.tail.wantedlines = n1;
                                        obj->data.tail.interval = update_interval * 2;
@@ -3066,7 +3140,7 @@ static struct text_object *construct_text_object(const char *s,
                                }
 
                                if (fp || obj->data.tail.fd != -1) {
-                                       obj->data.tail.logfile = malloc(small_text_buffer_size);
+                                       obj->data.tail.logfile = malloc(text_buffer_size);
                                        strcpy(obj->data.tail.logfile, buf);
                                        obj->data.tail.wantedlines = n1;
                                        obj->data.tail.interval = n2;
@@ -3085,7 +3159,7 @@ static struct text_object *construct_text_object(const char *s,
                        return NULL;
                }
                /* asumming all else worked */
-               obj->data.tail.buffer = malloc(small_text_buffer_size * 20);
+               obj->data.tail.buffer = malloc(text_buffer_size * 20);
        END OBJ(head, 0)
                char buf[64];
                int n1, n2;
@@ -3106,7 +3180,7 @@ static struct text_object *construct_text_object(const char *s,
 
                                fp = fopen(buf, "r");
                                if (fp != NULL) {
-                                       obj->data.tail.logfile = malloc(small_text_buffer_size);
+                                       obj->data.tail.logfile = malloc(text_buffer_size);
                                        strcpy(obj->data.tail.logfile, buf);
                                        obj->data.tail.wantedlines = n1;
                                        obj->data.tail.interval = update_interval * 2;
@@ -3131,7 +3205,7 @@ static struct text_object *construct_text_object(const char *s,
 
                                fp = fopen(buf, "r");
                                if (fp != NULL) {
-                                       obj->data.tail.logfile = malloc(small_text_buffer_size);
+                                       obj->data.tail.logfile = malloc(text_buffer_size);
                                        strcpy(obj->data.tail.logfile, buf);
                                        obj->data.tail.wantedlines = n1;
                                        obj->data.tail.interval = n2;
@@ -3147,7 +3221,7 @@ static struct text_object *construct_text_object(const char *s,
                        return NULL;
                }
                /* asumming all else worked */
-               obj->data.tail.buffer = malloc(small_text_buffer_size * 20);
+               obj->data.tail.buffer = malloc(text_buffer_size * 20);
        END OBJ(loadavg, INFO_LOADAVG)
                int a = 1, b = 2, c = 3, r = 3;
 
@@ -3251,11 +3325,11 @@ static struct text_object *construct_text_object(const char *s,
                obj->data.local_mail.box = strdup(dst);
                obj->data.local_mail.interval = n1;
        END OBJ(mboxscan, 0)
-               obj->data.mboxscan.args = (char *) malloc(small_text_buffer_size);
-               obj->data.mboxscan.output = (char *) malloc(small_text_buffer_size);
+               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, small_text_buffer_size);
+               strncpy(obj->data.mboxscan.args, arg, text_buffer_size);
        END OBJ(mem, INFO_MEM)
        END OBJ(memmax, INFO_MEM)
        END OBJ(memperc, INFO_MEM)
@@ -3438,6 +3512,9 @@ static struct text_object *construct_text_object(const char *s,
        END OBJ(user_times, INFO_USERS)
        END OBJ(user_terms, INFO_USERS)
        END OBJ(user_number, INFO_USERS)
+       END OBJ(gw_iface, INFO_GW)
+       END OBJ(gw_ip, INFO_GW)
+       END OBJ(if_gw, INFO_GW)
 #ifndef __OpenBSD__
        END OBJ(adt746xcpu, 0)
        END OBJ(adt746xfan, 0)
@@ -3490,14 +3567,14 @@ static struct text_object *construct_text_object(const char *s,
                if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
                        CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
                }
-       if (!arg) {
-               ERR("if_smapi_bat_installed 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++;
+               if (!arg) {
+                       ERR("if_smapi_bat_installed 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(smapi_bat_perc, 0)
                if (arg)
                        obj->data.s = strdup(arg);
@@ -3753,24 +3830,28 @@ static struct text_object *create_plain_text(const char *s)
        return obj;
 }
 
-static struct text_object_list *extract_variable_text_internal(const char *p)
+static struct text_object_list *extract_variable_text_internal(const char *const_p)
 {
        struct text_object_list *retval;
        struct text_object *obj;
-       const char *s = p;
+       char *p, *s, *orig_p;
+       long line;
+
+       p = strdup(const_p);
+       s = orig_p = p;
 
        retval = malloc(sizeof(struct text_object_list));
        memset(retval, 0, sizeof(struct text_object_list));
        retval->text_object_count = 0;
 
-       long line = text_lines;
+       line = text_lines;
 
        while (*p) {
                if (*p == '\n') {
                        line++;
                }
                if (*p == '$') {
-                       *(char *) p = '\0';
+                       *p = '\0';
                        obj = create_plain_text(s);
                        if (obj != NULL) {
                                // allocate memory for the object
@@ -3782,7 +3863,7 @@ static struct text_object_list *extract_variable_text_internal(const char *p)
                                        sizeof(struct text_object));
                                free(obj);
                        }
-                       *(char *) p = '$';
+                       *p = '$';
                        p++;
                        s = p;
 
@@ -3831,7 +3912,7 @@ static struct text_object_list *extract_variable_text_internal(const char *p)
 
                                /* if variable wasn't found in environment, use some special */
                                if (!var) {
-                                       char *p;
+                                       char *tmp_p;
                                        char *arg = 0;
 
                                        /* split arg */
@@ -3848,10 +3929,10 @@ static struct text_object_list *extract_variable_text_internal(const char *p)
                                        }
 
                                        /* lowercase variable name */
-                                       p = buf;
-                                       while (*p) {
-                                               *p = tolower(*p);
-                                               p++;
+                                       tmp_p = buf;
+                                       while (*tmp_p) {
+                                               *tmp_p = tolower(*tmp_p);
+                                               tmp_p++;
                                        }
 
                                        // create new object
@@ -3901,6 +3982,7 @@ static struct text_object_list *extract_variable_text_internal(const char *p)
                ERR("one or more $endif's are missing");
        }
 
+       free(orig_p);
        return retval;
 }
 
@@ -3908,25 +3990,37 @@ static void extract_variable_text(const char *p)
 {
        struct text_object_list *list;
 
-       free_text_objects(text_object_count, text_objects);
-       text_object_count = 0;
-       text_objects = NULL;
+       free_text_objects(global_text_object_count, global_text_objects);
+       if (tmpstring1) {
+               free(tmpstring1);
+               tmpstring1 = 0;
+       }
+       if (tmpstring2) {
+               free(tmpstring2);
+               tmpstring2 = 0;
+       }
+       if (text_buffer) {
+               free(text_buffer);
+               text_buffer = 0;
+       }
+       global_text_object_count = 0;
+       global_text_objects = NULL;
 
        list = extract_variable_text_internal(p);
-       text_objects = list->text_objects;
-       text_object_count = list->text_object_count;
+       global_text_objects = list->text_objects;
+       global_text_object_count = list->text_object_count;
 
        free(list);
 }
 
-void parse_conky_vars(char *text, char *p, struct information *cur)
+struct text_object_list *parse_conky_vars(char *text, char *p, struct information *cur)
 {
        struct text_object_list *object_list =
                extract_variable_text_internal(text);
 
-       generate_text_internal(p, p_p_max_size, object_list->text_objects,
+       generate_text_internal(p, max_user_text, object_list->text_objects,
                object_list->text_object_count, cur);
-       free(object_list);
+       return object_list;
 }
 
 /* Allows reading from a FIFO (i.e., /dev/xconsole).
@@ -4065,6 +4159,10 @@ static void generate_text_internal(char *p, int p_max_size,
        for (i = 0; i < object_count; i++) {
                struct text_object *obj = &objs[i];
 
+               if (p_max_size < 1) {
+                       break;
+               };
+
 #define OBJ(a) break; case OBJ_##a:
 
                switch (obj->type) {
@@ -4188,8 +4286,8 @@ static void generate_text_internal(char *p, int p_max_size,
                                get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_TIME);
                        }
                        OBJ(battery_percent) {
-                               spaced_print(p, p_max_size, "%*d", pad_percents,
-                                               "battery_percent", get_battery_perct(obj->data.s));
+                               spaced_print(p, p_max_size, "%*d", 4, "battery_percent",
+                                               pad_percents, get_battery_perct(obj->data.s));
                        }
                        OBJ(battery_bar) {
                                new_bar(p, obj->a, obj->b, get_battery_perct_bar(obj->data.s));
@@ -4263,6 +4361,10 @@ static void generate_text_internal(char *p, int p_max_size,
                                snprintf(p, p_max_size, "%s", BUILD_ARCH);
                        }
 #if defined(__linux__)
+                       OBJ(disk_protect) {
+                               snprintf(p, p_max_size, "%s",
+                                       get_disk_protect_queue(obj->data.s));
+                       }
                        OBJ(i8k_version) {
                                snprintf(p, p_max_size, "%s", i8k.version);
                        }
@@ -4354,6 +4456,23 @@ static void generate_text_internal(char *p, int p_max_size,
                                        if_jumped = 0;
                                }
                        }
+                       OBJ(if_gw) {
+                               if (!cur->gw_info.count) {
+                                       i = obj->data.ifblock.pos;
+                                       if_jumped = 1;
+                               } else {
+                                       if_jumped = 0;
+                               }
+                       }
+                       OBJ(gw_iface) {
+                               snprintf(p, p_max_size, "%s", cur->gw_info.iface);
+                       }
+                       OBJ(gw_ip) {
+                               snprintf(p, p_max_size, "%s", cur->gw_info.ip);
+                       }
+                       OBJ(laptop_mode) {
+                               snprintf(p, p_max_size, "%d", get_laptop_mode());
+                       }
                        OBJ(pb_battery) {
                                get_powerbook_batt_info(p, p_max_size, obj->data.i);
                        }
@@ -4530,20 +4649,42 @@ static void generate_text_internal(char *p, int p_max_size,
                                int length = fread(p, 1, p_max_size, fp);
 
                                pclose(fp);
-                               /* output[length] = '\0';
-                               if (length > 0 && output[length - 1] == '\n') {
-                                       output[length - 1] = '\0';
-                               } */
+
                                p[length] = '\0';
                                if (length > 0 && p[length - 1] == '\n') {
                                        p[length - 1] = '\0';
                                }
-                               // parse_conky_vars(output, p, cur);
+                       }
+                       OBJ(execp) {
+                               FILE *fp;
+                               struct information *my_info;
+                               struct text_object_list *text_objects;
+                               int length;
+
+                               fp = popen(obj->data.s, "r");
+                               fread(p, 1, p_max_size, fp);
+                               pclose(fp);
+
+                               my_info = malloc(sizeof(struct information));
+                               memcpy(my_info, cur, sizeof(struct information));
+                               text_objects = parse_conky_vars(p, p, my_info);
+
+                               length = strlen(p);
+
+                               p[length] = '\0';
+                               if (length > 0 && p[length - 1] == '\n') {
+                                       p[length - 1] = '\0';
+                               }
+
+                               free_text_objects(text_objects->text_object_count, text_objects->text_objects);
+                               free(text_objects);
+                               free(my_info);
                        }
                        OBJ(execbar) {
                                char *p2 = p;
                                FILE *fp = popen(obj->data.s, "r");
                                int n2 = fread(p, 1, p_max_size, fp);
+                               double barnum;
 
                                pclose(fp);
                                p[n2] = '\0';
@@ -4557,7 +4698,6 @@ static void generate_text_internal(char *p, int p_max_size,
                                        }
                                        p2++;
                                }
-                               double barnum;
 
                                if (sscanf(p, "%lf", &barnum) == 0) {
                                        ERR("reading execbar value failed (perhaps it's not the "
@@ -4575,6 +4715,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                char *p2 = p;
                                FILE *fp = popen(obj->data.s, "r");
                                int n2 = fread(p, 1, p_max_size, fp);
+                               double barnum;
 
                                pclose(fp);
                                p[n2] = '\0';
@@ -4587,7 +4728,6 @@ static void generate_text_internal(char *p, int p_max_size,
                                        }
                                        p2++;
                                }
-                               double barnum;
 
                                if (sscanf(p, "%lf", &barnum) == 0) {
                                        ERR("reading execgraph value failed (perhaps it's not the "
@@ -4609,6 +4749,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        char *p2 = p;
                                        FILE *fp = popen(obj->data.execi.cmd, "r");
                                        int n2 = fread(p, 1, p_max_size, fp);
+                                       float barnum;
 
                                        pclose(fp);
                                        p[n2] = '\0';
@@ -4622,7 +4763,6 @@ static void generate_text_internal(char *p, int p_max_size,
                                                }
                                                p2++;
                                        }
-                                       float barnum;
 
                                        if (sscanf(p, "%f", &barnum) == 0) {
                                                ERR("reading execibar value failed (perhaps it's not "
@@ -4646,6 +4786,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        char *p2 = p;
                                        FILE *fp = popen(obj->data.execi.cmd, "r");
                                        int n2 = fread(p, 1, p_max_size, fp);
+                                       float barnum;
 
                                        pclose(fp);
                                        p[n2] = '\0';
@@ -4659,7 +4800,6 @@ static void generate_text_internal(char *p, int p_max_size,
                                                }
                                                p2++;
                                        }
-                                       float barnum;
 
                                        if (sscanf(p, "%f", &barnum) == 0) {
                                                ERR("reading execigraph value failed (perhaps it's not "
@@ -4685,8 +4825,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        char *output = obj->data.execi.buffer;
                                        FILE *fp = popen(obj->data.execi.cmd, "r");
 
-                                       // int length = fread(output, 1, small_text_buffer_size, fp);
-                                       int length = fread(output, 1, small_text_buffer_size, fp);
+                                       int length = fread(output, 1, text_buffer_size, fp);
 
                                        pclose(fp);
                                        output[length] = '\0';
@@ -4698,10 +4837,39 @@ static void generate_text_internal(char *p, int p_max_size,
                                }
                                // parse_conky_vars(output, p, cur);
                        }
+                       OBJ(execpi) {
+                               struct text_object_list *text_objects = 0;
+                               struct information *my_info =
+                                       malloc(sizeof(struct information));
+                               memcpy(my_info, cur, sizeof(struct information));
+
+                               if (current_update_time - obj->data.execi.last_update
+                                               < obj->data.execi.interval
+                                               || obj->data.execi.interval == 0) {
+                                       text_objects = parse_conky_vars(obj->data.execi.buffer, p, my_info);
+                               } else {
+                                       char *output = obj->data.execi.buffer;
+                                       FILE *fp = popen(obj->data.execi.cmd, "r");
+                                       int length = fread(output, 1, text_buffer_size, fp);
+
+                                       pclose(fp);
+
+                                       output[length] = '\0';
+                                       if (length > 0 && output[length - 1] == '\n') {
+                                               output[length - 1] = '\0';
+                                       }
+                                       
+                                       text_objects = parse_conky_vars(obj->data.execi.buffer, p, my_info);
+                                       obj->data.execi.last_update = current_update_time;
+                               }
+                               free_text_objects(text_objects->text_object_count, text_objects->text_objects);
+                               free(text_objects);
+                               free(my_info);
+                       }
                        OBJ(texeci) {
                                if (!obj->data.texeci.p_timed_thread) {
                                        obj->data.texeci.p_timed_thread =
-                                               timed_thread_create((void *) threaded_exec,
+                                               timed_thread_create(&threaded_exec,
                                                (void *) obj, obj->data.texeci.interval * 1000000);
                                        if (!obj->data.texeci.p_timed_thread) {
                                                ERR("Error creating texeci timed thread");
@@ -4722,7 +4890,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        // this means we use info
                                        if (!info.mail->p_timed_thread) {
                                                info.mail->p_timed_thread =
-                                                       timed_thread_create((void *) imap_thread,
+                                                       timed_thread_create(&imap_thread,
                                                        (void *) info.mail, info.mail->interval * 1000000);
                                                if (!info.mail->p_timed_thread) {
                                                        ERR("Error creating imap timed thread");
@@ -4740,7 +4908,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        // this means we use obj
                                        if (!obj->data.mail->p_timed_thread) {
                                                obj->data.mail->p_timed_thread =
-                                                       timed_thread_create((void *) imap_thread,
+                                                       timed_thread_create(&imap_thread,
                                                        (void *) obj->data.mail,
                                                        obj->data.mail->interval * 1000000);
                                                if (!obj->data.mail->p_timed_thread) {
@@ -4768,7 +4936,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        // this means we use info
                                        if (!info.mail->p_timed_thread) {
                                                info.mail->p_timed_thread =
-                                                       timed_thread_create((void *) imap_thread,
+                                                       timed_thread_create(&imap_thread,
                                                        (void *) info.mail, info.mail->interval * 1000000);
                                                if (!info.mail->p_timed_thread) {
                                                        ERR("Error creating imap timed thread");
@@ -4786,7 +4954,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        // this means we use obj
                                        if (!obj->data.mail->p_timed_thread) {
                                                obj->data.mail->p_timed_thread =
-                                                       timed_thread_create((void *) imap_thread,
+                                                       timed_thread_create(&imap_thread,
                                                        (void *) obj->data.mail,
                                                        obj->data.mail->interval * 1000000);
                                                if (!obj->data.mail->p_timed_thread) {
@@ -4814,7 +4982,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        // this means we use info
                                        if (!info.mail->p_timed_thread) {
                                                info.mail->p_timed_thread =
-                                                       timed_thread_create((void *) pop3_thread,
+                                                       timed_thread_create(&pop3_thread,
                                                        (void *) info.mail, info.mail->interval * 1000000);
                                                if (!info.mail->p_timed_thread) {
                                                        ERR("Error creating pop3 timed thread");
@@ -4832,7 +5000,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        // this means we use obj
                                        if (!obj->data.mail->p_timed_thread) {
                                                obj->data.mail->p_timed_thread =
-                                                       timed_thread_create((void *) pop3_thread,
+                                                       timed_thread_create(&pop3_thread,
                                                        (void *) obj->data.mail,
                                                        obj->data.mail->interval * 1000000);
                                                if (!obj->data.mail->p_timed_thread) {
@@ -4860,7 +5028,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        // this means we use info
                                        if (!info.mail->p_timed_thread) {
                                                info.mail->p_timed_thread =
-                                                       timed_thread_create((void *) pop3_thread,
+                                                       timed_thread_create(&pop3_thread,
                                                        (void *) info.mail, info.mail->interval * 1000000);
                                                if (!info.mail->p_timed_thread) {
                                                        ERR("Error creating pop3 timed thread");
@@ -4879,7 +5047,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                        // this means we use obj
                                        if (!obj->data.mail->p_timed_thread) {
                                                obj->data.mail->p_timed_thread =
-                                                       timed_thread_create((void *) pop3_thread,
+                                                       timed_thread_create(&pop3_thread,
                                                        (void *) obj->data.mail,
                                                        obj->data.mail->interval * 1000000);
                                                if (!obj->data.mail->p_timed_thread) {
@@ -4922,9 +5090,9 @@ static void generate_text_internal(char *p, int p_max_size,
                        OBJ(fs_free_perc) {
                                if (obj->data.fs != NULL) {
                                        if (obj->data.fs->size) {
-                                               spaced_print(p, p_max_size, "%*d", pad_percents,
-                                                       "fs_free_perc", (int) ((obj->data.fs->avail * 100) /
-                                                       obj->data.fs->size));
+                                               spaced_print(p, p_max_size, "%*d", 4, "fs_free_perc",
+                                                               pad_percents, (int) ((obj->data.fs->avail * 100) /
+                                                                       obj->data.fs->size));
                                        } else {
                                                snprintf(p, p_max_size, "0");
                                        }
@@ -4960,9 +5128,9 @@ static void generate_text_internal(char *p, int p_max_size,
                        OBJ(fs_used_perc) {
                                if (obj->data.fs != NULL) {
                                        if (obj->data.fs->size) {
-                                               spaced_print(p, 4, "%*d", pad_percents,
-                                                       "fs_used_perc", 100 - ((int) ((obj->data.fs->avail * 100) /
-                                                       obj->data.fs->size)));
+                                               spaced_print(p, 4, "%*d", 4, "fs_used_perc",
+                                                               pad_percents, 100 - ((int) ((obj->data.fs->avail * 100) /
+                                                                               obj->data.fs->size)));
                                        } else {
                                                snprintf(p, p_max_size, "0");
                                        }
@@ -4994,6 +5162,11 @@ static void generate_text_internal(char *p, int p_max_size,
                        OBJ(hr) {
                                new_hr(p, obj->data.i);
                        }
+                       OBJ(nameserver) {
+                               if (cur->nameserver_info.nscount > obj->data.i)
+                                       snprintf(p, p_max_size, "%s",
+                                                       cur->nameserver_info.ns_list[obj->data.i]);
+                       }
 #ifdef RSS
                        OBJ(rss) {
                                PRSS *data = get_rss_info(obj->data.rss.uri,
@@ -5032,9 +5205,9 @@ static void generate_text_internal(char *p, int p_max_size,
                                        } else if (!strcmp(obj->data.rss.action, "item_titles")) {
                                                if (data->item_count > 0) {
                                                        int itmp;
+                                                       int show;
 
                                                        p[0] = 0;
-                                                       int show;
 
                                                        if (obj->data.rss.act_par > data->item_count) {
                                                                show = data->item_count;
@@ -5130,11 +5303,12 @@ static void generate_text_internal(char *p, int p_max_size,
                                new_alignc(p, obj->data.i);
                        }
                        OBJ(if_empty) {
+                               struct text_object_list *text_objects;
                                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);
+                               text_objects = parse_conky_vars(obj->data.ifblock.s, p, my_info);
+
                                if (strlen(p) != 0) {
                                        i = obj->data.ifblock.pos;
                                        if_jumped = 1;
@@ -5142,6 +5316,8 @@ static void generate_text_internal(char *p, int p_max_size,
                                        if_jumped = 0;
                                }
                                p[0] = '\0';
+                               free_text_objects(text_objects->text_object_count, text_objects->text_objects);
+                               free(text_objects);
                                free(my_info);
                        }
                        OBJ(if_existing) {
@@ -5182,6 +5358,9 @@ static void generate_text_internal(char *p, int p_max_size,
                                        if_jumped = 0;
                                }
                        }
+                       OBJ(ioscheduler) {
+                               snprintf(p, p_max_size, "%s", get_ioscheduler(obj->data.s));
+                       }
                        OBJ(kernel) {
                                snprintf(p, p_max_size, "%s", cur->uname_s.release);
                        }
@@ -5198,7 +5377,7 @@ static void generate_text_internal(char *p, int p_max_size,
                        }
                        OBJ(memperc) {
                                if (cur->memmax) {
-                                       spaced_print(p, p_max_size, "%*Lu", 4, "memperc",
+                                       spaced_print(p, p_max_size, "%*llu", 4, "memperc",
                                                pad_percents, cur->mem * 100 / cur->memmax);
                                }
                        }
@@ -5242,7 +5421,7 @@ static void generate_text_internal(char *p, int p_max_size,
                        }
                        OBJ(mboxscan) {
                                mbox_scan(obj->data.mboxscan.args, obj->data.mboxscan.output,
-                                       small_text_buffer_size);
+                                       text_buffer_size);
                                snprintf(p, p_max_size, "%s", obj->data.mboxscan.output);
                        }
                        OBJ(new_mails) {
@@ -5281,7 +5460,7 @@ static void generate_text_internal(char *p, int p_max_size,
                                if (cur->swapmax == 0) {
                                        strncpy(p, "No swap", p_max_size);
                                } else {
-                                       spaced_print(p, p_max_size, "%*Lu", 4, "swapperc",
+                                       spaced_print(p, p_max_size, "%*llu", 4, "swapperc",
                                                pad_percents, cur->swap * 100 / cur->swapmax);
                                }
                        }
@@ -5307,14 +5486,16 @@ static void generate_text_internal(char *p, int p_max_size,
                        }
                        OBJ(tztime) {
                                char *oldTZ = NULL;
+                               time_t t;
+                               struct tm *tm;
 
                                if (obj->data.tztime.tz) {
                                        oldTZ = getenv("TZ");
                                        setenv("TZ", obj->data.tztime.tz, 1);
                                        tzset();
                                }
-                               time_t t = time(NULL);
-                               struct tm *tm = localtime(&t);
+                               t = time(NULL);
+                               tm = localtime(&t);
 
                                setlocale(LC_TIME, "");
                                strftime(p, p_max_size, obj->data.tztime.fmt, tm);
@@ -5481,8 +5662,8 @@ static void generate_text_internal(char *p, int p_max_size,
                                }
                        }
                        OBJ(mpd_percent) {
-                               spaced_print(p, p_max_size, "%*d", pad_percents,
-                                               "mpd_percent", (int) (cur->mpd.progress * 100));
+                               spaced_print(p, p_max_size, "%*d", 4, "mpd_percent",
+                                               pad_percents, (int) (cur->mpd.progress * 100));
                        }
                        OBJ(mpd_bar) {
                                new_bar(p, obj->data.pair.a, obj->data.pair.b,
@@ -5733,11 +5914,12 @@ static void generate_text_internal(char *p, int p_max_size,
                                                < obj->data.tail.interval) {
                                        snprintf(p, p_max_size, "%s", obj->data.tail.buffer);
                                } else {
-                                       obj->data.tail.last_update = current_update_time;
                                        FILE *fp;
                                        long nl = 0, bsize;
                                        int iter;
 
+                                       obj->data.tail.last_update = current_update_time;
+
                                        if (obj->data.tail.fd != -1) {
                                                tail_pipe(obj, p, p_max_size);
                                                goto head;
@@ -5777,10 +5959,10 @@ static void generate_text_internal(char *p, int p_max_size,
                                                }
                                                /* Make sure bsize is at least 1 byte smaller than the
                                                 * buffer max size. */
-                                               if (bsize > (long) ((small_text_buffer_size * 20) - 1)) {
-                                                       fseek(fp, bsize - small_text_buffer_size * 20 - 1,
+                                               if (bsize > (long) ((text_buffer_size * 20) - 1)) {
+                                                       fseek(fp, bsize - text_buffer_size * 20 - 1,
                                                                SEEK_CUR);
-                                                       bsize = small_text_buffer_size * 20 - 1;
+                                                       bsize = text_buffer_size * 20 - 1;
                                                }
                                                bsize = fread(obj->data.tail.buffer, 1, bsize, fp);
                                                fclose(fp);
@@ -5809,11 +5991,12 @@ head:
                                                < obj->data.tail.interval) {
                                        snprintf(p, p_max_size, "%s", obj->data.tail.buffer);
                                } else {
-                                       obj->data.tail.last_update = current_update_time;
                                        FILE *fp;
                                        long nl = 0;
                                        int iter;
 
+                                       obj->data.tail.last_update = current_update_time;
+
                                        fp = fopen(obj->data.tail.logfile, "rt");
                                        if (fp == NULL) {
                                                /* Send one message, but do not consistently spam
@@ -5836,8 +6019,8 @@ head:
                                                obj->data.tail.readlines = iter;
                                                /* Make sure nl is at least 1 byte smaller than the
                                                 * buffer max size. */
-                                               if (nl > (long) ((small_text_buffer_size * 20) - 1)) {
-                                                       nl = small_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);
@@ -5933,7 +6116,7 @@ head:
                                if(obj->data.s && sscanf(obj->data.s, "%i", &idx) == 1) {
                                        val = smapi_bat_installed(idx) ?
                                                smapi_get_bat_int(idx, "remaining_percent") : 0;
-                                       spaced_print(p, p_max_size, "%*d", pad_percents, "smapi_bat_perc", val);
+                                       spaced_print(p, p_max_size, "%*d", 4, "smapi_bat_perc", pad_percents, val);
                                } else
                                        ERR("argument to smapi_bat_perc must be an integer");
                        }
@@ -5987,7 +6170,7 @@ head:
 
 double current_update_time, last_update_time;
 
-static void generate_text()
+static void generate_text(void)
 {
        struct information *cur = &info;
        char *p;
@@ -5998,7 +6181,7 @@ static void generate_text()
 
        current_update_time = get_time();
 
-       update_stuff(cur);
+       update_stuff();
        /* 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;
@@ -6010,7 +6193,8 @@ static void generate_text()
 
        p = text_buffer;
 
-       generate_text_internal(p, p_p_max_size, text_objects, text_object_count, cur);
+       generate_text_internal(p, max_user_text, global_text_objects,
+                       global_text_object_count, cur);
 
        if (stuff_in_upper_case) {
                char *p;
@@ -6028,7 +6212,7 @@ static void generate_text()
 }
 
 #ifdef X11
-static void set_font()
+static void set_font(void)
 {
 #ifdef XFT
        if (use_xft) {
@@ -6057,17 +6241,18 @@ static inline int get_string_width(const char *s)
 
 static inline int get_string_width_special(char *s)
 {
+#ifdef X11
+       char *p, *final;
+       int index = 1;
+       int width = 0;
+       unsigned int i;
+
        if (!s) {
                return 0;
        }
-#ifdef X11
-       char *p, *final;
 
        p = strdup(s);
        final = p;
-       int index = 1;
-       int width = 0;
-       unsigned int i;
 
        while (*p) {
                if (*p == SPECIAL_CHAR) {
@@ -6091,7 +6276,7 @@ static inline int get_string_width_special(char *s)
        free(final);
        return width;
 #else
-       return strlen(s);
+       return (s) ? strlen(s) : 0;
 #endif /* X11 */
 }
 
@@ -6099,7 +6284,7 @@ static inline int get_string_width_special(char *s)
 static void text_size_updater(char *s);
 
 int last_font_height;
-static void update_text_area()
+static void update_text_area(void)
 {
        int x, y;
 
@@ -6279,24 +6464,25 @@ static inline void set_foreground_color(long c)
 
 static void draw_string(const char *s)
 {
-       if (s[0] == '\0') {
-               return;
-       }
        int i, i2, pos, width_of_s;
        int max = 0;
        int added;
+       char space[2];
+
+       if (s[0] == '\0') {
+               return;
+       }
 
        width_of_s = get_string_width(s);
        if (out_to_console) {
                printf("%s\n", s);
                fflush(stdout); /* output immediately, don't buffer */
        }
-       memset(tmpstring1, 0, small_text_buffer_size);
-       memset(tmpstring2, 0, small_text_buffer_size);
-       strncpy(tmpstring1, s, small_text_buffer_size - 1);
+       memset(tmpstring1, 0, text_buffer_size);
+       memset(tmpstring2, 0, text_buffer_size);
+       strncpy(tmpstring1, s, text_buffer_size - 1);
        pos = 0;
        added = 0;
-       char space[2];
 
        snprintf(space, 2, " ");
 #ifdef X11
@@ -6305,19 +6491,19 @@ static void draw_string(const char *s)
        /* This code looks for tabs in the text and coverts them to spaces.
         * The trick is getting the correct number of spaces, and not going
         * over the window's size without forcing the window larger. */
-       for (i = 0; i < (int)small_text_buffer_size; i++) {
+       for (i = 0; i < (int)text_buffer_size; i++) {
                if (tmpstring1[i] == '\t') {    // 9 is ascii tab
                        i2 = 0;
                        for (i2 = 0; i2 < (8 - (1 + pos) % 8) && added <= max; i2++) {
                                /* guard against overrun */
-                               tmpstring2[MIN(pos + i2, (int)small_text_buffer_size - 1)] = ' ';
+                               tmpstring2[MIN(pos + i2, (int)text_buffer_size - 1)] = ' ';
                                added++;
                        }
                        pos += i2;
                } else {
                        if (tmpstring1[i] != 9) {
                                /* guard against overrun */
-                               tmpstring2[MIN(pos, (int)small_text_buffer_size - 1)] = tmpstring1[i];
+                               tmpstring2[MIN(pos, (int)text_buffer_size - 1)] = tmpstring1[i];
                                pos++;
                        }
                }
@@ -6349,10 +6535,10 @@ static void draw_string(const char *s)
                c2.color.alpha = fonts[selected_font].font_alpha;
                if (utf8_mode) {
                        XftDrawStringUtf8(window.xftdraw, &c2, fonts[selected_font].xftfont,
-                               cur_x, cur_y, (XftChar8 *) s, strlen(s));
+                               cur_x, cur_y, (const XftChar8 *) s, strlen(s));
                } else {
                        XftDrawString8(window.xftdraw, &c2, fonts[selected_font].xftfont,
-                               cur_x, cur_y, (XftChar8 *) s, strlen(s));
+                               cur_x, cur_y, (const XftChar8 *) s, strlen(s));
                }
        } else
 #endif
@@ -6362,13 +6548,14 @@ static void draw_string(const char *s)
        }
        cur_x += width_of_s;
 #endif /* X11 */
-       memcpy(tmpstring1, s, small_text_buffer_size);
+       memcpy(tmpstring1, s, text_buffer_size);
 }
 
 long redmask, greenmask, bluemask;
 
-void set_up_gradient()
+void set_up_gradient(void)
 {
+       int i;
 #ifdef X11
        colour_depth = DisplayPlanes(display, screen);
 #else
@@ -6378,7 +6565,6 @@ void set_up_gradient()
                ERR("using non-standard colour depth, gradients may look like a "
                        "lolly-pop");
        }
-       int i;
 
        redmask = 0;
        greenmask = 0;
@@ -6459,14 +6645,17 @@ inline unsigned long do_gradient(unsigned long first_colour,
 inline unsigned long gradient_max(unsigned long first_colour,
                unsigned long last_colour)
 {
+       int red1, green1, blue1;                                // first colour
+       int red2, green2, blue2;                                // second colour
+       int red3 = 0, green3 = 0, blue3 = 0;                    // difference
+       long redshift, greenshift;
+       int max;
+
        if (colour_depth == 0) {
                set_up_gradient();
        }
-       int red1, green1, blue1;                                // first colour
-       int red2, green2, blue2;                                // second colour
-       long redshift = (2 * colour_depth / 3 + colour_depth % 3);
-       long greenshift = (colour_depth / 3);
-       int red3 = 0, green3 = 0, blue3 = 0;    // difference
+       redshift = (2 * colour_depth / 3 + colour_depth % 3);
+       greenshift = (colour_depth / 3);
 
        red1 = (first_colour & redmask) >> redshift;
        green1 = (first_colour & greenmask) >> greenshift;
@@ -6477,7 +6666,7 @@ inline unsigned long gradient_max(unsigned long first_colour,
        red3 = abs(red1 - red2);
        green3 = abs(green1 - green2);
        blue3 = abs(blue1 - blue2);
-       int max = red3;
+       max = red3;
 
        if (green3 > max) {
                max = green3;
@@ -6492,11 +6681,12 @@ static void draw_line(char *s)
 {
 #ifdef X11
        char *p;
+       int cur_y_add = 0;
+       short font_h;
 
        cur_x = text_start_x;
        cur_y += font_ascent();
-       int cur_y_add = 0;
-       short font_h = font_height();
+       font_h = font_height();
 
        /* find specials and draw stuff */
        p = s;
@@ -6544,13 +6734,14 @@ static void draw_line(char *s)
 
                                case BAR:
                                {
+                                       int h, bar_usage, by;
                                        if (cur_x - text_start_x > maximum_width
                                                        && maximum_width > 0) {
                                                break;
                                        }
-                                       int h = specials[special_index].height;
-                                       int bar_usage = specials[special_index].arg;
-                                       int by = cur_y - (font_ascent() / 2) - 1;
+                                       h = specials[special_index].height;
+                                       bar_usage = specials[special_index].arg;
+                                       by = cur_y - (font_ascent() / 2) - 1;
 
                                        if (h < font_height()) {
                                                by -= h / 2 - 1;
@@ -6579,13 +6770,18 @@ static void draw_line(char *s)
 
                                case GRAPH:
                                {
+                                       int h, by, i, j = 0;
+                                       int gradient_size = 0;
+                                       float gradient_factor = 0;
+                                       float gradient_update = 0;
+                                       unsigned long last_colour = current_color;
+                                       unsigned long tmpcolour = current_color;
                                        if (cur_x - text_start_x > maximum_width
                                                        && maximum_width > 0) {
                                                break;
                                        }
-                                       int h = specials[special_index].height;
-                                       unsigned long last_colour = current_color;
-                                       int by = cur_y - (font_ascent() / 2) - 1;
+                                       h = specials[special_index].height;
+                                       by = cur_y - (font_ascent() / 2) - 1;
 
                                        if (h < font_height()) {
                                                by -= h / 2 - 1;
@@ -6605,12 +6801,6 @@ static void draw_line(char *s)
                                        }
                                        XSetLineAttributes(display, window.gc, 1, LineSolid,
                                                CapButt, JoinMiter);
-                                       int i;
-                                       int j = 0;
-                                       int gradient_size = 0;
-                                       float gradient_factor = 0;
-                                       float gradient_update = 0;
-                                       unsigned long tmpcolour = current_color;
 
                                        if (specials[special_index].last_colour != 0
                                                        || specials[special_index].first_colour != 0) {
@@ -6776,7 +6966,7 @@ static void draw_line(char *s)
 #endif /* X11 */
 }
 
-static void draw_text()
+static void draw_text(void)
 {
 #ifdef X11
        cur_y = text_start_y;
@@ -6807,7 +6997,7 @@ static void draw_text()
        for_each_line(text_buffer, draw_line);
 }
 
-static void draw_stuff()
+static void draw_stuff(void)
 {
 #ifdef X11
        selected_font = 0;
@@ -6822,8 +7012,8 @@ static void draw_stuff()
        }
 
        if (draw_outline) {
-               selected_font = 0;
                int i, j;
+               selected_font = 0;
 
                for (i = -1; i < 2; i++) {
                        for (j = -1; j < 2; j++) {
@@ -6880,7 +7070,7 @@ static void clear_text(int exposures)
 static int need_to_update;
 
 /* update_text() generates new text and clears old text area */
-static void update_text()
+static void update_text(void)
 {
        generate_text();
 #ifdef X11
@@ -6889,35 +7079,35 @@ static void update_text()
        need_to_update = 1;
 }
 
-static void main_loop()
+static void main_loop(void)
 {
 #ifdef SIGNAL_BLOCKING
        sigset_t newmask, oldmask;
-
-       sigemptyset(&newmask);
-       sigaddset(&newmask, SIGINT);
-       sigaddset(&newmask, SIGTERM);
-       sigaddset(&newmask, SIGUSR1);
 #endif
-
 #ifdef X11
        Region region = XCreateRegion();
 
 #ifdef HAVE_XDAMAGE
+       Damage damage;
+       XserverRegion region2, part;
        int event_base, error_base;
 
        if (!XDamageQueryExtension(display, &event_base, &error_base)) {
                ERR("Xdamage extension unavailable");
        }
-       Damage damage = XDamageCreate(display, window.window,
-               XDamageReportNonEmpty);
-       XserverRegion region2 = XFixesCreateRegionFromWindow(display,
-               window.window, 0);
-       XserverRegion part = XFixesCreateRegionFromWindow(display,
-               window.window, 0);
+       damage = XDamageCreate(display, window.window, XDamageReportNonEmpty);
+       region2 = XFixesCreateRegionFromWindow(display, window.window, 0);
+       part = XFixesCreateRegionFromWindow(display, window.window, 0);
 #endif /* HAVE_XDAMAGE */
 #endif /* X11 */
 
+#ifdef SIGNAL_BLOCKING
+       sigemptyset(&newmask);
+       sigaddset(&newmask, SIGINT);
+       sigaddset(&newmask, SIGTERM);
+       sigaddset(&newmask, SIGUSR1);
+#endif
+
        info.looped = 0;
        while (total_run_times == 0 || info.looped < total_run_times) {
                info.looped++;
@@ -7195,9 +7385,9 @@ static void main_loop()
                                XDestroyRegion(region);
                                region = NULL;
 #ifdef HAVE_XDAMAGE
-       XDamageDestroy(display, damage);
-       XFixesDestroyRegion(display, region2);
-       XFixesDestroyRegion(display, part);
+                               XDamageDestroy(display, damage);
+                               XFixesDestroyRegion(display, region2);
+                               XFixesDestroyRegion(display, part);
 #endif /* HAVE_XDAMAGE */
 #endif /* X11 */
                                return; /* return from main_loop */
@@ -7314,18 +7504,18 @@ void reload_config(void)
                if (tmpstring1) {
                        free(tmpstring1);
                }
-               tmpstring1 = malloc(small_text_buffer_size);
-               memset(tmpstring1, 0, small_text_buffer_size);
+               tmpstring1 = malloc(text_buffer_size);
+               memset(tmpstring1, 0, text_buffer_size);
                if (tmpstring2) {
                        free(tmpstring2);
                }
-               tmpstring2 = malloc(small_text_buffer_size);
-               memset(tmpstring2, 0, small_text_buffer_size);
+               tmpstring2 = malloc(text_buffer_size);
+               memset(tmpstring2, 0, text_buffer_size);
                if (text_buffer) {
                        free(text_buffer);
                }
-               text_buffer = malloc(large_text_buffer_size);
-               memset(text_buffer, 0, large_text_buffer_size);
+               text_buffer = malloc(max_user_text);
+               memset(text_buffer, 0, max_user_text);
                update_text();
        }
 }
@@ -7361,9 +7551,21 @@ void clean_up(void)
        free_fonts();
 #endif /* X11 */
 
-       free_text_objects(text_object_count, text_objects);
-       text_object_count = 0;
-       text_objects = NULL;
+       free_text_objects(global_text_object_count, global_text_objects);
+       if (tmpstring1) {
+               free(tmpstring1);
+               tmpstring1 = 0;
+       }
+       if (tmpstring2) {
+               free(tmpstring2);
+               tmpstring2 = 0;
+       }
+       if (text_buffer) {
+               free(text_buffer);
+               text_buffer = 0;
+       }
+       global_text_object_count = 0;
+       global_text_objects = NULL;
 
        if (text) {
                free(text);
@@ -8130,26 +8332,16 @@ static void load_config_file(const char *f)
                        }
                }
                CONF("text_buffer_size") {
-                       ERR("text_buffer_size is deprecated in favour of small_text_buffer size and large_text_buffer_size");
-               }
-               CONF("small_text_buffer_size") {
                        if (value) {
-                               small_text_buffer_size = atoi(value);
-                               if (small_text_buffer_size < DEFAULT_TEXT_BUFFER_SIZE) {
-                                       small_text_buffer_size = DEFAULT_TEXT_BUFFER_SIZE;
+                               text_buffer_size = atoi(value);
+                               if (text_buffer_size < DEFAULT_TEXT_BUFFER_SIZE) {
+                                       ERR("text_buffer_size must be >=%i bytes", DEFAULT_TEXT_BUFFER_SIZE);
+                                       text_buffer_size = DEFAULT_TEXT_BUFFER_SIZE;
                                }
                        } else {
                                CONF_ERR;
                        }
                }
-               CONF("large_text_buffer_size") {
-                       if (value) {
-                               large_text_buffer_size = atoi(value);
-                               p_p_max_size = large_text_buffer_size; 
-                       } else {
-                               CONF_ERR;
-                       }
-               }
                CONF("text") {
                        if (text) {
                                free(text);
@@ -8249,6 +8441,10 @@ static const struct option longopts[] = {
 
 int main(int argc, char **argv)
 {
+#ifdef X11
+       char *s, *temp;
+       unsigned int x;
+#endif
        struct sigaction act, oact;
 
        g_signal_pending = 0;
@@ -8261,9 +8457,6 @@ int main(int argc, char **argv)
 
        /* handle command line parameters that don't change configs */
 #ifdef X11
-       char *s, *temp;
-       unsigned int x;
-
        if (((s = getenv("LC_ALL")) && *s) || ((s = getenv("LC_CTYPE")) && *s)
                        || ((s = getenv("LANG")) && *s)) {
                temp = (char *) malloc((strlen(s) + 1) * sizeof(char));
@@ -8346,6 +8539,17 @@ int main(int argc, char **argv)
        init_X11();
 #endif /* X11 */
 
+       /* check if specified config file is valid */
+       if (current_config) {
+               struct stat sb;
+               if (stat(current_config, &sb) ||
+                               (!S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode))) {
+                       ERR("invalid configuration file '%s'\n", current_config);
+                       free(current_config);
+                       current_config = 0;
+               }
+       }
+
        /* load current_config, CONFIG_FILE or SYSTEM_CONFIG_FILE */
 
        if (!current_config) {
@@ -8511,12 +8715,12 @@ int main(int argc, char **argv)
                }
        }
 
-       text_buffer = malloc(large_text_buffer_size);
-       memset(text_buffer, 0, large_text_buffer_size);
-       tmpstring1 = malloc(small_text_buffer_size);
-       memset(tmpstring1, 0, small_text_buffer_size);
-       tmpstring2 = malloc(small_text_buffer_size);
-       memset(tmpstring2, 0, small_text_buffer_size);
+       text_buffer = malloc(max_user_text);
+       memset(text_buffer, 0, max_user_text);
+       tmpstring1 = malloc(text_buffer_size);
+       memset(tmpstring1, 0, text_buffer_size);
+       tmpstring2 = malloc(text_buffer_size);
+       memset(tmpstring2, 0, text_buffer_size);
 
 #ifdef X11
        selected_font = 0;