* Please see COPYING for details
*
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
- * Copyright (c) 2005-2007 Brenden Matthews, Philip Kovacs, et. al.
+ * Copyright (c) 2005-2008 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS)
* All rights reserved.
*
* $Id$ */
#include "conky.h"
-#include <stdio.h>
-#include <stdlib.h>
+#include <stdarg.h>
+#include <math.h>
#include <ctype.h>
#include <time.h>
#include <locale.h>
#include <unistd.h>
#include <errno.h>
#include <termios.h>
-#include <string.h>
#include <limits.h>
#if HAVE_DIRENT_H
#include <dirent.h>
#define CONFIG_FILE "$HOME/.conkyrc"
#define MAIL_FILE "$MAIL"
#define MAX_IF_BLOCK_DEPTH 5
+#define MAX_TAIL_LINES 100
/* #define SIGNAL_BLOCKING */
#undef SIGNAL_BLOCKING
-static void print_version()
+static void print_version(void) __attribute__((noreturn));
+
+static void print_version(void)
{
printf("Conky %s compiled %s for %s\n", VERSION, BUILD_DATE, BUILD_ARCH);
#ifdef SMAPI
" * smapi\n"
#endif /* SMAPI */
+#ifdef NVIDIA
+ " * nvidia\n"
+#endif
"", SYSTEM_CONFIG_FILE
);
exit(0);
}
-static char *suffixes[] = { "B", "kiB", "MiB", "GiB", "TiB", "PiB", "" };
+static const char *suffixes[] = { "B", "kiB", "MiB", "GiB", "TiB", "PiB", "" };
#ifdef X11
#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)
{
font_count++;
}
if (strlen(data_in) > 1) {
- strncpy(fonts[0].name, data_in, DEFAULT_TEXT_BUFFER_SIZE - 1);
+ strncpy(fonts[0].name, data_in, DEFAULT_TEXT_BUFFER_SIZE);
#ifdef XFT
fonts[0].font_alpha = 0xffff;
#endif
}
}
-void free_fonts()
+void free_fonts(void)
{
int i;
selected_font = 0;
}
-static void load_fonts()
+static void load_fonts(void)
{
int i;
#ifdef X11
+static int show_graph_scale;
+
/* Position on the screen */
static int text_alignment;
static int gap_x, gap_y;
int register_iconv(iconv_t *new_iconv)
{
- if (iconv_cd) {
- iconv_cd = realloc(iconv, sizeof(iconv_t *) * (iconv_count + 1));
- } else {
- iconv_cd = malloc(sizeof(iconv_t *));
- }
+ iconv_cd = realloc(iconv_cd, sizeof(iconv_t *) * (iconv_count + 1));
if (!iconv_cd) {
CRIT_ERR("Out of memory");
}
tcp_port_monitor_args_t tcp_port_monitor_args;
#endif
-static char *text = 0;
-long text_lines;
+static char *global_text = 0;
+long global_text_lines;
static int total_updates;
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
long arg;
double *graph;
double graph_scale;
+ short show_scale;
int graph_width;
int scaled;
unsigned long first_colour; // for graph gradient
static char *scan_font(const char *args)
{
if (args && *args) {
- return strdup(args);
+ return strndup(args, DEFAULT_TEXT_BUFFER_SIZE);
}
return NULL;
}
}
#endif
-
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;
}
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
} */
if (s->scaled) {
s->graph_scale = 1;
+ s->show_scale = 1;
} else {
s->graph_scale = scale;
+ s->show_scale = 0;
}
if (append) {
graph_append(s, i);
unsigned int *scale)
{
char buf[64];
+ buf[0] = 0;
/* zero width means all space that is available */
*w = 0;
*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;
}
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);
+ return strndup(buf, text_buffer_size);
}
*scale = 0;
if (sscanf(args, "%63s %d,%d %x %x", buf, h, w, first_colour,
last_colour) == 5) {
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
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);
+ return strndup(buf, text_buffer_size);
}
*scale = 0;
if (sscanf(args, "%63s %x %x", buf, first_colour, last_colour) == 3) {
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
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);
}
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
if (buf[0] == '\0') {
return NULL;
} else {
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
}
new_special(buf, ALIGNR)->arg = c;
}
+// A postive offset pushes the text further left
static inline void new_alignc(char *buf, long c)
{
new_special(buf, ALIGNC)->arg = c;
/* 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 *, int, const char *, int, const char *, ...)
+ __attribute__((format(printf, 3, 6)));
+
+static int spaced_print(char *buf, int size, const char *format, int width,
+ const char *func_name, ...) {
int len;
va_list argp;
+ char *tempbuf;
+
if (size < 1) {
return 0;
}
- char *tempbuf = malloc(size * sizeof(char));
+ tempbuf = malloc(size * sizeof(char));
// Passes the varargs along to vsnprintf
va_start(argp, func_name);
}
/* 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;
OBJ_cpu,
OBJ_cpubar,
OBJ_cpugraph,
+ OBJ_loadgraph,
OBJ_diskio,
OBJ_diskio_read,
OBJ_diskio_write,
OBJ_memgraph,
OBJ_memmax,
OBJ_memperc,
+ OBJ_mem_res,
+ OBJ_mem_vsize,
OBJ_mixer,
OBJ_mixerl,
OBJ_mixerr,
OBJ_nameserver,
OBJ_new_mails,
OBJ_nodename,
+ OBJ_nvidia,
OBJ_pre_exec,
OBJ_processes,
OBJ_running_processes,
char *addr;
int port;
char *dev;
+ double update_time;
+ char *temp;
+ char unit;
} hddtemp; /* 2 */
#endif
#ifdef RSS
} rss;
#endif
struct local_mail_s local_mail;
+#ifdef NVIDIA
+ struct nvidia_s nvidia;
+#endif /* NVIDIA */
+
} data;
int type;
int a, b;
struct text_object *text_objects;
};
-static unsigned int text_object_count;
-static struct text_object *text_objects;
+static struct text_object_list *global_text_object_list;
+
static void generate_text_internal(char *p, int p_max_size,
- struct text_object *objs, unsigned int object_count,
+ struct text_object_list *text_object_list,
struct information *cur);
#define MAXDATASIZE 1000
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) {
}
tmp = strstr(arg, "-e ");
if (tmp) {
- tmp += 3;
int len = 1024;
+ tmp += 3;
if (tmp[0] == '\'') {
len = strstr(tmp + 1, "'") - tmp - 1;
return mail;
}
-void *imap_thread(struct mail_s *mail)
+void *imap_thread(void *arg)
{
int sockfd, numbytes;
char recvbuf[MAXDATASIZE];
unsigned int old_unseen = UINT_MAX;
unsigned int old_messages = UINT_MAX;
struct stat stat_buf;
- struct hostent *he;
+ struct hostent he, *he_res = 0;
+ int he_errno;
+ char hostbuff[2048];
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
+#ifdef HAVE_GETHOSTBYNAME_R
+ if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
+ ERR("IMAP gethostbyname_r: %s", hstrerror(h_errno));
+ exit(1);
+ }
+#else /* HAVE_GETHOSTBYNAME_R */
+ if ((he_res = gethostbyname(mail->host)) == NULL) { // get the host info
herror("gethostbyname");
exit(1);
}
+#endif /* HAVE_GETHOSTBYNAME_R */
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);
- }
- if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
- perror("socket");
- fail++;
- goto next_iteration;
+ mail->user, mail->host, fail + 1);
}
+ do {
+ if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+ perror("socket");
+ fail++;
+ break;
+ }
- // host byte order
- their_addr.sin_family = AF_INET;
- // short, network byte order
- their_addr.sin_port = htons(mail->port);
- their_addr.sin_addr = *((struct in_addr *) he->h_addr);
- // zero the rest of the struct
- memset(&(their_addr.sin_zero), '\0', 8);
+ // host byte order
+ their_addr.sin_family = AF_INET;
+ // short, network byte order
+ their_addr.sin_port = htons(mail->port);
+ their_addr.sin_addr = *((struct in_addr *) he_res->h_addr);
+ // zero the rest of the struct
+ memset(&(their_addr.sin_zero), '\0', 8);
- if (connect(sockfd, (struct sockaddr *) &their_addr,
- sizeof(struct sockaddr)) == -1) {
- perror("connect");
- fail++;
- goto next_iteration;
- }
- struct timeval timeout;
- int res;
- fd_set fdset;
+ if (connect(sockfd, (struct sockaddr *) &their_addr,
+ sizeof(struct sockaddr)) == -1) {
+ perror("connect");
+ fail++;
+ break;
+ }
- timeout.tv_sec = 60; // 60 second timeout i guess
- timeout.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
- if (res > 0) {
- if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
- perror("recv");
+ timeout.tv_sec = 60; // 60 second timeout i guess
+ timeout.tv_usec = 0;
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
+ if (res > 0) {
+ if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
+ perror("recv");
+ fail++;
+ break;
+ }
+ } else {
+ ERR("IMAP connection failed: timeout");
fail++;
- goto next_iteration;
+ break;
}
- } else {
- ERR("IMAP connection failed: timeout");
- fail++;
- goto next_iteration;
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "* OK") != recvbuf) {
- ERR("IMAP connection failed, probably not an IMAP server");
- fail++;
- goto next_iteration;
- }
- strncpy(sendbuf, "a1 login ", MAXDATASIZE);
- strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1);
- strncat(sendbuf, " ", MAXDATASIZE - strlen(sendbuf) - 1);
- strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1);
- strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1);
- if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
- perror("send a1");
- fail++;
- goto next_iteration;
- }
- timeout.tv_sec = 60; // 60 second timeout i guess
- timeout.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
- if (res > 0) {
- if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
- perror("recv a1");
+ recvbuf[numbytes] = '\0';
+ if (strstr(recvbuf, "* OK") != recvbuf) {
+ ERR("IMAP connection failed, probably not an IMAP server");
fail++;
- goto next_iteration;
- }
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "a1 OK") == NULL) {
- ERR("IMAP server login failed: %s", recvbuf);
- fail++;
- goto next_iteration;
- }
- strncpy(sendbuf, "a2 STATUS ", MAXDATASIZE);
- strncat(sendbuf, mail->folder, MAXDATASIZE - strlen(sendbuf) - 1);
- strncat(sendbuf, " (MESSAGES UNSEEN)\r\n",
- MAXDATASIZE - strlen(sendbuf) - 1);
- if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
- perror("send a2");
- fail++;
- goto next_iteration;
- }
- timeout.tv_sec = 60; // 60 second timeout i guess
- timeout.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
- if (res > 0) {
- if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
- perror("recv a2");
+ break;
+ }
+ strncpy(sendbuf, "a1 login ", MAXDATASIZE);
+ strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1);
+ strncat(sendbuf, " ", MAXDATASIZE - strlen(sendbuf) - 1);
+ strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1);
+ strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1);
+ if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
+ perror("send a1");
fail++;
- goto next_iteration;
- }
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "a2 OK") == NULL) {
- ERR("IMAP status failed: %s", recvbuf);
- fail++;
- goto next_iteration;
- }
- // now we get the data
- reply = strstr(recvbuf, " (MESSAGES ");
- reply += 2;
- *strchr(reply, ')') = '\0';
- if (reply == NULL) {
- ERR("Error parsing IMAP response: %s", recvbuf);
- fail++;
- goto next_iteration;
- } else {
- timed_thread_lock(mail->p_timed_thread);
- sscanf(reply, "MESSAGES %lu UNSEEN %lu", &mail->messages,
- &mail->unseen);
- timed_thread_unlock(mail->p_timed_thread);
- }
- strncpy(sendbuf, "a3 logout\r\n", MAXDATASIZE);
- if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
- perror("send a3");
- fail++;
- goto next_iteration;
- }
- timeout.tv_sec = 60; // 60 second timeout i guess
- timeout.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
- if (res > 0) {
- if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
- perror("recv a3");
+ break;
+ }
+ timeout.tv_sec = 60; // 60 second timeout i guess
+ timeout.tv_usec = 0;
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
+ if (res > 0) {
+ if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
+ perror("recv a1");
+ fail++;
+ break;
+ }
+ }
+ recvbuf[numbytes] = '\0';
+ if (strstr(recvbuf, "a1 OK") == NULL) {
+ ERR("IMAP server login failed: %s", recvbuf);
fail++;
- goto next_iteration;
+ break;
}
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "a3 OK") == NULL) {
- ERR("IMAP logout failed: %s", recvbuf);
- fail++;
- goto next_iteration;
- }
- if (strlen(mail->command) > 1 && (mail->unseen > old_unseen
- || (mail->messages > old_messages && mail->unseen > 0))) {
- // new mail goodie
- if (system(mail->command) == -1) {
- perror("system()");
+ strncpy(sendbuf, "a2 STATUS ", MAXDATASIZE);
+ strncat(sendbuf, mail->folder, MAXDATASIZE - strlen(sendbuf) - 1);
+ strncat(sendbuf, " (MESSAGES UNSEEN)\r\n",
+ MAXDATASIZE - strlen(sendbuf) - 1);
+ if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
+ perror("send a2");
+ fail++;
+ break;
}
- }
- fail = 0;
- old_unseen = mail->unseen;
- old_messages = mail->messages;
-next_iteration:
+ timeout.tv_sec = 60; // 60 second timeout i guess
+ timeout.tv_usec = 0;
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
+ if (res > 0) {
+ if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
+ perror("recv a2");
+ fail++;
+ break;
+ }
+ }
+ recvbuf[numbytes] = '\0';
+ if (strstr(recvbuf, "a2 OK") == NULL) {
+ ERR("IMAP status failed: %s", recvbuf);
+ fail++;
+ break;
+ }
+ // now we get the data
+ reply = strstr(recvbuf, " (MESSAGES ");
+ reply += 2;
+ *strchr(reply, ')') = '\0';
+ if (reply == NULL) {
+ ERR("Error parsing IMAP response: %s", recvbuf);
+ fail++;
+ break;
+ } else {
+ timed_thread_lock(mail->p_timed_thread);
+ sscanf(reply, "MESSAGES %lu UNSEEN %lu", &mail->messages,
+ &mail->unseen);
+ timed_thread_unlock(mail->p_timed_thread);
+ }
+ strncpy(sendbuf, "a3 logout\r\n", MAXDATASIZE);
+ if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
+ perror("send a3");
+ fail++;
+ break;
+ }
+ timeout.tv_sec = 60; // 60 second timeout i guess
+ timeout.tv_usec = 0;
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
+ if (res > 0) {
+ if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
+ perror("recv a3");
+ fail++;
+ break;
+ }
+ }
+ recvbuf[numbytes] = '\0';
+ if (strstr(recvbuf, "a3 OK") == NULL) {
+ ERR("IMAP logout failed: %s", recvbuf);
+ fail++;
+ break;
+ }
+ if (strlen(mail->command) > 1 && (mail->unseen > old_unseen
+ || (mail->messages > old_messages && mail->unseen > 0))) {
+ // new mail goodie
+ if (system(mail->command) == -1) {
+ perror("system()");
+ }
+ }
+ fail = 0;
+ old_unseen = mail->unseen;
+ old_messages = mail->messages;
+ } while (0);
if ((fstat(sockfd, &stat_buf) == 0) && S_ISSOCK(stat_buf.st_mode)) {
/* if a valid socket, close it */
close(sockfd);
return 0;
}
-void *pop3_thread(struct mail_s *mail)
+void *pop3_thread(void *arg)
{
int sockfd, numbytes;
char recvbuf[MAXDATASIZE];
int fail = 0;
unsigned int old_unseen = UINT_MAX;
struct stat stat_buf;
- struct hostent *he;
+ struct hostent he, *he_res = 0;
+ int he_errno;
+ char hostbuff[2048];
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
+#ifdef HAVE_GETHOSTBYNAME_R
+ if (gethostbyname_r(mail->host, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
+ ERR("POP3 gethostbyname_r: %s", hstrerror(h_errno));
+ exit(1);
+ }
+#else /* HAVE_GETHOSTBYNAME_R */
+ if ((he_res = gethostbyname(mail->host)) == NULL) { // get the host info
herror("gethostbyname");
exit(1);
}
+#endif /* HAVE_GETHOSTBYNAME_R */
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);
- }
- if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
- perror("socket");
- fail++;
- goto next_iteration;
+ mail->user, mail->host, fail + 1);
}
+ do {
+ if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+ perror("socket");
+ fail++;
+ break;
+ }
- // host byte order
- their_addr.sin_family = AF_INET;
- // short, network byte order
- their_addr.sin_port = htons(mail->port);
- their_addr.sin_addr = *((struct in_addr *) he->h_addr);
- // zero the rest of the struct
- memset(&(their_addr.sin_zero), '\0', 8);
+ // host byte order
+ their_addr.sin_family = AF_INET;
+ // short, network byte order
+ their_addr.sin_port = htons(mail->port);
+ their_addr.sin_addr = *((struct in_addr *) he_res->h_addr);
+ // zero the rest of the struct
+ memset(&(their_addr.sin_zero), '\0', 8);
- if (connect(sockfd, (struct sockaddr *) &their_addr,
- sizeof(struct sockaddr)) == -1) {
- perror("connect");
- fail++;
- goto next_iteration;
- }
- struct timeval timeout;
- int res;
- fd_set fdset;
+ if (connect(sockfd, (struct sockaddr *) &their_addr,
+ sizeof(struct sockaddr)) == -1) {
+ perror("connect");
+ fail++;
+ break;
+ }
- timeout.tv_sec = 60; // 60 second timeout i guess
- timeout.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
- if (res > 0) {
- if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
- perror("recv");
+ timeout.tv_sec = 60; // 60 second timeout i guess
+ timeout.tv_usec = 0;
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
+ if (res > 0) {
+ if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
+ perror("recv");
+ fail++;
+ break;
+ }
+ } else {
+ ERR("POP3 connection failed: timeout\n");
fail++;
- goto next_iteration;
+ break;
}
- } else {
- ERR("POP3 connection failed: timeout\n");
- fail++;
- goto next_iteration;
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "+OK ") != recvbuf) {
- ERR("POP3 connection failed, probably not a POP3 server");
- fail++;
- goto next_iteration;
- }
- strncpy(sendbuf, "USER ", MAXDATASIZE);
- strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1);
- strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1);
- if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
- perror("send USER");
- fail++;
- goto next_iteration;
- }
- timeout.tv_sec = 60; // 60 second timeout i guess
- timeout.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
- if (res > 0) {
- if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
- perror("recv USER");
+ recvbuf[numbytes] = '\0';
+ if (strstr(recvbuf, "+OK ") != recvbuf) {
+ ERR("POP3 connection failed, probably not a POP3 server");
+ fail++;
+ break;
+ }
+ strncpy(sendbuf, "USER ", MAXDATASIZE);
+ strncat(sendbuf, mail->user, MAXDATASIZE - strlen(sendbuf) - 1);
+ strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1);
+ if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
+ perror("send USER");
fail++;
- goto next_iteration;
- }
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "+OK ") == NULL) {
- ERR("POP3 server login failed: %s", recvbuf);
- fail++;
- goto next_iteration;
- }
- strncpy(sendbuf, "PASS ", MAXDATASIZE);
- strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1);
- strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1);
- if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
- perror("send PASS");
- fail++;
- goto next_iteration;
- }
- timeout.tv_sec = 60; // 60 second timeout i guess
- timeout.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
- if (res > 0) {
- if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
- perror("recv PASS");
+ break;
+ }
+ timeout.tv_sec = 60; // 60 second timeout i guess
+ timeout.tv_usec = 0;
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
+ if (res > 0) {
+ if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
+ perror("recv USER");
+ fail++;
+ break;
+ }
+ }
+ recvbuf[numbytes] = '\0';
+ if (strstr(recvbuf, "+OK ") == NULL) {
+ ERR("POP3 server login failed: %s", recvbuf);
fail++;
- goto next_iteration;
- }
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "+OK ") == NULL) {
- ERR("POP3 server login failed: %s", recvbuf);
- fail++;
- goto next_iteration;
- }
- strncpy(sendbuf, "STAT\r\n", MAXDATASIZE);
- if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
- perror("send STAT");
- fail++;
- goto next_iteration;
- }
- timeout.tv_sec = 60; // 60 second timeout i guess
- timeout.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
- if (res > 0) {
- if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
- perror("recv STAT");
+ break;
+ }
+ strncpy(sendbuf, "PASS ", MAXDATASIZE);
+ strncat(sendbuf, mail->pass, MAXDATASIZE - strlen(sendbuf) - 1);
+ strncat(sendbuf, "\r\n", MAXDATASIZE - strlen(sendbuf) - 1);
+ if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
+ perror("send PASS");
fail++;
- goto next_iteration;
+ break;
}
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "+OK ") == NULL) {
- ERR("POP3 status failed: %s", recvbuf);
- fail++;
- goto next_iteration;
- }
- // now we get the data
- reply = recvbuf + 4;
- if (reply == NULL) {
- ERR("Error parsing POP3 response: %s", recvbuf);
- fail++;
- goto next_iteration;
- } else {
- timed_thread_lock(mail->p_timed_thread);
- sscanf(reply, "%lu %lu", &mail->unseen, &mail->used);
- timed_thread_unlock(mail->p_timed_thread);
- }
- strncpy(sendbuf, "QUIT\r\n", MAXDATASIZE);
- if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
- perror("send QUIT");
- fail++;
- goto next_iteration;
- }
- timeout.tv_sec = 60; // 60 second timeout i guess
- timeout.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(sockfd, &fdset);
- res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
- if (res > 0) {
- if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
- perror("recv QUIT");
+ timeout.tv_sec = 60; // 60 second timeout i guess
+ timeout.tv_usec = 0;
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
+ if (res > 0) {
+ if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
+ perror("recv PASS");
+ fail++;
+ break;
+ }
+ }
+ recvbuf[numbytes] = '\0';
+ if (strstr(recvbuf, "+OK ") == NULL) {
+ ERR("POP3 server login failed: %s", recvbuf);
fail++;
- goto next_iteration;
+ break;
}
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "+OK") == NULL) {
- ERR("POP3 logout failed: %s", recvbuf);
- fail++;
- goto next_iteration;
- }
- if (strlen(mail->command) > 1 && mail->unseen > old_unseen) {
- // new mail goodie
- if (system(mail->command) == -1) {
- perror("system()");
+ strncpy(sendbuf, "STAT\r\n", MAXDATASIZE);
+ if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
+ perror("send STAT");
+ fail++;
+ break;
}
- }
- fail = 0;
- old_unseen = mail->unseen;
-next_iteration:
+ timeout.tv_sec = 60; // 60 second timeout i guess
+ timeout.tv_usec = 0;
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
+ if (res > 0) {
+ if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
+ perror("recv STAT");
+ fail++;
+ break;
+ }
+ }
+ recvbuf[numbytes] = '\0';
+ if (strstr(recvbuf, "+OK ") == NULL) {
+ ERR("POP3 status failed: %s", recvbuf);
+ fail++;
+ break;
+ }
+ // now we get the data
+ reply = recvbuf + 4;
+ if (reply == NULL) {
+ ERR("Error parsing POP3 response: %s", recvbuf);
+ fail++;
+ break;
+ } else {
+ timed_thread_lock(mail->p_timed_thread);
+ sscanf(reply, "%lu %lu", &mail->unseen, &mail->used);
+ timed_thread_unlock(mail->p_timed_thread);
+ }
+ strncpy(sendbuf, "QUIT\r\n", MAXDATASIZE);
+ if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
+ perror("send QUIT");
+ fail++;
+ break;
+ }
+ timeout.tv_sec = 60; // 60 second timeout i guess
+ timeout.tv_usec = 0;
+ FD_ZERO(&fdset);
+ FD_SET(sockfd, &fdset);
+ res = select(sockfd + 1, &fdset, NULL, NULL, &timeout);
+ if (res > 0) {
+ if ((numbytes = recv(sockfd, recvbuf, MAXDATASIZE - 1, 0)) == -1) {
+ perror("recv QUIT");
+ fail++;
+ break;
+ }
+ }
+ recvbuf[numbytes] = '\0';
+ if (strstr(recvbuf, "+OK") == NULL) {
+ ERR("POP3 logout failed: %s", recvbuf);
+ fail++;
+ break;
+ }
+ if (strlen(mail->command) > 1 && mail->unseen > old_unseen) {
+ // new mail goodie
+ if (system(mail->command) == -1) {
+ perror("system()");
+ }
+ }
+ fail = 0;
+ old_unseen = mail->unseen;
+ } while (0);
if ((fstat(sockfd, &stat_buf) == 0) && S_ISSOCK(stat_buf.st_mode)) {
/* if a valid socket, close it */
close(sockfd);
return 0;
}
-void *threaded_exec(struct text_object *obj)
+void *threaded_exec(void *) __attribute__((noreturn));
+
+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, text_buffer_size, fp);
+ n2 = fread(p2, 1, text_buffer_size, fp);
pclose(fp);
p2[n2] = '\0';
timed_thread_exit(obj->data.texeci.p_timed_thread);
}
}
- return 0;
+ /* never reached */
}
-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));
return obj;
}
-static void free_text_objects(unsigned int count, struct text_object *objs)
+static void free_text_objects(struct text_object_list *text_object_list)
{
unsigned int i;
+ struct text_object *obj;
+
+ if (text_object_list == NULL) {
+ return;
+ }
- for (i = 0; i < count; i++) {
- switch (objs[i].type) {
+ for (i = 0; i < text_object_list->text_object_count; i++) {
+ obj = &text_object_list->text_objects[i];
+ switch (obj->type) {
#ifndef __OpenBSD__
case OBJ_acpitemp:
case OBJ_acpitempf:
- close(objs[i].data.i);
+ close(obj->data.i);
break;
case OBJ_i2c:
case OBJ_platform:
case OBJ_hwmon:
- close(objs[i].data.sysfs.fd);
+ close(obj->data.sysfs.fd);
break;
#endif /* !__OpenBSD__ */
case OBJ_time:
case OBJ_utime:
- free(objs[i].data.s);
+ free(obj->data.s);
break;
case OBJ_tztime:
- free(objs[i].data.tztime.tz);
- free(objs[i].data.tztime.fmt);
+ free(obj->data.tztime.tz);
+ free(obj->data.tztime.fmt);
break;
case OBJ_mboxscan:
- free(objs[i].data.mboxscan.args);
- free(objs[i].data.mboxscan.output);
+ free(obj->data.mboxscan.args);
+ free(obj->data.mboxscan.output);
break;
case OBJ_mails:
case OBJ_new_mails:
- free(objs[i].data.local_mail.box);
+ free(obj->data.local_mail.box);
break;
case OBJ_imap:
free(info.mail);
break;
case OBJ_imap_unseen:
- if (!objs[i].global_mode) {
- free(objs[i].data.mail);
+ if (!obj->global_mode) {
+ free(obj->data.mail);
}
break;
case OBJ_imap_messages:
- if (!objs[i].global_mode) {
- free(objs[i].data.mail);
+ if (!obj->global_mode) {
+ free(obj->data.mail);
}
break;
case OBJ_pop3:
free(info.mail);
break;
case OBJ_pop3_unseen:
- if (!objs[i].global_mode) {
- free(objs[i].data.mail);
+ if (!obj->global_mode) {
+ free(obj->data.mail);
}
break;
case OBJ_pop3_used:
- if (!objs[i].global_mode) {
- free(objs[i].data.mail);
+ if (!obj->global_mode) {
+ free(obj->data.mail);
}
break;
case OBJ_if_empty:
case OBJ_if_existing:
case OBJ_if_mounted:
case OBJ_if_running:
- free(objs[i].data.ifblock.s);
- free(objs[i].data.ifblock.str);
+ free(obj->data.ifblock.s);
+ free(obj->data.ifblock.str);
break;
case OBJ_tail:
- free(objs[i].data.tail.logfile);
- free(objs[i].data.tail.buffer);
+ free(obj->data.tail.logfile);
+ free(obj->data.tail.buffer);
break;
case OBJ_text:
case OBJ_font:
case OBJ_execbar:
case OBJ_execgraph:
case OBJ_execp:
- free(objs[i].data.s);
+ free(obj->data.s);
break;
#ifdef HAVE_ICONV
case OBJ_iconv_start:
#endif
#ifdef RSS
case OBJ_rss:
- free(objs[i].data.rss.uri);
- free(objs[i].data.rss.action);
+ free(obj->data.rss.uri);
+ free(obj->data.rss.action);
break;
#endif
case OBJ_pre_exec:
break;
#ifndef __OpenBSD__
case OBJ_battery:
- free(objs[i].data.s);
+ free(obj->data.s);
break;
case OBJ_battery_time:
- free(objs[i].data.s);
+ free(obj->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);
+ free(obj->data.execi.cmd);
+ free(obj->data.execi.buffer);
break;
case OBJ_texeci:
- free(objs[i].data.texeci.cmd);
- free(objs[i].data.texeci.buffer);
+ free(obj->data.texeci.cmd);
+ free(obj->data.texeci.buffer);
break;
case OBJ_nameserver:
free_dns_data();
break;
#ifdef HDDTEMP
case OBJ_hddtemp:
- free(objs[i].data.hddtemp.dev);
- free(objs[i].data.hddtemp.addr);
+ free(obj->data.hddtemp.dev);
+ free(obj->data.hddtemp.addr);
+ free(obj->data.hddtemp.temp);
break;
#endif
case OBJ_entropy_avail:
#ifdef SMAPI
case OBJ_smapi:
case OBJ_smapi_bat_perc:
- free(objs[i].data.s);
+ free(obj->data.s);
break;
case OBJ_if_smapi_bat_installed:
- free(objs[i].data.ifblock.s);
- free(objs[i].data.ifblock.str);
+ free(obj->data.ifblock.s);
+ free(obj->data.ifblock.str);
+ break;
+#endif
+#ifdef NVIDIA
+ case OBJ_nvidia:
break;
#endif
#ifdef MPD
case OBJ_mpd_file:
case OBJ_mpd_percent:
case OBJ_mpd_smart:
- free_mpd_vars(&info);
+ free_mpd_vars(&info.mpd);
break;
#endif
}
}
- free(objs);
- /* text_objects = NULL;
- text_object_count = 0; */
+ free(text_object_list->text_objects);
+ text_object_list->text_objects = NULL;
+ text_object_list->text_object_count = 0;
}
void scan_mixer_bar(const char *arg, int *a, int *w, int *h)
}
}
+/* strip a leading /dev/ if any */
+#define DEV_NAME(x) x != NULL && strlen(x) > 5 && strncmp(x, "/dev/", 5) == 0 \
+ ? x + 5 : x
+
/* construct_text_object() creates a new text_object */
static struct text_object *construct_text_object(const char *s,
const char *arg, unsigned int object_count,
} else {
strcpy(bat, "BAT0");
}
- obj->data.s = strdup(bat);
+ obj->data.s = strndup(bat, text_buffer_size);
END OBJ(battery_time, 0)
char bat[64];
} else {
strcpy(bat, "BAT0");
}
- obj->data.s = strdup(bat);
+ obj->data.s = strndup(bat, text_buffer_size);
END OBJ(battery_percent, 0)
char bat[64];
} else {
strcpy(bat, "BAT0");
}
- obj->data.s = strdup(bat);
+ obj->data.s = strndup(bat, text_buffer_size);
END OBJ(battery_bar, 0)
char bat[64];
obj->b = 6;
} else {
strcpy(bat, "BAT0");
}
- obj->data.s = strdup(bat);
+ obj->data.s = strndup(bat, text_buffer_size);
#endif /* !__OpenBSD__ */
#if defined(__linux__)
END OBJ(disk_protect, 0)
if (arg)
- obj->data.s = strdup(arg);
+ obj->data.s = strndup(DEV_NAME(arg), text_buffer_size);
else
CRIT_ERR("disk_protect needs an argument");
END OBJ(i8k_version, INFO_I8K)
ERR("if_up needs an argument");
obj->data.ifblock.s = 0;
} else
- obj->data.ifblock.s = strdup(arg);
+ obj->data.ifblock.s = strndup(arg, text_buffer_size);
blockstart[blockdepth] = object_count;
obj->data.ifblock.pos = object_count + 2;
blockdepth++;
CRIT_ERR("get_ioscheduler needs an argument (e.g. hda)");
obj->data.s = 0;
} else
- obj->data.s = strdup(arg);
+ obj->data.s = strndup(DEV_NAME(arg), text_buffer_size);
END OBJ(laptop_mode, 0)
END OBJ(pb_battery, 0)
if (arg && strcmp(arg, "status") == 0) {
}
free(buf);
}
+ END OBJ(loadgraph, INFO_LOADAVG)
+ char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
+ &obj->e);
+ if (buf) {
+ int a = 1, r = 3;
+ if (arg) {
+ r = sscanf(arg, "%d", &a);
+ }
+ obj->data.loadavg[0] = (r >= 1) ? (unsigned char) a : 0;
+ free(buf);
+ }
+#if defined(__linux__)
END OBJ(diskio, INFO_DISKIO)
if (arg) {
- obj->data.diskio = prepare_diskio_stat(arg);
+ obj->data.diskio = prepare_diskio_stat(DEV_NAME(arg));
} else {
obj->data.diskio = NULL;
}
END OBJ(diskio_read, INFO_DISKIO)
if (arg) {
- obj->data.diskio = prepare_diskio_stat(arg);
+ obj->data.diskio = prepare_diskio_stat(DEV_NAME(arg));
} else {
obj->data.diskio = NULL;
}
END OBJ(diskio_write, INFO_DISKIO)
if (arg) {
- obj->data.diskio = prepare_diskio_stat(arg);
+ obj->data.diskio = prepare_diskio_stat(DEV_NAME(arg));
} else {
obj->data.diskio = NULL;
}
END OBJ(diskiograph, INFO_DISKIO)
- char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
+ char *buf = scan_graph(DEV_NAME(arg), &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
obj->data.diskio = NULL;
}
END OBJ(diskiograph_read, INFO_DISKIO)
- char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
+ char *buf = scan_graph(DEV_NAME(arg), &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
obj->data.diskio = NULL;
}
END OBJ(diskiograph_write, INFO_DISKIO)
- char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
+ char *buf = scan_graph(DEV_NAME(arg), &obj->a, &obj->b, &obj->c, &obj->d,
&obj->e);
if (buf) {
} else {
obj->data.diskio = NULL;
}
+#endif
END OBJ(color, 0)
#ifdef X11
obj->data.l = arg ? get_x11_color(arg) : default_fg_color;
ERR("$endif: no matching $if_*");
}
END OBJ(image, 0)
- obj->data.s = strdup(arg ? arg : "");
+ obj->data.s = strndup(arg ? arg : "", text_buffer_size);
#ifdef HAVE_POPEN
END OBJ(exec, 0)
- obj->data.s = strdup(arg ? arg : "");
+ obj->data.s = strndup(arg ? arg : "", text_buffer_size);
END OBJ(execp, 0)
- obj->data.s = strdup(arg ? arg : "");
+ obj->data.s = strndup(arg ? arg : "", text_buffer_size);
END OBJ(execbar, 0)
- obj->data.s = strdup(arg ? arg : "");
+ obj->data.s = strndup(arg ? arg : "", text_buffer_size);
END OBJ(execgraph, 0)
- obj->data.s = strdup(arg ? arg : "");
+ obj->data.s = strndup(arg ? arg : "", text_buffer_size);
END OBJ(execibar, 0)
- unsigned int n;
+ int n;
if (!arg || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
char buf[256];
ERR("${execibar <interval> command}");
obj->type = OBJ_text;
snprintf(buf, 256, "${%s}", s);
- obj->data.s = strdup(buf);
+ obj->data.s = strndup(buf, text_buffer_size);
} else {
- obj->data.execi.cmd = strdup(arg + n);
+ obj->data.execi.cmd = strndup(arg + n, text_buffer_size);
}
END OBJ(execigraph, 0)
- unsigned int n;
+ int n;
if (!arg || sscanf(arg, "%f %n", &obj->data.execi.interval, &n) <= 0) {
char buf[256];
ERR("${execigraph <interval> command}");
obj->type = OBJ_text;
snprintf(buf, 256, "${%s}", s);
- obj->data.s = strdup(buf);
+ obj->data.s = strndup(buf, text_buffer_size);
} else {
- obj->data.execi.cmd = strdup(arg + n);
+ obj->data.execi.cmd = strndup(arg + n, text_buffer_size);
}
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);
+ obj->data.s = strndup(buf, text_buffer_size);
} else {
- obj->data.execi.cmd = strdup(arg + n);
+ obj->data.execi.cmd = strndup(arg + n, text_buffer_size);
obj->data.execi.buffer = malloc(text_buffer_size);
}
END OBJ(execpi, 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);
+ obj->data.s = strndup(buf, text_buffer_size);
} else {
- obj->data.execi.cmd = strdup(arg + n);
+ obj->data.execi.cmd = strndup(arg + n, 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];
ERR("${texeci <interval> command}");
obj->type = OBJ_text;
snprintf(buf, 256, "${%s}", s);
- obj->data.s = strdup(buf);
+ obj->data.s = strndup(buf, text_buffer_size);
} else {
- obj->data.texeci.cmd = strdup(arg + n);
+ obj->data.texeci.cmd = strndup(arg + n, text_buffer_size);
obj->data.texeci.buffer = malloc(text_buffer_size);
}
obj->data.texeci.p_timed_thread = NULL;
pclose(fp);
- obj->data.s = strdup(buf);
+ obj->data.s = strndup(buf, text_buffer_size);
} else {
- obj->data.s = strdup("");
+ obj->data.s = strndup("", text_buffer_size);
}
#endif
END OBJ(fs_bar, INFO_FS)
if (!arg) {
ERR("goto needs arguments");
obj->type = OBJ_text;
- obj->data.s = strdup("${goto}");
+ obj->data.s = strndup("${goto}", text_buffer_size);
return NULL;
}
if (!arg) {
ERR("i2c needs arguments");
obj->type = OBJ_text;
- // obj->data.s = strdup("${i2c}");
+ // obj->data.s = strndup("${i2c}", text_buffer_size);
return NULL;
}
if (!arg) {
ERR("top needs arguments");
obj->type = OBJ_text;
- // obj->data.s = strdup("${top}");
+ // obj->data.s = strndup("${top}", text_buffer_size);
return NULL;
}
if (sscanf(arg, "%63s %i", buf, &n) == 2) {
obj->data.top.type = TOP_MEM;
} else if (strcmp(buf, "time") == 0) {
obj->data.top.type = TOP_TIME;
+ } else if (strcmp(buf, "mem_res") == 0) {
+ obj->data.top.type = TOP_MEM_RES;
+ } else if (strcmp(buf, "mem_vsize") == 0) {
+ obj->data.top.type = TOP_MEM_VSIZE;
} else {
ERR("invalid arg for top");
return NULL;
ERR("invalid args given for top");
return NULL;
}
- END OBJ(top_mem, INFO_TOP)
- char buf[64];
+ END OBJ(top_mem, INFO_TOP)
+ char buf[64];
int n;
if (!arg) {
ERR("top_mem needs arguments");
obj->type = OBJ_text;
- obj->data.s = strdup("${top_mem}");
+ obj->data.s = strndup("${top_mem}", text_buffer_size);
return NULL;
}
if (sscanf(arg, "%63s %i", buf, &n) == 2) {
obj->data.top.type = TOP_MEM;
} else if (strcmp(buf, "time") == 0) {
obj->data.top.type = TOP_TIME;
+ } else if (strcmp(buf, "mem_res") == 0) {
+ obj->data.top.type = TOP_MEM_RES;
+ } else if (strcmp(buf, "mem_vsize") == 0) {
+ obj->data.top.type = TOP_MEM_VSIZE;
} else {
ERR("invalid arg for top");
return NULL;
}
if (n < 1 || n > 10) {
- CRIT_ERR("invalid arg for top");
+ CRIT_ERR("invalid arg for top");
return NULL;
} else {
obj->data.top.num = n - 1;
ERR("invalid args given for top");
return NULL;
}
- END OBJ(addr, INFO_NET)
- if (arg) {
- obj->data.net = get_net_stat(arg);
- } else {
- CRIT_ERR("addr needs argument");
- }
+ END OBJ(addr, INFO_NET)
+ if (arg) {
+ obj->data.net = get_net_stat(arg);
+ } else {
+ CRIT_ERR("addr needs argument");
+ }
#if defined(__linux__)
- END OBJ(addrs, INFO_NET)
- if (arg) {
- obj->data.net = get_net_stat(arg);
- } else {
- CRIT_ERR("addrs needs argument");
- }
+ END OBJ(addrs, INFO_NET)
+ if (arg) {
+ obj->data.net = get_net_stat(arg);
+ } else {
+ CRIT_ERR("addrs needs argument");
+ }
#endif /* __linux__ */
- END OBJ(tail, 0)
- char buf[64];
+ END OBJ(tail, 0)
+ char buf[64];
int n1, n2;
struct stat st;
if (!arg) {
ERR("tail needs arguments");
obj->type = OBJ_text;
- obj->data.s = strdup("${tail}");
+ obj->data.s = strndup("${tail}", text_buffer_size);
return NULL;
}
if (sscanf(arg, "%63s %i %i", buf, &n1, &n2) == 2) {
- if (n1 < 1 || n1 > 30) {
+ if (n1 < 1 || n1 > MAX_TAIL_LINES) {
CRIT_ERR("invalid arg for tail, number of lines must be "
- "between 1 and 30");
+ "between 1 and %i", MAX_TAIL_LINES);
return NULL;
} else {
FILE *fp = NULL;
}
}
} else if (sscanf(arg, "%63s %i %i", buf, &n1, &n2) == 3) {
- if (n1 < 1 || n1 > 30) {
+ if (n1 < 1 || n1 > MAX_TAIL_LINES) {
CRIT_ERR("invalid arg for tail, number of lines must be "
- "between 1 and 30");
+ "between 1 and %i", MAX_TAIL_LINES);
return NULL;
} else if (n2 < 1 || n2 < update_interval) {
CRIT_ERR("invalid arg for tail, interval must be greater than "
if (!arg) {
ERR("head needs arguments");
obj->type = OBJ_text;
- obj->data.s = strdup("${head}");
+ obj->data.s = strndup("${head}", text_buffer_size);
return NULL;
}
if (sscanf(arg, "%63s %i %i", buf, &n1, &n2) == 2) {
- if (n1 < 1 || n1 > 30) {
+ if (n1 < 1 || n1 > MAX_TAIL_LINES) {
CRIT_ERR("invalid arg for head, number of lines must be "
- "between 1 and 30");
+ "between 1 and %i", MAX_TAIL_LINES);
return NULL;
} else {
FILE *fp;
}
}
} else if (sscanf(arg, "%63s %i %i", buf, &n1, &n2) == 3) {
- if (n1 < 1 || n1 > 30) {
+ if (n1 < 1 || n1 > MAX_TAIL_LINES) {
CRIT_ERR("invalid arg for head, number of lines must be "
- "between 1 and 30");
+ "between 1 and %i", MAX_TAIL_LINES);
return NULL;
} else if (n2 < 1 || n2 < update_interval) {
CRIT_ERR("invalid arg for head, interval must be greater than "
ERR("if_empty needs an argument");
obj->data.ifblock.s = 0;
} else {
- obj->data.ifblock.s = strdup(arg);
+ obj->data.ifblock.s = strndup(arg, text_buffer_size);
}
blockstart[blockdepth] = object_count;
obj->data.ifblock.pos = object_count + 2;
int r = sscanf(arg, "%255s %255[^\n]", buf1, buf2);
if (r == 1) {
- obj->data.ifblock.s = strdup(buf1);
+ obj->data.ifblock.s = strndup(buf1, text_buffer_size);
obj->data.ifblock.str = NULL;
} else {
- obj->data.ifblock.s = strdup(buf1);
- obj->data.ifblock.str = strdup(buf2);
+ obj->data.ifblock.s = strndup(buf1, text_buffer_size);
+ obj->data.ifblock.str = strndup(buf2, text_buffer_size);
}
}
blockstart[blockdepth] = object_count;
ERR("if_mounted needs an argument");
obj->data.ifblock.s = 0;
} else {
- obj->data.ifblock.s = strdup(arg);
+ obj->data.ifblock.s = strndup(arg, text_buffer_size);
}
blockstart[blockdepth] = object_count;
obj->data.ifblock.pos = object_count + 2;
char buf[256];
snprintf(buf, 256, "pidof %s >/dev/null", arg);
- obj->data.ifblock.s = strdup(buf);
+ obj->data.ifblock.s = strndup(buf, text_buffer_size);
} else {
ERR("if_running needs an argument");
obj->data.ifblock.s = 0;
if (!arg) {
n1 = 9.5;
- strncpy(box, MAIL_FILE, sizeof(box));
+ /* Kapil: Changed from MAIL_FILE to
+ current_mail_spool since the latter
+ is a copy of the former if undefined
+ but the latter should take precedence
+ if defined */
+ strncpy(box, current_mail_spool, sizeof(box));
} else {
if (sscanf(arg, "%s %f", box, &n1) != 2) {
n1 = 9.5;
}
variable_substitute(box, dst, sizeof(dst));
- obj->data.local_mail.box = strdup(dst);
+ obj->data.local_mail.box = strndup(dst, text_buffer_size);
obj->data.local_mail.interval = n1;
END OBJ(mboxscan, 0)
obj->data.mboxscan.args = (char *) malloc(text_buffer_size);
if (!arg) {
n1 = 9.5;
- strncpy(box, MAIL_FILE, sizeof(box));
+ /* Kapil: Changed from MAIL_FILE to
+ current_mail_spool since the latter
+ is a copy of the former if undefined
+ but the latter should take precedence
+ if defined */
+ strncpy(box, current_mail_spool, sizeof(box));
} else {
if (sscanf(arg, "%s %f", box, &n1) != 2) {
n1 = 9.5;
}
variable_substitute(box, dst, sizeof(dst));
- obj->data.local_mail.box = strdup(dst);
+ obj->data.local_mail.box = strndup(dst, text_buffer_size);
obj->data.local_mail.interval = n1;
END OBJ(nodename, 0)
END OBJ(processes, INFO_PROCS)
&obj->data.sysfs.arg, obj->data.sysfs.devtype);
#endif
END OBJ(time, 0)
- obj->data.s = strdup(arg ? arg : "%F %T");
+ obj->data.s = strndup(arg ? arg : "%F %T", text_buffer_size);
END OBJ(utime, 0)
- obj->data.s = strdup(arg ? arg : "%F %T");
+ obj->data.s = strndup(arg ? arg : "%F %T", text_buffer_size);
END OBJ(tztime, 0)
char buf1[256], buf2[256], *fmt, *tz;
}
}
- obj->data.tztime.fmt = strdup(fmt ? fmt : "%F %T");
- obj->data.tztime.tz = tz ? strdup(tz) : NULL;
+ obj->data.tztime.fmt = strndup(fmt ? fmt : "%F %T", text_buffer_size);
+ obj->data.tztime.tz = tz ? strndup(tz, text_buffer_size) : NULL;
#ifdef HAVE_ICONV
END OBJ(iconv_start, 0)
if (iconv_converting) {
END OBJ(user_times, INFO_USERS)
END OBJ(user_terms, INFO_USERS)
END OBJ(user_number, INFO_USERS)
+#if defined(__linux__)
END OBJ(gw_iface, INFO_GW)
END OBJ(gw_ip, INFO_GW)
END OBJ(if_gw, INFO_GW)
+#endif /* !__linux__ */
#ifndef __OpenBSD__
END OBJ(adt746xcpu, 0)
END OBJ(adt746xfan, 0)
#ifdef SMAPI
END OBJ(smapi, 0)
if (arg)
- obj->data.s = strdup(arg);
+ obj->data.s = strndup(arg, text_buffer_size);
else
ERR("smapi needs an argument");
END OBJ(if_smapi_bat_installed, 0)
ERR("if_smapi_bat_installed needs an argument");
obj->data.ifblock.s = 0;
} else
- obj->data.ifblock.s = strdup(arg);
+ obj->data.ifblock.s = strndup(arg, text_buffer_size);
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);
+ obj->data.s = strndup(arg, text_buffer_size);
else
ERR("smapi_bat_perc needs an argument");
END OBJ(smapi_bat_bar, 0)
#ifdef HDDTEMP
END OBJ(hddtemp, 0)
if (!arg || scan_hddtemp(arg, &obj->data.hddtemp.dev,
- &obj->data.hddtemp.addr, &obj->data.hddtemp.port)) {
+ &obj->data.hddtemp.addr, &obj->data.hddtemp.port, &obj->data.hddtemp.temp)) {
ERR("hddtemp needs arguments");
obj->type = OBJ_text;
- obj->data.s = strdup("${hddtemp}");
+ obj->data.s = strndup("${hddtemp}", text_buffer_size);
+ obj->data.hddtemp.update_time = 0;
return NULL;
}
#endif
END OBJ(entropy_poolsize, INFO_ENTROPY)
END OBJ(entropy_bar, INFO_ENTROPY)
scan_bar(arg, &obj->a, &obj->b);
+#ifdef NVIDIA
+ END OBJ(nvidia, 0)
+ if (!arg){
+ CRIT_ERR("nvidia needs one argument "
+ "[temp,threshold,gpufreq,memfreq,imagequality]");
+ } else {
+ if (strcmp(arg, "temp") == 0)
+ obj->data.nvidia.type = NV_TEMP;
+ else if (strcmp(arg, "threshold") == 0)
+ obj->data.nvidia.type = NV_TEMP_THRESHOLD;
+ else if (strcmp(arg, "gpufreq") == 0)
+ obj->data.nvidia.type = NV_GPU_FREQ;
+ else if (strcmp(arg, "memfreq") == 0)
+ obj->data.nvidia.type = NV_MEM_FREQ;
+ else if (strcmp(arg, "imagequality") == 0)
+ obj->data.nvidia.type = NV_IMAGE_QUALITY;
+ else
+ CRIT_ERR("you have to give one of these arguments "
+ "[temp,threshold,gpufreq,memfreq,imagequality");
+ strncpy((char*)&obj->data.nvidia.arg, arg, 20);
+ }
+#endif /* NVIDIA */
END {
char buf[256];
ERR("unknown variable %s", s);
obj->type = OBJ_text;
snprintf(buf, 256, "${%s}", s);
- obj->data.s = strdup(buf);
+ obj->data.s = strndup(buf, text_buffer_size);
}
#undef OBJ
obj = new_text_object_internal();
obj->type = OBJ_text;
- obj->data.s = strdup(s);
+ obj->data.s = strndup(s, text_buffer_size);
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 = strndup(const_p, max_user_text);
+ 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 = global_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
sizeof(struct text_object));
free(obj);
}
- *(char *) p = '$';
+ *p = '$';
p++;
s = p;
/* if variable wasn't found in environment, use some special */
if (!var) {
- char *p;
+ char *tmp_p;
char *arg = 0;
/* split arg */
}
/* 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
ERR("one or more $endif's are missing");
}
+ free(orig_p);
return retval;
}
static void extract_variable_text(const char *p)
{
- struct text_object_list *list;
-
- free_text_objects(text_object_count, text_objects);
+ free_text_objects(global_text_object_list);
+ free(global_text_object_list);
if (tmpstring1) {
free(tmpstring1);
tmpstring1 = 0;
free(text_buffer);
text_buffer = 0;
}
- text_object_count = 0;
- text_objects = NULL;
-
- list = extract_variable_text_internal(p);
- text_objects = list->text_objects;
- text_object_count = list->text_object_count;
- free(list);
+ global_text_object_list = extract_variable_text_internal(p);
}
-struct text_object_list *parse_conky_vars(char *text, char *p, struct information *cur)
+struct text_object_list *parse_conky_vars(char *txt, char *p, struct information *cur)
{
struct text_object_list *object_list =
- extract_variable_text_internal(text);
+ extract_variable_text_internal(txt);
- generate_text_internal(p, max_user_text, object_list->text_objects,
- object_list->text_object_count, cur);
+ generate_text_internal(p, max_user_text, object_list, cur);
return object_list;
}
snprintf(dst, dst_size, "%s", obj->data.tail.buffer);
}
-char *format_time(unsigned long time, const int width)
+static inline struct mail_s *ensure_mail_thread(struct text_object *obj,
+ void *thread(void *), const char *text)
+{
+ if (obj->global_mode && info.mail) {
+ // this means we use info
+ if (!info.mail->p_timed_thread) {
+ info.mail->p_timed_thread =
+ timed_thread_create(thread,
+ (void *) info.mail, info.mail->interval * 1000000);
+ if (!info.mail->p_timed_thread) {
+ ERR("Error creating %s timed thread", text);
+ }
+ timed_thread_register(info.mail->p_timed_thread,
+ &info.mail->p_timed_thread);
+ if (timed_thread_run(info.mail->p_timed_thread)) {
+ ERR("Error running %s timed thread", text);
+ }
+ }
+ return info.mail;
+ } else if (obj->data.mail) {
+ // this means we use obj
+ if (!obj->data.mail->p_timed_thread) {
+ obj->data.mail->p_timed_thread =
+ timed_thread_create(thread,
+ (void *) obj->data.mail,
+ obj->data.mail->interval * 1000000);
+ if (!obj->data.mail->p_timed_thread) {
+ ERR("Error creating %s timed thread", text);
+ }
+ timed_thread_register(obj->data.mail->p_timed_thread,
+ &obj->data.mail->p_timed_thread);
+ if (timed_thread_run(obj->data.mail->p_timed_thread)) {
+ ERR("Error running %s timed thread", text);
+ }
+ }
+ return obj->data.mail;
+ } else if (!obj->a) {
+ // something is wrong, warn once then stop
+ ERR("Theres a problem with your %s_unseen settings. "
+ "Check that the global %s settings are defined "
+ "properly (line %li).", global_text, global_text, obj->line);
+ obj->a++;
+ }
+ return NULL;
+}
+
+char *format_time(unsigned long timeval, const int width)
{
char buf[10];
unsigned long nt; // narrow time, for speed on 32-bit
unsigned cc; // centiseconds
unsigned nn; // multi-purpose whatever
- nt = time;
+ nt = timeval;
cc = nt % 100; // centiseconds past second
nt /= 100; // total seconds
nn = nt % 60; // seconds past the minute
nt /= 60; // total minutes
if (width >= snprintf(buf, sizeof buf, "%lu:%02u.%02u",
nt, nn, cc)) {
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
if (width >= snprintf(buf, sizeof buf, "%lu:%02u", nt, nn)) {
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
nn = nt % 60; // minutes past the hour
nt /= 60; // total hours
if (width >= snprintf(buf, sizeof buf, "%lu,%02u", nt, nn)) {
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
nn = nt; // now also hours
if (width >= snprintf(buf, sizeof buf, "%uh", nn)) {
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
nn /= 24; // now days
if (width >= snprintf(buf, sizeof buf, "%ud", nn)) {
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
nn /= 7; // now weeks
if (width >= snprintf(buf, sizeof buf, "%uw", nn)) {
- return strdup(buf);
+ return strndup(buf, text_buffer_size);
}
// well shoot, this outta' fit...
- return strdup("<inf>");
+ return strndup("<inf>", text_buffer_size);
+}
+
+//remove backspaced chars, example: "dog^H^H^Hcat" becomes "cat"
+//string has to end with \0 and it's length should fit in a int
+#define BACKSPACE 8
+void remove_deleted_chars(char *string){
+ int i = 0;
+ while(string[i] != 0){
+ if(string[i] == BACKSPACE){
+ if(i != 0){
+ strcpy( &(string[i-1]), &(string[i+1]) );
+ i--;
+ }else strcpy( &(string[i]), &(string[i+1]) ); //necessary for ^H's at the start of a string
+ }else i++;
+ }
+}
+
+static inline void format_media_player_time(char *buf, const int size,
+ int seconds)
+{
+ int days, hours, minutes;
+
+ days = seconds / (24 * 60 * 60);
+ seconds %= (24 * 60 * 60);
+ hours = seconds / (60 * 60);
+ seconds %= (60 * 60);
+ minutes = seconds / 60;
+ seconds %= 60;
+
+ if (days > 0) {
+ snprintf(buf, size, "%i days %i:%02i:%02i", days,
+ hours, minutes, seconds);
+ } else if (hours > 0) {
+ snprintf(buf, size, "%i:%02i:%02i", hours, minutes,
+ seconds);
+ } else {
+ snprintf(buf, size, "%i:%02i", minutes, seconds);
+ }
}
static void generate_text_internal(char *p, int p_max_size,
- struct text_object *objs, unsigned int object_count,
+ struct text_object_list *text_object_list,
struct information *cur)
{
unsigned int i;
iconv_converting = 0;
#endif
- for (i = 0; i < object_count; i++) {
- struct text_object *obj = &objs[i];
+ p[0] = 0;
+ for (i = 0; i < text_object_list->text_object_count; i++) {
+ struct text_object *obj = &(text_object_list->text_objects[i]);
if (p_max_size < 1) {
break;
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));
if (obj->data.cpu_index > info.cpu_count) {
printf("obj->data.cpu_index %i info.cpu_count %i",
obj->data.cpu_index, info.cpu_count);
- CRIT_ERR("attempting to use more CPUs then you have!");
+ CRIT_ERR("attempting to use more CPUs than you have!");
}
spaced_print(p, p_max_size, "%*d", 4, "cpu", pad_percents,
round_to_int(cur->cpu_usage[obj->data.cpu_index] * 100.0));
round_to_int(cur->cpu_usage[obj->data.cpu_index] * 100),
100, 1);
}
+ OBJ(loadgraph) {
+ new_graph(p, obj->a, obj->b, obj->c, obj->d, cur->loadavg[0],
+ obj->e, 1);
+ }
OBJ(color) {
new_fg(p, obj->data.l);
}
(obj->data.diskio->current / update_interval) * 1024LL,
p, p_max_size, "diskio");
} else {
- human_readable(diskio_value * 1024LL, p, p_max_size,
+ human_readable(info.diskio_value * 1024LL, p, p_max_size,
"diskio");
}
}
human_readable((obj->data.diskio->current_write / update_interval) * 1024LL, p, p_max_size,
"diskio_write");
} else {
- human_readable(diskio_write_value * 1024LL, p, p_max_size,
+ human_readable(info.diskio_write_value * 1024LL, p, p_max_size,
"diskio_write");
}
}
human_readable((obj->data.diskio->current_read / update_interval) * 1024LL, p, p_max_size,
"diskio_read");
} else {
- human_readable(diskio_read_value * 1024LL, p, p_max_size,
+ human_readable(info.diskio_read_value * 1024LL, p, p_max_size,
"diskio_read");
}
}
new_graph(p, obj->a, obj->b, obj->c, obj->d,
obj->data.diskio->current, obj->e, 1);
} else {
- new_graph(p, obj->a, obj->b, obj->c, obj->d, diskio_value,
+ new_graph(p, obj->a, obj->b, obj->c, obj->d, info.diskio_value,
obj->e, 1);
}
}
obj->data.diskio->current_read, obj->e, 1);
} else {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
- diskio_read_value, obj->e, 1);
+ info.diskio_read_value, obj->e, 1);
}
}
OBJ(diskiograph_write) {
obj->data.diskio->current_write, obj->e, 1);
} else {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
- diskio_write_value, obj->e, 1);
+ info.diskio_write_value, obj->e, 1);
}
}
OBJ(downspeed) {
}
#ifdef HAVE_POPEN
OBJ(addr) {
- snprintf(p, p_max_size, "%u.%u.%u.%u",
- obj->data.net->addr.sa_data[2] & 255,
- obj->data.net->addr.sa_data[3] & 255,
- obj->data.net->addr.sa_data[4] & 255,
- obj->data.net->addr.sa_data[5] & 255);
+ if ((obj->data.net->addr.sa_data[2] & 255) == 0
+ && (obj->data.net->addr.sa_data[3] & 255) == 0
+ && (obj->data.net->addr.sa_data[4] & 255) == 0
+ && (obj->data.net->addr.sa_data[5] & 255) == 0) {
+ snprintf(p, p_max_size, "No Address");
+ } else {
+ snprintf(p, p_max_size, "%u.%u.%u.%u",
+ obj->data.net->addr.sa_data[2] & 255,
+ obj->data.net->addr.sa_data[3] & 255,
+ obj->data.net->addr.sa_data[4] & 255,
+ obj->data.net->addr.sa_data[5] & 255);
+ }
}
-
#if defined(__linux__)
- OBJ(addrs) {
- if(NULL != obj->data.net->addrs && strlen(obj->data.net->addrs) > 2)
- {
- obj->data.net->addrs[strlen(obj->data.net->addrs) - 2] = 0; /* remove ", " from end of string */
- strcpy(p, obj->data.net->addrs);
- }
- else
+ OBJ(addrs) {
+ if(NULL != obj->data.net->addrs && strlen(obj->data.net->addrs) > 2)
+ {
+ obj->data.net->addrs[strlen(obj->data.net->addrs) - 2] = 0; /* remove ", " from end of string */
+ strcpy(p, obj->data.net->addrs);
+ }
+ else
strcpy(p, "0.0.0.0");
}
#endif /* __linux__ */
pclose(fp);
p[length] = '\0';
+ remove_deleted_chars(p);
if (length > 0 && p[length - 1] == '\n') {
p[length - 1] = '\0';
}
}
OBJ(execp) {
- FILE *fp = popen(obj->data.s, "r");
- fread(p, 1, p_max_size, fp);
+ FILE *fp;
+ struct information *tmp_info;
+ struct text_object_list *text_objects;
+ int length;
+ fp = popen(obj->data.s, "r");
+ fread(p, 1, p_max_size, fp);
pclose(fp);
- struct information *my_info =
- malloc(sizeof(struct information));
- memcpy(my_info, cur, sizeof(struct information));
- struct text_object_list *text_objects = parse_conky_vars(p, p, my_info);
+ tmp_info = malloc(sizeof(struct information));
+ memcpy(tmp_info, cur, sizeof(struct information));
+ text_objects = parse_conky_vars(p, p, tmp_info);
- int length = strlen(p);
+ 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(text_objects);
free(text_objects);
- free(my_info);
+ free(tmp_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';
}
p2++;
}
- double barnum;
if (sscanf(p, "%lf", &barnum) == 0) {
ERR("reading execbar value failed (perhaps it's not the "
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';
}
p2++;
}
- double barnum;
if (sscanf(p, "%lf", &barnum) == 0) {
ERR("reading execgraph value failed (perhaps it's not the "
ERR("your execgraph value is not between 0 and 100, "
"therefore it will be ignored");
} else {
- new_graph(p, 0, 25, obj->c, obj->d, (int) (barnum),
- obj->e, 1);
+ new_graph(p, 0, 25, obj->c, obj->d, (int) (barnum), 100, 1);
}
}
OBJ(execibar) {
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';
}
p2++;
}
- float barnum;
if (sscanf(p, "%f", &barnum) == 0) {
ERR("reading execibar value failed (perhaps it's not "
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';
}
p2++;
}
- float barnum;
if (sscanf(p, "%f", &barnum) == 0) {
ERR("reading execigraph value failed (perhaps it's not "
// parse_conky_vars(output, p, cur);
}
OBJ(execpi) {
- struct information *my_info =
- malloc(sizeof(struct information));
- memcpy(my_info, cur, sizeof(struct information));
struct text_object_list *text_objects = 0;
+ struct information *tmp_info =
+ malloc(sizeof(struct information));
+ memcpy(tmp_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);
+ text_objects = parse_conky_vars(obj->data.execi.buffer, p, tmp_info);
} else {
char *output = obj->data.execi.buffer;
FILE *fp = popen(obj->data.execi.cmd, "r");
if (length > 0 && output[length - 1] == '\n') {
output[length - 1] = '\0';
}
-
- text_objects = parse_conky_vars(obj->data.execi.buffer, p, my_info);
+
+ text_objects = parse_conky_vars(obj->data.execi.buffer, p, tmp_info);
obj->data.execi.last_update = current_update_time;
}
- free_text_objects(text_objects->text_object_count, text_objects->text_objects);
+ free_text_objects(text_objects);
free(text_objects);
- free(my_info);
+ free(tmp_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");
}
#endif /* HAVE_POPEN */
OBJ(imap_unseen) {
- if (obj->global_mode && info.mail) {
- // this means we use info
- if (!info.mail->p_timed_thread) {
- info.mail->p_timed_thread =
- timed_thread_create((void *) imap_thread,
- (void *) info.mail, info.mail->interval * 1000000);
- if (!info.mail->p_timed_thread) {
- ERR("Error creating imap timed thread");
- }
- timed_thread_register(info.mail->p_timed_thread,
- &info.mail->p_timed_thread);
- if (timed_thread_run(info.mail->p_timed_thread)) {
- ERR("Error running imap timed thread");
- }
- }
- timed_thread_lock(info.mail->p_timed_thread);
- snprintf(p, p_max_size, "%lu", info.mail->unseen);
- timed_thread_unlock(info.mail->p_timed_thread);
- } else if (obj->data.mail) {
- // this means we use obj
- if (!obj->data.mail->p_timed_thread) {
- obj->data.mail->p_timed_thread =
- timed_thread_create((void *) imap_thread,
- (void *) obj->data.mail,
- obj->data.mail->interval * 1000000);
- if (!obj->data.mail->p_timed_thread) {
- ERR("Error creating imap timed thread");
- }
- timed_thread_register(obj->data.mail->p_timed_thread,
- &obj->data.mail->p_timed_thread);
- if (timed_thread_run(obj->data.mail->p_timed_thread)) {
- ERR("Error running imap timed thread");
- }
- }
- timed_thread_lock(obj->data.mail->p_timed_thread);
- snprintf(p, p_max_size, "%lu", obj->data.mail->unseen);
- timed_thread_unlock(obj->data.mail->p_timed_thread);
- } else if (!obj->a) {
- // something is wrong, warn once then stop
- ERR("Theres a problem with your imap_unseen settings. "
- "Check that the global IMAP settings are defined "
- "properly (line %li).", obj->line);
- obj->a++;
+ struct mail_s *mail = ensure_mail_thread(obj, imap_thread, "imap");
+
+ if (mail && mail->p_timed_thread) {
+ timed_thread_lock(mail->p_timed_thread);
+ snprintf(p, p_max_size, "%lu", mail->unseen);
+ timed_thread_unlock(mail->p_timed_thread);
}
}
OBJ(imap_messages) {
- if (obj->global_mode && info.mail) {
- // this means we use info
- if (!info.mail->p_timed_thread) {
- info.mail->p_timed_thread =
- timed_thread_create((void *) imap_thread,
- (void *) info.mail, info.mail->interval * 1000000);
- if (!info.mail->p_timed_thread) {
- ERR("Error creating imap timed thread");
- }
- timed_thread_register(info.mail->p_timed_thread,
- &info.mail->p_timed_thread);
- if (timed_thread_run(info.mail->p_timed_thread)) {
- ERR("Error running imap timed thread");
- }
- }
- timed_thread_lock(info.mail->p_timed_thread);
- snprintf(p, p_max_size, "%lu", info.mail->messages);
- timed_thread_unlock(info.mail->p_timed_thread);
- } else if (obj->data.mail) {
- // this means we use obj
- if (!obj->data.mail->p_timed_thread) {
- obj->data.mail->p_timed_thread =
- timed_thread_create((void *) imap_thread,
- (void *) obj->data.mail,
- obj->data.mail->interval * 1000000);
- if (!obj->data.mail->p_timed_thread) {
- ERR("Error creating imap timed thread");
- }
- timed_thread_register(obj->data.mail->p_timed_thread,
- &obj->data.mail->p_timed_thread);
- if (timed_thread_run(obj->data.mail->p_timed_thread)) {
- ERR("Error runninging imap timed thread");
- }
- }
- timed_thread_lock(obj->data.mail->p_timed_thread);
- snprintf(p, p_max_size, "%lu", obj->data.mail->messages);
- timed_thread_lock(obj->data.mail->p_timed_thread);
- } else if (!obj->a) {
- // something is wrong, warn once then stop
- ERR("Theres a problem with your imap_messages settings. "
- "Check that the global IMAP settings are defined "
- "properly (line %li).", obj->line);
- obj->a++;
+ struct mail_s *mail = ensure_mail_thread(obj, imap_thread, "imap");
+
+ if (mail && mail->p_timed_thread) {
+ timed_thread_lock(mail->p_timed_thread);
+ snprintf(p, p_max_size, "%lu", mail->messages);
+ timed_thread_unlock(mail->p_timed_thread);
}
}
OBJ(pop3_unseen) {
- if (obj->global_mode && info.mail) {
- // this means we use info
- if (!info.mail->p_timed_thread) {
- info.mail->p_timed_thread =
- timed_thread_create((void *) pop3_thread,
- (void *) info.mail, info.mail->interval * 1000000);
- if (!info.mail->p_timed_thread) {
- ERR("Error creating pop3 timed thread");
- }
- timed_thread_register(info.mail->p_timed_thread,
- &info.mail->p_timed_thread);
- if (timed_thread_run(info.mail->p_timed_thread)) {
- ERR("Error running pop3 timed thread");
- }
- }
- timed_thread_lock(info.mail->p_timed_thread);
- snprintf(p, p_max_size, "%lu", info.mail->unseen);
- timed_thread_unlock(info.mail->p_timed_thread);
- } else if (obj->data.mail) {
- // this means we use obj
- if (!obj->data.mail->p_timed_thread) {
- obj->data.mail->p_timed_thread =
- timed_thread_create((void *) pop3_thread,
- (void *) obj->data.mail,
- obj->data.mail->interval * 1000000);
- if (!obj->data.mail->p_timed_thread) {
- ERR("Error creating pop3 timed thread");
- }
- timed_thread_register(obj->data.mail->p_timed_thread,
- &obj->data.mail->p_timed_thread);
- if (timed_thread_run(obj->data.mail->p_timed_thread)) {
- ERR("Error running pop3 timed thread");
- }
- }
- timed_thread_lock(obj->data.mail->p_timed_thread);
- snprintf(p, p_max_size, "%lu", obj->data.mail->unseen);
- timed_thread_unlock(obj->data.mail->p_timed_thread);
- } else if (!obj->a) {
- // something is wrong, warn once then stop
- ERR("Theres a problem with your pop3_unseen settings. "
- "Check that the global POP3 settings are defined "
- "properly (line %li).", obj->line);
- obj->a++;
+ struct mail_s *mail = ensure_mail_thread(obj, pop3_thread, "pop3");
+
+ if (mail && mail->p_timed_thread) {
+ timed_thread_lock(mail->p_timed_thread);
+ snprintf(p, p_max_size, "%lu", mail->unseen);
+ timed_thread_unlock(mail->p_timed_thread);
}
}
OBJ(pop3_used) {
- if (obj->global_mode && info.mail) {
- // this means we use info
- if (!info.mail->p_timed_thread) {
- info.mail->p_timed_thread =
- timed_thread_create((void *) pop3_thread,
- (void *) info.mail, info.mail->interval * 1000000);
- if (!info.mail->p_timed_thread) {
- ERR("Error creating pop3 timed thread");
- }
- timed_thread_register(info.mail->p_timed_thread,
- &info.mail->p_timed_thread);
- if (timed_thread_run(info.mail->p_timed_thread)) {
- ERR("Error running pop3 timed thread");
- }
- }
- timed_thread_lock(info.mail->p_timed_thread);
- snprintf(p, p_max_size, "%.1f",
- info.mail->used / 1024.0 / 1024.0);
- timed_thread_unlock(info.mail->p_timed_thread);
- } else if (obj->data.mail) {
- // this means we use obj
- if (!obj->data.mail->p_timed_thread) {
- obj->data.mail->p_timed_thread =
- timed_thread_create((void *) pop3_thread,
- (void *) obj->data.mail,
- obj->data.mail->interval * 1000000);
- if (!obj->data.mail->p_timed_thread) {
- ERR("Error creating pop3 timed thread");
- }
- timed_thread_register(obj->data.mail->p_timed_thread,
- &obj->data.mail->p_timed_thread);
- if (timed_thread_run(obj->data.mail->p_timed_thread)) {
- ERR("Error running pop3 timed thread");
- }
- }
- timed_thread_lock(obj->data.mail->p_timed_thread);
+ struct mail_s *mail = ensure_mail_thread(obj, pop3_thread, "pop3");
+
+ if (mail && mail->p_timed_thread) {
+ timed_thread_lock(mail->p_timed_thread);
snprintf(p, p_max_size, "%.1f",
- obj->data.mail->used / 1024.0 / 1024.0);
- timed_thread_unlock(obj->data.mail->p_timed_thread);
- } else if (!obj->a) {
- // something is wrong, warn once then stop
- ERR("Theres a problem with your pop3_used settings. "
- "Check that the global POP3 settings are defined "
- "properly (line %li).", obj->line);
- obj->a++;
+ mail->used / 1024.0 / 1024.0);
+ timed_thread_unlock(mail->p_timed_thread);
}
}
OBJ(fs_bar) {
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");
}
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");
}
} 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;
#endif
#ifdef HDDTEMP
OBJ(hddtemp) {
- char *temp;
- char unit;
-
- temp = get_hddtemp_info(obj->data.hddtemp.dev,
- obj->data.hddtemp.addr, obj->data.hddtemp.port, &unit);
- if (!temp) {
+ if (obj->data.hddtemp.update_time < current_update_time - 30) {
+ char *str = get_hddtemp_info(obj->data.hddtemp.dev,
+ obj->data.hddtemp.addr, obj->data.hddtemp.port, &obj->data.hddtemp.unit);
+ if (str) {
+ strncpy(obj->data.hddtemp.temp, str, text_buffer_size);
+ } else {
+ obj->data.hddtemp.temp[0] = 0;
+ }
+ obj->data.hddtemp.update_time = current_update_time;
+ }
+ if (!obj->data.hddtemp.temp) {
snprintf(p, p_max_size, "N/A");
- } else if (unit == '*') {
- snprintf(p, p_max_size, "%s", temp);
+ } else if (obj->data.hddtemp.unit == '*') {
+ snprintf(p, p_max_size, "%s", obj->data.hddtemp.temp);
} else {
- snprintf(p, p_max_size, "%s°%c", temp, unit);
+ snprintf(p, p_max_size, "%s%c", obj->data.hddtemp.temp, obj->data.hddtemp.unit);
}
}
#endif
new_alignc(p, obj->data.i);
}
OBJ(if_empty) {
- struct information *my_info =
+ struct text_object_list *text_objects;
+ struct information *tmp_info =
malloc(sizeof(struct information));
+ memcpy(tmp_info, cur, sizeof(struct information));
+ text_objects = parse_conky_vars(obj->data.ifblock.s, p, tmp_info);
- memcpy(my_info, cur, sizeof(struct information));
- struct text_object_list *text_objects = parse_conky_vars(obj->data.ifblock.s, p, my_info);
if (strlen(p) != 0) {
i = obj->data.ifblock.pos;
if_jumped = 1;
if_jumped = 0;
}
p[0] = '\0';
- free_text_objects(text_objects->text_object_count, text_objects->text_objects);
+ free_text_objects(text_objects);
free(text_objects);
- free(my_info);
+ free(tmp_info);
}
OBJ(if_existing) {
struct stat tmp;
if_jumped = 0;
}
}
+#if defined(__linux__)
OBJ(ioscheduler) {
snprintf(p, p_max_size, "%s", get_ioscheduler(obj->data.s));
}
+#endif
OBJ(kernel) {
snprintf(p, p_max_size, "%s", cur->uname_s.release);
}
}
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);
}
}
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);
}
}
}
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);
snprintf(p, p_max_size, "%s", cur->mpd.status);
}
OBJ(mpd_elapsed) {
- int days = 0, hours = 0, minutes = 0, seconds = 0;
- int tmp = cur->mpd.elapsed;
-
- while (tmp >= 86400) {
- tmp -= 86400;
- days++;
- }
- while (tmp >= 3600) {
- tmp -= 3600;
- hours++;
- }
- while (tmp >= 60) {
- tmp -= 60;
- minutes++;
- }
- seconds = tmp;
- if (days > 0) {
- snprintf(p, p_max_size, "%i days %i:%02i:%02i", days,
- hours, minutes, seconds);
- } else if (hours > 0) {
- snprintf(p, p_max_size, "%i:%02i:%02i", hours, minutes,
- seconds);
- } else {
- snprintf(p, p_max_size, "%i:%02i", minutes, seconds);
- }
+ format_media_player_time(p, p_max_size, cur->mpd.elapsed);
}
OBJ(mpd_length) {
- int days = 0, hours = 0, minutes = 0, seconds = 0;
- int tmp = cur->mpd.length;
-
- while (tmp >= 86400) {
- tmp -= 86400;
- days++;
- }
- while (tmp >= 3600) {
- tmp -= 3600;
- hours++;
- }
- while (tmp >= 60) {
- tmp -= 60;
- minutes++;
- }
- seconds = tmp;
- if (days > 0) {
- snprintf(p, p_max_size, "%i days %i:%02i:%02i", days,
- hours, minutes, seconds);
- } else if (hours > 0) {
- snprintf(p, p_max_size, "%i:%02i:%02i", hours, minutes,
- seconds);
- } else {
- snprintf(p, p_max_size, "%i:%02i", minutes, seconds);
- }
+ format_media_player_time(p, p_max_size, cur->mpd.length);
}
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,
#endif
OBJ(top) {
if (obj->data.top.num >= 0 && obj->data.top.num < 10) {
- char *time;
+ char *timeval;
switch (obj->data.top.type) {
case TOP_NAME:
cur->cpu[obj->data.top.num]->totalmem);
break;
case TOP_TIME:
- time = format_time(
+ timeval = format_time(
cur->cpu[obj->data.top.num]->total_cpu_time, 9);
- snprintf(p, 10, "%9s", time);
- free(time);
+ snprintf(p, 10, "%9s", timeval);
+ free(timeval);
+ break;
+ case TOP_MEM_RES:
+ human_readable(cur->cpu[obj->data.top.num]->rss,
+ p, 255, "top_rss");
+ break;
+ case TOP_MEM_VSIZE:
+ human_readable(cur->cpu[obj->data.top.num]->vsize,
+ p, 255, "top_rss");
break;
default:
ERR("Unhandled top data type: %d\n",
}
OBJ(top_mem) {
if (obj->data.top.num >= 0 && obj->data.top.num < 10) {
- char *time;
+ char *timeval;
switch (obj->data.top.type) {
case TOP_NAME:
cur->memu[obj->data.top.num]->totalmem);
break;
case TOP_TIME:
- time = format_time(
+ timeval = format_time(
cur->memu[obj->data.top.num]->total_cpu_time,
9);
- snprintf(p, 10, "%9s", time);
- free(time);
+ snprintf(p, 10, "%9s", timeval);
+ free(timeval);
+ break;
+ case TOP_MEM_RES:
+ human_readable(cur->cpu[obj->data.top.num]->rss,
+ p, 255, "top_rss");
+ break;
+ case TOP_MEM_VSIZE:
+ human_readable(cur->cpu[obj->data.top.num]->vsize,
+ p, 255, "top_rss");
break;
default:
ERR("Unhandled top data type: %d\n",
< 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;
} /* if cur_upd_time >= */
// parse_conky_vars(obj->data.tail.buffer, p, cur);
}
-
head:
OBJ(head) {
if (current_update_time - obj->data.tail.last_update
< obj->data.tail.interval) {
snprintf(p, p_max_size, "%s", obj->data.tail.buffer);
} 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
new_bar(p, obj->a, obj->b, 0);
}
#endif /* SMAPI */
+#ifdef NVIDIA
+ OBJ(nvidia) {
+ int hol = (strcmp((char*)&obj->data.nvidia.arg, "gpufreq")) ? 1 : 0;
+ if(!(obj->data.nvidia.value = get_nvidia_value(obj->data.nvidia.type, display, hol)))
+ snprintf(p, p_max_size, "value unavailible");
+ else
+ spaced_print(p, p_max_size, "%*d", 4, "nvidia",
+ 4, obj->data.nvidia.value);
+
+ }
+#endif /* NVIDIA */
break;
}
double current_update_time, last_update_time;
-static void generate_text()
+static void generate_text(void)
{
struct information *cur = &info;
char *p;
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;
- diskio_value = diskio_value / update_interval;
+ info.diskio_read_value /= update_interval;
+ info.diskio_write_value /= update_interval;
+ info.diskio_value /= update_interval;
/* add things to the buffer */
p = text_buffer;
- generate_text_internal(p, max_user_text, text_objects, text_object_count, cur);
+ generate_text_internal(p, max_user_text, global_text_object_list, cur);
if (stuff_in_upper_case) {
- char *p;
+ char *tmp_p;
- p = text_buffer;
- while (*p) {
- *p = toupper(*p);
- p++;
+ tmp_p = text_buffer;
+ while (*tmp_p) {
+ *tmp_p = toupper(*tmp_p);
+ tmp_p++;
}
}
}
#ifdef X11
-static void set_font()
+static void set_font(void)
{
#ifdef XFT
if (use_xft) {
static inline int get_string_width_special(char *s)
{
+#ifdef X11
+ char *p, *final;
+ int idx = 1;
+ int width = 0;
+ unsigned int i;
+
if (!s) {
return 0;
}
-#ifdef X11
- char *p, *final;
- p = strdup(s);
+ p = strndup(s, text_buffer_size);
final = p;
- int index = 1;
- int width = 0;
- unsigned int i;
while (*p) {
if (*p == SPECIAL_CHAR) {
for (i = 0; i < strlen(p); i++) {
*(p + i) = *(p + i + 1);
}
- if (specials[special_index + index].type == GRAPH
- || specials[special_index + index].type == BAR) {
- width += specials[special_index + index].width;
+ if (specials[special_index + idx].type == GRAPH
+ || specials[special_index + idx].type == BAR) {
+ width += specials[special_index + idx].width;
}
- index++;
+ idx++;
} else {
p++;
}
free(final);
return width;
#else
- return strlen(s);
+ return (s) ? strlen(s) : 0;
#endif /* X11 */
}
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;
/* drawing stuff */
static int cur_x, cur_y; /* current x and y for drawing */
+#endif
+//draw_mode also without X11 because we only need to print to stdout with FG
static int draw_mode; /* FG, BG or OUTLINE */
+#ifdef X11
static long current_color;
#ifdef X11
static void draw_string(const char *s)
{
- if (s[0] == '\0') {
- return;
- }
int i, i2, pos, width_of_s;
int max = 0;
int added;
+ if (s[0] == '\0') {
+ return;
+ }
+
width_of_s = get_string_width(s);
- if (out_to_console) {
+ if (out_to_console && draw_mode == FG) {
printf("%s\n", s);
fflush(stdout); /* output immediately, don't buffer */
}
strncpy(tmpstring1, s, text_buffer_size - 1);
pos = 0;
added = 0;
- char space[2];
- snprintf(space, 2, " ");
#ifdef X11
- max = ((text_width - width_of_s) / get_string_width(space));
+ max = ((text_width - width_of_s) / get_string_width(" "));
#endif /* X11 */
/* 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)text_buffer_size; i++) {
- if (tmpstring1[i] == '\t') { // 9 is ascii tab
+ for (i = 0; i < (int) text_buffer_size; i++) {
+ if (tmpstring1[i] == '\t') {
i2 = 0;
for (i2 = 0; i2 < (8 - (1 + pos) % 8) && added <= max; i2++) {
/* guard against overrun */
}
pos += i2;
} else {
- if (tmpstring1[i] != 9) {
- /* guard against overrun */
- tmpstring2[MIN(pos, (int)text_buffer_size - 1)] = tmpstring1[i];
- pos++;
- }
+ /* guard against overrun */
+ tmpstring2[MIN(pos, (int) text_buffer_size - 1)] = tmpstring1[i];
+ pos++;
}
}
#ifdef X11
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
long redmask, greenmask, bluemask;
-void set_up_gradient()
+void set_up_gradient(void)
{
+ int i;
#ifdef X11
colour_depth = DisplayPlanes(display, screen);
#else
ERR("using non-standard colour depth, gradients may look like a "
"lolly-pop");
}
- int i;
redmask = 0;
greenmask = 0;
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;
red3 = abs(red1 - red2);
green3 = abs(green1 - green2);
blue3 = abs(blue1 - blue2);
- int max = red3;
+ max = red3;
if (green3 > max) {
max = green3;
{
#ifdef X11
char *p;
+ int cur_y_add = 0;
+ short font_h;
+ char *tmp_str;
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;
case STIPPLED_HR:
{
int h = specials[special_index].height;
- int s = specials[special_index].arg;
+ int tmp_s = specials[special_index].arg;
int mid = font_ascent() / 2;
- char ss[2] = { s, s };
+ char ss[2] = { tmp_s, tmp_s };
w = text_start_x + text_width - cur_x - 1;
XSetLineAttributes(display, window.gc, h, LineOnOffDash,
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;
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;
+ int show_scale_x = cur_x + font_ascent() / 2;
+ int show_scale_y = cur_y + font_height() / 2;
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;
}
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) {
} else {
set_foreground_color(default_fg_color);
} */
+ if (show_graph_scale && (specials[special_index].show_scale == 1)) {
+ int tmp_x = cur_x;
+ int tmp_y = cur_y;
+ cur_x = show_scale_x;
+ cur_y = show_scale_y;
+ tmp_str = (char *)
+ calloc(log10(floor(specials[special_index].graph_scale)) + 4,
+ sizeof(char));
+ sprintf(tmp_str, "%.1f", specials[special_index].graph_scale);
+ draw_string(tmp_str);
+ free(tmp_str);
+ cur_x = tmp_x;
+ cur_y = tmp_y;
+ }
set_foreground_color(last_colour);
break;
}
#endif /* X11 */
}
-static void draw_text()
+static void draw_text(void)
{
#ifdef X11
cur_y = text_start_y;
for_each_line(text_buffer, draw_line);
}
-static void draw_stuff()
+static void draw_stuff(void)
{
#ifdef X11
selected_font = 0;
}
if (draw_outline) {
- selected_font = 0;
int i, j;
+ selected_font = 0;
for (i = -1; i < 2; i++) {
for (j = -1; j < 2; j++) {
}
set_foreground_color(default_fg_color);
- draw_mode = FG;
#endif /* X11 */
+ draw_mode = FG;
draw_text();
#ifdef X11
#ifdef HAVE_XDBE
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
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++;
#ifdef X11
free_fonts();
- load_fonts();
- set_font();
#endif /* X11 */
#ifdef TCP_PORT_MONITOR
}
#ifdef X11
+ load_fonts();
+ set_font();
// clear the window first
XClearWindow(display, RootWindow(display, screen));
#ifdef TCP_PORT_MONITOR
info.p_tcp_port_monitor_collection = NULL;
#endif
- extract_variable_text(text);
- free(text);
- text = NULL;
+ extract_variable_text(global_text);
+ free(global_text);
+ global_text = NULL;
if (tmpstring1) {
free(tmpstring1);
}
free_fonts();
#endif /* X11 */
- free_text_objects(text_object_count, text_objects);
+ free_text_objects(global_text_object_list);
+ free(global_text_object_list);
+ global_text_object_list = NULL;
if (tmpstring1) {
free(tmpstring1);
tmpstring1 = 0;
free(text_buffer);
text_buffer = 0;
}
- text_object_count = 0;
- text_objects = NULL;
- if (text) {
- free(text);
- text = 0;
+ if (global_text) {
+ free(global_text);
+ global_text = 0;
}
free(current_config);
static int string_to_bool(const char *s)
{
if (!s) {
+ // Assumes an option without a true/false means true
return 1;
} else if (strcasecmp(s, "yes") == 0) {
return 1;
out_to_console = 1;
#endif
#ifdef X11
+ show_graph_scale = 0;
default_fg_color = WhitePixel(display, screen);
default_bg_color = BlackPixel(display, screen);
default_out_color = BlackPixel(display, screen);
variable_substitute(MAIL_FILE, buf, 256);
if (buf[0] != '\0') {
- current_mail_spool = strdup(buf);
+ current_mail_spool = strndup(buf, text_buffer_size);
}
}
}
#endif /* X11 */
#ifdef X11
+ CONF("show_graph_scale") {
+ show_graph_scale = string_to_bool(value);
+ }
CONF("border_margin") {
if (value) {
border_margin = strtol(value, 0, 0);
#endif /* X11 */
CONF("mail_spool") {
if (value) {
- char buf[256];
+ char buffer[256];
- variable_substitute(value, buf, 256);
+ variable_substitute(value, buffer, 256);
- if (buf[0] != '\0') {
+ if (buffer[0] != '\0') {
if (current_mail_spool) {
free(current_mail_spool);
}
- current_mail_spool = strdup(buf);
+ current_mail_spool = strndup(buffer, text_buffer_size);
}
} else {
CONF_ERR;
window.type = TYPE_NORMAL;
} else if (strncmp(value, "desktop", 7) == 0) {
window.type = TYPE_DESKTOP;
+ } else if (strncmp(value, "dock", 7) == 0) {
+ window.type = TYPE_DOCK;
} else if (strncmp(value, "override", 8) == 0) {
window.type = TYPE_OVERRIDE;
} else {
}
}
CONF("text") {
- if (text) {
- free(text);
- text = 0;
+ if (global_text) {
+ free(global_text);
+ global_text = 0;
}
- text = (char *) malloc(1);
- text[0] = '\0';
+ global_text = (char *) malloc(1);
+ global_text[0] = '\0';
while (!feof(fp)) {
- unsigned int l = strlen(text);
+ unsigned int l = strlen(global_text);
if (fgets(buf, 256, fp) == NULL) {
break;
}
- text = (char *) realloc(text, l + strlen(buf) + 1);
- strcat(text, buf);
+ global_text = (char *) realloc(global_text, l + strlen(buf) + 1);
+ strcat(global_text, buf);
- if (strlen(text) > max_user_text) {
+ if (strlen(global_text) > max_user_text) {
break;
}
}
fclose(fp);
- text_lines = line + 1;
+ if (strlen(global_text) < 1) {
+ CRIT_ERR("no text supplied in configuration; exiting");
+ }
+ global_text_lines = line + 1;
return;
}
#ifdef TCP_PORT_MONITOR
* as per config */
}
#endif
+ CONF("if_up_strictness") {
+ if (!value) {
+ ERR("incorrect if_up_strictness value, defaulting to 'up'");
+ ifup_strictness = IFUP_UP;
+ } else if (!strcmp(value, "up")) {
+ ifup_strictness = IFUP_UP;
+ } else if (!strcmp(value, "link")) {
+ ifup_strictness = IFUP_LINK;
+ } else if (!strcmp(value, "address")) {
+ ifup_strictness = IFUP_ADDR;
+ } else {
+ ERR("incorrect if_up_strictness value, defaulting to 'up'");
+ ifup_strictness = IFUP_UP;
+ }
+ }
else {
ERR("%s: %d: no such configuration: '%s'", f, line, name);
}
// default to update_interval
info.music_player_interval = update_interval;
}
+ if (!global_text) { // didn't supply any text
+ CRIT_ERR("missing text block in configuration; exiting");
+ }
+}
+
+static void print_help(const char *prog_name) {
+ printf("Usage: %s [OPTION]...\n"
+ "Conky is a system monitor that renders text on desktop or to own transparent\n"
+ "window. Command line options will override configurations defined in config\n"
+ "file.\n"
+ " -v, --version version\n"
+ " -q, --quiet quiet mode\n"
+ " -c, --config=FILE config file to load\n"
+ " -d, --daemonize daemonize, fork to background\n"
+ " -h, --help help\n"
+#ifdef X11
+ " -a, --alignment=ALIGNMENT text alignment on screen, {top,bottom,middle}_{left,right,middle}\n"
+ " -f, --font=FONT font to use\n"
+#ifdef OWN_WINDOW
+ " -o, --own-window create own window to draw\n"
+#endif
+#ifdef HAVE_XDBE
+ " -b, --double-buffer double buffer (prevents flickering)\n"
+#endif
+ " -w, --window-id=WIN_ID window id to draw\n"
+ " -x X x position\n"
+ " -y Y y position\n"
+#endif /* X11 */
+ " -t, --text=TEXT text to render, remember single quotes, like -t '$uptime'\n"
+ " -u, --interval=SECS update interval\n"
+ " -i COUNT number of times to update Conky (and quit)\n",
+ prog_name
+ );
}
/* : means that character before that takes an argument */
-static const char *getopt_string = "vVdt:u:i:hc:"
+static const char *getopt_string = "vVqdt:u:i:hc:"
#ifdef X11
"x:y:w:a:f:"
#ifdef OWN_WINDOW
int main(int argc, char **argv)
{
+#ifdef X11
+ char *s, *temp;
+ unsigned int x;
+#endif
struct sigaction act, oact;
g_signal_pending = 0;
/* 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));
if (current_config) {
free(current_config);
}
- current_config = strdup(optarg);
+ current_config = strndup(optarg, max_user_text);
+ break;
+ case 'q':
+ freopen("/dev/null", "w", stderr);
break;
-
case 'h':
- printf("Usage: %s [OPTION]...\n"
- "Conky is a system monitor that renders text on desktop or to own transparent\n"
- "window. Command line options will override configurations defined in config\n"
- "file.\n"
- " -V, --version version\n"
- " -c, --config=FILE config file to load\n"
- " -d, --daemonize daemonize, fork to background\n"
- " -h, --help help\n"
-#ifdef X11
- " -a, --alignment=ALIGNMENT text alignment on screen, {top,bottom}_{left,right}\n"
- " -f, --font=FONT font to use\n"
-#ifdef OWN_WINDOW
- " -o, --own-window create own window to draw\n"
-#endif
-#ifdef HAVE_XDBE
- " -b, --double-buffer double buffer (prevents flickering)\n"
-#endif
- " -w, --window-id=WIN_ID window id to draw\n"
- " -x X x position\n"
- " -y Y y position\n"
-#endif /* X11 */
- " -t, --text=TEXT text to render, remember single quotes, like -t '$uptime'\n"
- " -u, --interval=SECS update interval\n"
- " -i NUM number of times to update Conky\n",
- argv[0]
- );
+ print_help(argv[0]);
return 0;
#ifdef X11
case 'w':
/* Try to use personal config file first */
variable_substitute(CONFIG_FILE, buf, sizeof(buf));
if (buf[0] && (fp = fopen(buf, "r"))) {
- current_config = strdup(buf);
+ current_config = strndup(buf, max_user_text);
fclose(fp);
}
/* Try to use system config file if personal config not readable */
if (!current_config && (fp = fopen(SYSTEM_CONFIG_FILE, "r"))) {
- current_config = strdup(SYSTEM_CONFIG_FILE);
+ current_config = strndup(SYSTEM_CONFIG_FILE, max_user_text);
fclose(fp);
}
variable_substitute(MAIL_FILE, buf, 256);
if (buf[0] != '\0') {
- current_mail_spool = strdup(buf);
+ current_mail_spool = strndup(buf, text_buffer_size);
}
}
#endif
#endif
#endif /* X11 */
case 't':
- if (text) {
- free(text);
- text = 0;
+ if (global_text) {
+ free(global_text);
+ global_text = 0;
}
- text = strdup(optarg);
- convert_escapes(text);
+ global_text = strndup(optarg, max_user_text);
+ convert_escapes(global_text);
break;
case 'u':
#endif /* X11 */
/* generate text and get initial size */
- extract_variable_text(text);
- if (text) {
- free(text);
- text = 0;
+ extract_variable_text(global_text);
+ if (global_text) {
+ free(global_text);
+ global_text = 0;
}
- text = NULL;
+ global_text = NULL;
/* fork */
if (fork_to_background) {
int pid = fork();