* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
- * $Id$ */
+ */
+#include "config.h"
+#include "text_object.h"
#include "conky.h"
-#include <stdio.h>
-#include <stdlib.h>
+#include "common.h"
#include <stdarg.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <locale.h>
#include <signal.h>
-#include <unistd.h>
#include <errno.h>
-#include <termios.h>
-#include <string.h>
#include <limits.h>
#if HAVE_DIRENT_H
#include <dirent.h>
#endif
#include <sys/time.h>
#ifdef X11
+#include "x11.h"
#include <X11/Xutil.h>
#ifdef HAVE_XDAMAGE
#include <X11/extensions/Xdamage.h>
#include <fcntl.h>
#include <getopt.h>
+/* local headers */
+#include "build.h"
+#include "diskio.h"
+#include "fs.h"
+#include "logging.h"
+#include "mixer.h"
+#include "mail.h"
+#include "mboxscan.h"
+#include "temphelper.h"
+#include "top.h"
+
+/* check for OS and include appropriate headers */
+#if defined(__linux__)
+#include "linux.h"
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#include "freebsd.h"
+#elif defined(__OpenBSD__)
+#include "openbsd.h"
+#endif
+
+/* FIXME: apm_getinfo is unused here. maybe it's meant for common.c */
+#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
+ || defined(__OpenBSD__)) && (defined(i386) || defined(__i386__))
+int apm_getinfo(int fd, apm_info_t aip);
+char *get_apm_adapter(void);
+char *get_apm_battery_life(void);
+char *get_apm_battery_time(void);
+#endif
+
#ifdef HAVE_ICONV
#include <iconv.h>
#endif
-#include "build.h"
+#ifdef CONFIG_OUTPUT
+#include "defconfig.h"
+#ifdef HAVE_FOPENCOOKIE
+#include "conf_cookie.h"
+#endif
+#endif
#ifndef S_ISSOCK
#define S_ISSOCK(x) ((x & S_IFMT) == S_IFSOCK)
#endif
-#define CONFIG_FILE "$HOME/.conkyrc"
#define MAIL_FILE "$MAIL"
#define MAX_IF_BLOCK_DEPTH 5
#define MAX_TAIL_LINES 100
-/* #define SIGNAL_BLOCKING */
+//#define SIGNAL_BLOCKING
#undef SIGNAL_BLOCKING
+/* debugging level, used by logging.h */
+int global_debug_level = 0;
+
+/* two strings for internal use */
+static char *tmpstring1, *tmpstring2;
+
+/* variables holding various config settings */
+int short_units;
+int cpu_separate;
+static int use_spacer;
+int top_cpu, top_mem;
+#define TO_X 1
+#define TO_STDOUT 2
+static int output_methods;
+static volatile int g_signal_pending;
+/* Update interval */
+static double update_interval;
+
+
+/* prototypes for internally used functions */
+static void signal_handler(int);
static void print_version(void) __attribute__((noreturn));
+static void reload_config(void);
+static void clean_up(void);
static void print_version(void)
{
- printf("Conky %s compiled %s for %s\n", VERSION, BUILD_DATE, BUILD_ARCH);
+ printf(PACKAGE_NAME" "VERSION" compiled "BUILD_DATE" for "BUILD_ARCH"\n");
printf("\nCompiled in features:\n\n"
- "System config file: %s\n\n"
+ "System config file: "SYSTEM_CONFIG_FILE"\n\n"
#ifdef X11
" X11:\n"
# ifdef HAVE_XDAMAGE
#ifdef MPD
" * mpd\n"
#endif /* MPD */
+#ifdef MOC
+ " * moc\n"
+#endif /* MOC */
#ifdef XMMS2
" * xmms2\n"
#endif /* XMMS2 */
"\n General features:\n"
+#ifdef MATH
+ " * math\n"
+#endif /* Math */
#ifdef HDDTEMP
" * hddtemp\n"
#endif /* HDDTEMP */
#ifdef RSS
" * rss\n"
#endif /* RSS */
+#ifdef EVE
+ " * eve\n"
+#endif /* EVE */
#ifdef HAVE_IWLIB
" * wireless\n"
#endif /* HAVE_IWLIB */
#ifdef SMAPI
" * smapi\n"
#endif /* SMAPI */
- "", SYSTEM_CONFIG_FILE
+#ifdef NVIDIA
+ " * nvidia\n"
+#endif
);
exit(0);
}
-static const char *suffixes[] = { "B", "kiB", "MiB", "GiB", "TiB", "PiB", "" };
+static const char *suffixes[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "" };
+
#ifdef X11
#endif /* X11 */
+/* struct that has all info to be shared between
+ * instances of the same text object */
+struct information info;
+
/* default config file */
static char *current_config;
#ifdef X11
static int show_graph_scale;
+static int show_graph_range;
/* Position on the screen */
static int text_alignment;
static long color0, color1, color2, color3, color4, color5, color6, color7,
color8, color9;
+static char *template[10];
+
/* maximum number of special things, e.g. fonts, offsets, aligns, etc. */
static unsigned int max_specials = MAX_SPECIALS_DEFAULT;
/* pad percentages to decimals? */
static int pad_percents = 0;
-#ifdef TCP_PORT_MONITOR
-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-blocks */
-static int blockdepth = 0;
-static int if_jumped = 0;
-static int blockstart[MAX_IF_BLOCK_DEPTH];
-
int check_contains(char *f, char *s)
{
int ret = 0;
}
fseek(fp, orig_pos, SEEK_SET);
return ret;
-#undef BUFSZ
}
#ifndef HAVE_MEMRCHR
ret = file_pos + buf_pos;
}
return ret;
-#undef BUFSZ
}
static void new_bar(char *buf, int w, int h, int usage)
if (args) {
struct special_t *s = new_special(buf, FONT);
- if (s->font_added > font_count || !s->font_added || strncmp(args, fonts[s->font_added].name, DEFAULT_TEXT_BUFFER_SIZE)) {
+ if (s->font_added > font_count || !s->font_added || (strncmp(args, fonts[s->font_added].name, DEFAULT_TEXT_BUFFER_SIZE) != EQUAL) ) {
int tmp = selected_font;
selected_font = s->font_added = addfont(args);
}
}
#endif
-
-inline void graph_append(struct special_t *graph, double f)
+void graph_append(struct special_t *graph, double f, char showaslog)
{
int i;
+ if (showaslog) {
+#ifdef MATH
+ f = log10(f + 1);
+#endif
+ }
+
if (!graph->scaled && f > graph->graph_scale) {
f = graph->graph_scale;
}
+/* Already happens in new_graph
if (graph->scaled) {
graph->graph_scale = 1;
}
+*/
graph->graph[0] = f; /* add new data */
/* shift all the data by 1 */
for (i = graph->graph_width - 1; i > 0; i--) {
}
static void new_graph(char *buf, int w, int h, unsigned int first_colour,
- unsigned int second_colour, double i, int scale, int append)
+ unsigned int second_colour, double i, int scale, int append, char showaslog)
{
struct special_t *s = new_special(buf, GRAPH);
s->last_colour = adjust_colors(second_colour);
if (scale != 0) {
s->scaled = 0;
+ s->graph_scale = scale;
+ s->show_scale = 0;
} else {
s->scaled = 1;
+ s->graph_scale = 1;
+ s->show_scale = 1;
}
/* if (s->width) {
s->graph_width = s->width - 2; // subtract 2 for rectangle around
} */
- if (s->scaled) {
- s->graph_scale = 1;
- s->show_scale = 1;
- } else {
- s->graph_scale = scale;
- s->show_scale = 0;
+ if (showaslog) {
+#ifdef MATH
+ s->graph_scale = log10(s->graph_scale + 1);
+#endif
}
if (append) {
- graph_append(s, i);
+ graph_append(s, i, showaslog);
}
}
+//don't use spaces in LOGGRAPH or NORMGRAPH if you change them
+#define LOGGRAPH "log"
+#define NORMGRAPH "normal"
+
static char *scan_graph(const char *args, int *w, int *h,
unsigned int *first_colour, unsigned int *last_colour,
- unsigned int *scale)
+ unsigned int *scale, char *showaslog)
{
+ const char *nographtype;
char buf[64];
buf[0] = 0;
*first_colour = 0;
*last_colour = 0;
*scale = 0;
- /* graph's argument is either height or height,width */
if (args) {
- if (sscanf(args, "%d,%d %x %x %u", h, w, first_colour, last_colour,
- scale) == 5) {
+ //set showaslog and place the rest of the args in nographtype
+ if(strcasecmp(args, LOGGRAPH) == EQUAL) {
+ *showaslog = TRUE;
+ return NULL;
+ }else if(strcasecmp(args, NORMGRAPH) == EQUAL) {
+ *showaslog = FALSE;
+ return NULL;
+ }else if(strncasecmp(args, LOGGRAPH" ", strlen(LOGGRAPH) + 1 ) == EQUAL) {
+ *showaslog = TRUE;
+ nographtype = &args[strlen(LOGGRAPH) + 1];
+ }else if(strncasecmp(args, NORMGRAPH" ", strlen(NORMGRAPH) + 1 ) == EQUAL) {
+ *showaslog = FALSE;
+ nographtype = &args[strlen(NORMGRAPH) + 1];
+ }else{
+ *showaslog = FALSE;
+ nographtype = args;
+ }
+ //check the rest of the args
+ if (sscanf(nographtype, "%d,%d %x %x %u", h, w, first_colour, last_colour, scale) == 5) {
return NULL;
}
*scale = 0;
- if (sscanf(args, "%d,%d %x %x", h, w, first_colour, last_colour) == 4) {
+ if (sscanf(nographtype, "%d,%d %x %x", h, w, first_colour, last_colour) == 4) {
return NULL;
}
- if (sscanf(args, "%63s %d,%d %x %x %u", buf, h, w, first_colour,
- last_colour, scale) == 6) {
+ if (sscanf(nographtype, "%63s %d,%d %x %x %u", buf, h, w, first_colour, last_colour, scale) == 6) {
return strndup(buf, text_buffer_size);
}
*scale = 0;
- if (sscanf(args, "%63s %d,%d %x %x", buf, h, w, first_colour,
- last_colour) == 5) {
+ if (sscanf(nographtype, "%63s %d,%d %x %x", buf, h, w, first_colour, last_colour) == 5) {
return strndup(buf, text_buffer_size);
}
buf[0] = '\0';
*h = 25;
*w = 0;
- if (sscanf(args, "%x %x %u", first_colour, last_colour, scale) == 3) {
+ if (sscanf(nographtype, "%x %x %u", first_colour, last_colour, scale) == 3) {
return NULL;
}
*scale = 0;
- if (sscanf(args, "%x %x", first_colour, last_colour) == 2) {
+ if (sscanf(nographtype, "%x %x", first_colour, last_colour) == 2) {
return NULL;
}
- if (sscanf(args, "%63s %x %x %u", buf, first_colour, last_colour,
- scale) == 4) {
+ if (sscanf(nographtype, "%63s %x %x %u", buf, first_colour, last_colour, scale) == 4) {
return strndup(buf, text_buffer_size);
}
*scale = 0;
- if (sscanf(args, "%63s %x %x", buf, first_colour, last_colour) == 3) {
+ if (sscanf(nographtype, "%63s %x %x", buf, first_colour, last_colour) == 3) {
return strndup(buf, text_buffer_size);
}
buf[0] = '\0';
*first_colour = 0;
*last_colour = 0;
- if (sscanf(args, "%d,%d %u", h, w, scale) == 3) {
+ if (sscanf(nographtype, "%d,%d %u", h, w, scale) == 3) {
return NULL;
}
*scale = 0;
- if (sscanf(args, "%d,%d", h, w) == 2) {
+ if (sscanf(nographtype, "%d,%d", h, w) == 2) {
return NULL;
}
- if (sscanf(args, "%63s %d,%d %u", buf, h, w, scale) < 4) {
+ if (sscanf(nographtype, "%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);
+ sscanf(nographtype, "%63s %d,%d", buf, h, w);
}
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;
int precision, len;
static const int WIDTH = 10, SHORT_WIDTH = 8;
- if (num < 1024LL) {
+ if (num < 1024LL && num > -1024LL) {
if (short_units) {
spaced_print(buf, size, "%lld%c", SHORT_WIDTH, func_name, num,
**suffix);
return;
}
- while (num / 1024 >= 1000LL && **(suffix + 2)) {
+ while ((num / 1024 >= 1000LL || num / 1024 <= -1024LL) && **(suffix + 2)) {
num /= 1024;
suffix++;
}
suffix++;
fnum = num / 1024.0;
-
+
precision = 3;
do {
precision--;
} while (len >= (short_units ? SHORT_WIDTH : WIDTH) || len >= size);
}
-/* text handling */
-
-enum text_object_type {
- OBJ_addr,
-#if defined(__linux__)
- OBJ_addrs,
-#endif /* __linux__ */
-#ifndef __OpenBSD__
- OBJ_acpiacadapter,
- OBJ_adt746xcpu,
- OBJ_adt746xfan,
- OBJ_acpifan,
- OBJ_acpitemp,
- OBJ_acpitempf,
- OBJ_battery,
- OBJ_battery_time,
- OBJ_battery_percent,
- OBJ_battery_bar,
-#endif /* !__OpenBSD__ */
- OBJ_buffers,
- OBJ_cached,
- OBJ_color,
- OBJ_color0,
- OBJ_color1,
- OBJ_color2,
- OBJ_color3,
- OBJ_color4,
- OBJ_color5,
- OBJ_color6,
- OBJ_color7,
- OBJ_color8,
- OBJ_color9,
- OBJ_conky_version,
- OBJ_conky_build_date,
- OBJ_conky_build_arch,
- OBJ_font,
- OBJ_cpu,
- OBJ_cpubar,
- OBJ_cpugraph,
- OBJ_loadgraph,
- OBJ_diskio,
- OBJ_diskio_read,
- OBJ_diskio_write,
- OBJ_diskiograph,
- OBJ_diskiograph_read,
- OBJ_diskiograph_write,
- OBJ_downspeed,
- OBJ_downspeedf,
- OBJ_downspeedgraph,
- OBJ_else,
- OBJ_endif,
- OBJ_image,
- OBJ_exec,
- OBJ_execi,
- OBJ_texeci,
- OBJ_execbar,
- OBJ_execgraph,
- OBJ_execibar,
- OBJ_execigraph,
- OBJ_execp,
- OBJ_execpi,
- OBJ_freq,
- OBJ_freq_g,
- OBJ_freq_dyn,
- OBJ_freq_dyn_g,
- OBJ_fs_bar,
- OBJ_fs_bar_free,
- OBJ_fs_free,
- OBJ_fs_free_perc,
- OBJ_fs_size,
- OBJ_fs_type,
- OBJ_fs_used,
- OBJ_fs_used_perc,
- OBJ_goto,
- OBJ_tab,
- OBJ_hr,
- OBJ_offset,
- OBJ_voffset,
- OBJ_alignr,
- OBJ_alignc,
- OBJ_i2c,
- OBJ_platform,
- OBJ_hwmon,
-#if defined(__linux__)
- OBJ_disk_protect,
- OBJ_i8k_version,
- OBJ_i8k_bios,
- OBJ_i8k_serial,
- OBJ_i8k_cpu_temp,
- OBJ_i8k_cpu_tempf,
- OBJ_i8k_left_fan_status,
- OBJ_i8k_right_fan_status,
- OBJ_i8k_left_fan_rpm,
- OBJ_i8k_right_fan_rpm,
- OBJ_i8k_ac_status,
- OBJ_i8k_buttons_status,
- OBJ_ibm_fan,
- OBJ_ibm_temps,
- OBJ_ibm_volume,
- OBJ_ibm_brightness,
- OBJ_if_up,
- OBJ_if_gw,
- OBJ_ioscheduler,
- OBJ_gw_iface,
- OBJ_gw_ip,
- OBJ_laptop_mode,
- OBJ_pb_battery,
- OBJ_voltage_mv,
- OBJ_voltage_v,
- OBJ_wireless_essid,
- OBJ_wireless_mode,
- OBJ_wireless_bitrate,
- OBJ_wireless_ap,
- OBJ_wireless_link_qual,
- OBJ_wireless_link_qual_max,
- OBJ_wireless_link_qual_perc,
- OBJ_wireless_link_bar,
-#endif /* __linux__ */
- OBJ_if_empty,
- OBJ_if_existing,
- OBJ_if_mounted,
- OBJ_if_running,
- OBJ_top,
- OBJ_top_mem,
- OBJ_tail,
- OBJ_head,
- OBJ_kernel,
- OBJ_loadavg,
- OBJ_machine,
- OBJ_mails,
- OBJ_mboxscan,
- OBJ_mem,
- OBJ_membar,
- OBJ_memgraph,
- OBJ_memmax,
- OBJ_memperc,
- OBJ_mem_res,
- OBJ_mem_vsize,
- OBJ_mixer,
- OBJ_mixerl,
- OBJ_mixerr,
- OBJ_mixerbar,
- OBJ_mixerlbar,
- OBJ_mixerrbar,
- OBJ_nameserver,
- OBJ_new_mails,
- OBJ_nodename,
- OBJ_pre_exec,
- OBJ_processes,
- OBJ_running_processes,
- OBJ_shadecolor,
- OBJ_outlinecolor,
- OBJ_stippled_hr,
- OBJ_swap,
- OBJ_swapbar,
- OBJ_swapmax,
- OBJ_swapperc,
- OBJ_sysname,
- OBJ_temp1, /* i2c is used instead in these */
- OBJ_temp2,
- OBJ_text,
- OBJ_time,
- OBJ_utime,
- OBJ_tztime,
- OBJ_totaldown,
- OBJ_totalup,
- OBJ_updates,
- OBJ_upspeed,
- OBJ_upspeedf,
- OBJ_upspeedgraph,
- OBJ_uptime,
- OBJ_uptime_short,
- OBJ_user_names,
- OBJ_user_terms,
- OBJ_user_times,
- OBJ_user_number,
- OBJ_imap,
- OBJ_imap_messages,
- OBJ_imap_unseen,
- OBJ_pop3,
- OBJ_pop3_unseen,
- OBJ_pop3_used,
-#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
- || defined(__OpenBSD__)) && (defined(i386) || defined(__i386__))
- OBJ_apm_adapter,
- OBJ_apm_battery_time,
- OBJ_apm_battery_life,
-#endif /* __FreeBSD__ __OpenBSD__ */
-#ifdef __OpenBSD__
- OBJ_obsd_sensors_temp,
- OBJ_obsd_sensors_fan,
- OBJ_obsd_sensors_volt,
- OBJ_obsd_vendor,
- OBJ_obsd_product,
-#endif /* __OpenBSD__ */
-#ifdef MPD
- OBJ_mpd_title,
- OBJ_mpd_artist,
- OBJ_mpd_album,
- OBJ_mpd_random,
- OBJ_mpd_repeat,
- OBJ_mpd_vol,
- OBJ_mpd_bitrate,
- OBJ_mpd_status,
- OBJ_mpd_host,
- OBJ_mpd_port,
- OBJ_mpd_password,
- OBJ_mpd_bar,
- OBJ_mpd_elapsed,
- OBJ_mpd_length,
- OBJ_mpd_track,
- OBJ_mpd_name,
- OBJ_mpd_file,
- OBJ_mpd_percent,
- OBJ_mpd_smart,
-#endif
- OBJ_music_player_interval,
-#ifdef XMMS2
- OBJ_xmms2_artist,
- OBJ_xmms2_album,
- OBJ_xmms2_title,
- OBJ_xmms2_genre,
- OBJ_xmms2_comment,
- OBJ_xmms2_url,
- OBJ_xmms2_date,
- OBJ_xmms2_tracknr,
- OBJ_xmms2_bitrate,
- OBJ_xmms2_id,
- OBJ_xmms2_duration,
- OBJ_xmms2_elapsed,
- OBJ_xmms2_size,
- OBJ_xmms2_percent,
- OBJ_xmms2_status,
- OBJ_xmms2_bar,
- OBJ_xmms2_smart,
- OBJ_xmms2_playlist,
- OBJ_xmms2_timesplayed,
-#endif
-#ifdef AUDACIOUS
- OBJ_audacious_status,
- OBJ_audacious_title,
- OBJ_audacious_length,
- OBJ_audacious_length_seconds,
- OBJ_audacious_position,
- OBJ_audacious_position_seconds,
- OBJ_audacious_bitrate,
- OBJ_audacious_frequency,
- OBJ_audacious_channels,
- OBJ_audacious_filename,
- OBJ_audacious_playlist_length,
- OBJ_audacious_playlist_position,
- OBJ_audacious_bar,
-#endif
-#ifdef BMPX
- OBJ_bmpx_title,
- OBJ_bmpx_artist,
- OBJ_bmpx_album,
- OBJ_bmpx_track,
- OBJ_bmpx_uri,
- OBJ_bmpx_bitrate,
-#endif
-#ifdef RSS
- OBJ_rss,
-#endif
-#ifdef TCP_PORT_MONITOR
- OBJ_tcp_portmon,
-#endif
-#ifdef HAVE_ICONV
- OBJ_iconv_start,
- OBJ_iconv_stop,
-#endif
-#ifdef HDDTEMP
- OBJ_hddtemp,
-#endif
-#ifdef SMAPI
- OBJ_smapi,
- OBJ_smapi_bat_bar,
- OBJ_smapi_bat_perc,
- OBJ_if_smapi_bat_installed,
-#endif
- OBJ_entropy_avail,
- OBJ_entropy_poolsize,
- OBJ_entropy_bar
-};
-
-struct text_object {
- union {
- char *s; /* some string */
- int i; /* some integer */
- long l; /* some other integer */
- unsigned int sensor;
- struct net_stat *net;
- struct fs_stat *fs;
- struct diskio_stat *diskio;
- unsigned char loadavg[3];
- unsigned int cpu_index;
- struct mail_s *mail;
-
- struct {
- char *args;
- char *output;
- } mboxscan;
-
- struct {
- char *tz; /* timezone variable */
- char *fmt; /* time display formatting */
- } tztime;
-
- struct {
- struct fs_stat *fs;
- int w, h;
- } fsbar; /* 3 */
-
- struct {
- int l;
- int w, h;
- } mixerbar; /* 3 */
-
- struct {
- int fd;
- int arg;
- char devtype[256];
- char type[64];
- } sysfs; /* 2 */
-
- struct {
- int pos;
- char *s;
- char *str;
- } ifblock;
-
- struct {
- int num;
- int type;
- } top;
-
- struct {
- int wantedlines;
- int readlines;
- char *logfile;
- double last_update;
- float interval;
- char *buffer;
- /* If not -1, a file descriptor to read from when
- * logfile is a FIFO. */
- int fd;
- } tail;
-
- struct {
- double last_update;
- float interval;
- char *cmd;
- char *buffer;
- double data;
- } execi; /* 5 */
-
- struct {
- float interval;
- char *cmd;
- char *buffer;
- double data;
- timed_thread *p_timed_thread;
- } texeci;
-
- struct {
- int a, b;
- } pair; /* 2 */
-#ifdef TCP_PORT_MONITOR
- struct {
- /* starting port to monitor */
- in_port_t port_range_begin;
- /* ending port to monitor */
- in_port_t port_range_end;
- /* enum from libtcp-portmon.h, e.g. COUNT, etc. */
- int item;
- /* 0 to n-1 connections. */
- int connection_index;
- } tcp_port_monitor;
-#endif
-#ifdef HDDTEMP
- struct {
- char *addr;
- int port;
- char *dev;
- double update_time;
- char *temp;
- char unit;
- } hddtemp; /* 2 */
-#endif
-#ifdef RSS
- struct {
- char *uri;
- char *action;
- int act_par;
- int delay;
- } rss;
-#endif
- struct local_mail_s local_mail;
- } data;
- int type;
- int a, b;
- long line;
- unsigned int c, d, e;
- float f;
- char global_mode;
-};
-
-struct text_object_list {
- unsigned int text_object_count;
- struct text_object *text_objects;
-};
+/* global object list root element */
+static struct text_object global_root_object;
-static unsigned int global_text_object_count;
-static struct text_object *global_text_objects;
static void generate_text_internal(char *p, int p_max_size,
- struct text_object *objs, unsigned int object_count,
- struct information *cur);
-
-#define MAXDATASIZE 1000
-#define POP3 1
-#define IMAP 2
+ struct text_object text_object, struct information *cur);
-struct mail_s *parse_mail_args(char type, const char *arg)
+static inline void read_exec(const char *data, char *buf, const int size)
{
- struct mail_s *mail;
- char *tmp;
-
- mail = malloc(sizeof(struct mail_s));
- memset(mail, 0, sizeof(struct mail_s));
-
- if (sscanf(arg, "%128s %128s %128s", mail->host, mail->user, mail->pass)
- != 3) {
- if (type == POP3) {
- ERR("Scanning IMAP args failed");
- } else if (type == IMAP) {
- ERR("Scanning POP3 args failed");
- }
- }
- // see if password needs prompting
- if (mail->pass[0] == '*' && mail->pass[1] == '\0') {
- int fp = fileno(stdin);
- struct termios term;
-
- tcgetattr(fp, &term);
- term.c_lflag &= ~ECHO;
- tcsetattr(fp, TCSANOW, &term);
- printf("Enter mailbox password (%s@%s): ", mail->user, mail->host);
- scanf("%128s", mail->pass);
- printf("\n");
- term.c_lflag |= ECHO;
- tcsetattr(fp, TCSANOW, &term);
- }
- // now we check for optional args
- tmp = strstr(arg, "-i ");
- if (tmp) {
- tmp += 3;
- sscanf(tmp, "%f", &mail->interval);
- } else {
- mail->interval = 300; // 5 minutes
- }
- tmp = strstr(arg, "-p ");
- if (tmp) {
- tmp += 3;
- sscanf(tmp, "%lu", &mail->port);
- } else {
- if (type == POP3) {
- mail->port = 110; // default pop3 port
- } else if (type == IMAP) {
- mail->port = 143; // default imap port
- }
- }
- if (type == IMAP) {
- tmp = strstr(arg, "-f ");
- if (tmp) {
- tmp += 3;
- sscanf(tmp, "%s", mail->folder);
- } else {
- strncpy(mail->folder, "INBOX", 128); // default imap inbox
- }
- }
- tmp = strstr(arg, "-e ");
- if (tmp) {
- int len = 1024;
- tmp += 3;
+ FILE *fp = popen(data, "r");
+ int length = fread(buf, 1, size, fp);
- if (tmp[0] == '\'') {
- len = strstr(tmp + 1, "'") - tmp - 1;
- if (len > 1024) {
- len = 1024;
- }
- }
- strncpy(mail->command, tmp + 1, len);
- } else {
- mail->command[0] = '\0';
+ pclose(fp);
+ buf[length] = '\0';
+ if (length > 0 && buf[length - 1] == '\n') {
+ buf[length - 1] = '\0';
}
- mail->p_timed_thread = NULL;
- return mail;
-}
-
-void *imap_thread(void *arg)
-{
- int sockfd, numbytes;
- char recvbuf[MAXDATASIZE];
- char sendbuf[MAXDATASIZE];
- char *reply;
- int fail = 0;
- unsigned int old_unseen = UINT_MAX;
- unsigned int old_messages = UINT_MAX;
- struct stat stat_buf;
- 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;
-
-#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);
- }
- 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_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++;
- 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");
- fail++;
- break;
- }
- } else {
- ERR("IMAP connection failed: timeout");
- fail++;
- break;
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "* OK") != recvbuf) {
- ERR("IMAP connection failed, probably not an IMAP server");
- fail++;
- 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++;
- 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++;
- break;
- }
- 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;
- }
- 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);
- }
- if (timed_thread_test(mail->p_timed_thread)) {
- timed_thread_exit(mail->p_timed_thread);
- }
- }
- mail->unseen = 0;
- mail->messages = 0;
- return 0;
-}
-
-void *pop3_thread(void *arg)
-{
- int sockfd, numbytes;
- char recvbuf[MAXDATASIZE];
- char sendbuf[MAXDATASIZE];
- char *reply;
- int fail = 0;
- unsigned int old_unseen = UINT_MAX;
- struct stat stat_buf;
- 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;
-
-#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);
- }
- 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_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++;
- 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");
- fail++;
- break;
- }
- } else {
- ERR("POP3 connection failed: timeout\n");
- fail++;
- break;
- }
- 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++;
- 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++;
- 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++;
- 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 PASS");
- fail++;
- break;
- }
- }
- recvbuf[numbytes] = '\0';
- if (strstr(recvbuf, "+OK ") == NULL) {
- ERR("POP3 server login failed: %s", recvbuf);
- fail++;
- break;
- }
- strncpy(sendbuf, "STAT\r\n", MAXDATASIZE);
- if (send(sockfd, sendbuf, strlen(sendbuf), 0) == -1) {
- perror("send STAT");
- 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 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);
- }
- if (timed_thread_test(mail->p_timed_thread)) {
- timed_thread_exit(mail->p_timed_thread);
- }
- }
- mail->unseen = 0;
- mail->used = 0;
- return 0;
}
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) {
p2 = obj->data.texeci.buffer;
- fp = popen(obj->data.texeci.cmd, "r");
-
timed_thread_lock(obj->data.texeci.p_timed_thread);
- n2 = fread(p2, 1, text_buffer_size, fp);
-
- pclose(fp);
- p2[n2] = '\0';
- if (n2 && p2[n2 - 1] == '\n') {
- p2[n2 - 1] = '\0';
- }
+ read_exec(obj->data.texeci.cmd, obj->data.texeci.buffer,
+ text_buffer_size);
while (*p2) {
if (*p2 == '\001') {
*p2 = ' ';
p2++;
}
timed_thread_unlock(obj->data.texeci.p_timed_thread);
- if (timed_thread_test(obj->data.texeci.p_timed_thread)) {
+ if (timed_thread_test(obj->data.texeci.p_timed_thread, 0)) {
timed_thread_exit(obj->data.texeci.p_timed_thread);
}
}
return obj;
}
-static void free_text_objects(unsigned int count, struct text_object *objs)
+/*
+ * call with full == 0 when freeing after 'internal' evaluation of objects
+ */
+static void free_text_objects(struct text_object *root, char full)
{
- unsigned int i;
+ struct text_object *obj;
+
+ if (!root->prev) {
+ return;
+ }
- for (i = 0; i < count; i++) {
- switch (objs[i].type) {
+#define data obj->data
+ for (obj = root->prev; obj; obj = root->prev) {
+ root->prev = obj->prev;
+ switch (obj->type) {
#ifndef __OpenBSD__
case OBJ_acpitemp:
- case OBJ_acpitempf:
- close(objs[i].data.i);
+ close(data.i);
break;
case OBJ_i2c:
case OBJ_platform:
case OBJ_hwmon:
- close(objs[i].data.sysfs.fd);
+ close(data.sysfs.fd);
break;
#endif /* !__OpenBSD__ */
case OBJ_time:
case OBJ_utime:
- free(objs[i].data.s);
+ free(data.s);
break;
case OBJ_tztime:
- free(objs[i].data.tztime.tz);
- free(objs[i].data.tztime.fmt);
+ free(data.tztime.tz);
+ free(data.tztime.fmt);
break;
case OBJ_mboxscan:
- free(objs[i].data.mboxscan.args);
- free(objs[i].data.mboxscan.output);
+ free(data.mboxscan.args);
+ free(data.mboxscan.output);
break;
case OBJ_mails:
case OBJ_new_mails:
- free(objs[i].data.local_mail.box);
+ free(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(data.mail);
}
break;
case OBJ_imap_messages:
- if (!objs[i].global_mode) {
- free(objs[i].data.mail);
+ if (!obj->global_mode) {
+ free(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(data.mail);
}
break;
case OBJ_pop3_used:
- if (!objs[i].global_mode) {
- free(objs[i].data.mail);
+ if (!obj->global_mode) {
+ free(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(data.ifblock.s);
+ free(data.ifblock.str);
break;
case OBJ_tail:
- free(objs[i].data.tail.logfile);
- free(objs[i].data.tail.buffer);
+ free(data.tail.logfile);
+ free(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(data.s);
break;
#ifdef HAVE_ICONV
case OBJ_iconv_start:
#endif
#ifdef __LINUX__
case OBJ_disk_protect:
- free(objs[i].data.s);
+ free(obj->data.s);
break;
case OBJ_if_up:
- 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_if_gw:
- free(objs[i].data.ifblock.s);
- free(objs[i].data.ifblock.str);
+ free(obj->data.ifblock.s);
+ free(obj->data.ifblock.str);
case OBJ_gw_iface:
case OBJ_gw_ip:
if (info.gw_info.iface) {
}
break;
case OBJ_ioscheduler:
- if(objs[i].data.s)
- free(objs[i].data.s);
+ if(obj->data.s)
+ free(obj->data.s);
break;
#endif
#ifdef XMMS2
case OBJ_bmpx_bitrate:
break;
#endif
+#ifdef EVE
+ case OBJ_eve:
+ break;
+#endif
#ifdef RSS
case OBJ_rss:
- free(objs[i].data.rss.uri);
- free(objs[i].data.rss.action);
+ free(data.rss.uri);
+ free(data.rss.action);
break;
#endif
case OBJ_pre_exec:
break;
#ifndef __OpenBSD__
case OBJ_battery:
- free(objs[i].data.s);
+ free(data.s);
break;
case OBJ_battery_time:
- free(objs[i].data.s);
+ free(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(data.execi.cmd);
+ free(data.execi.buffer);
break;
case OBJ_texeci:
- free(objs[i].data.texeci.cmd);
- free(objs[i].data.texeci.buffer);
+ free(data.texeci.cmd);
+ free(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(objs[i].data.hddtemp.temp);
+ free(data.hddtemp.dev);
+ free(data.hddtemp.addr);
+ if (data.hddtemp.temp)
+ free(data.hddtemp.temp);
break;
#endif
case OBJ_entropy_avail:
#ifdef SMAPI
case OBJ_smapi:
case OBJ_smapi_bat_perc:
- free(objs[i].data.s);
+ case OBJ_smapi_bat_temp:
+ case OBJ_smapi_bat_power:
+ free(data.s);
break;
case OBJ_if_smapi_bat_installed:
- free(objs[i].data.ifblock.s);
- free(objs[i].data.ifblock.str);
+ free(data.ifblock.s);
+ free(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);
+ case OBJ_if_mpd_playing:
+ if (full) {
+ free_mpd_vars(&info.mpd);
+ }
break;
#endif
+#ifdef MOC
+ case OBJ_moc_state:
+ case OBJ_moc_file:
+ case OBJ_moc_title:
+ case OBJ_moc_artist:
+ case OBJ_moc_song:
+ case OBJ_moc_album:
+ case OBJ_moc_totaltime:
+ case OBJ_moc_timeleft:
+ case OBJ_moc_curtime:
+ case OBJ_moc_bitrate:
+ case OBJ_moc_rate:
+ free_moc(&info.moc);
+ break;
+#endif
+ case OBJ_scroll:
+ free(data.scroll.text);
+ break;
}
+ free(obj);
}
- free(objs);
- /* text_objects = NULL;
- text_object_count = 0; */
+#undef data
+ /* FIXME: below is surely useless */
+ if (full) {} // disable warning when MPD !defined
}
void scan_mixer_bar(const char *arg, int *a, int *w, int *h)
}
}
-/* strip a leading /dev/ if any */
-#define DEV_NAME(x) strncmp(x, "/dev/", 5) ? x : x + 5
+/* strip a leading /dev/ if any, following symlinks first
+ *
+ * BEWARE: this function returns a pointer to static content
+ * which gets overwritten in consecutive calls. I.e.:
+ * this function is NOT reentrant.
+ */
+const char *dev_name(const char *path)
+{
+ static char buf[255]; /* should be enough for pathnames */
+ ssize_t buflen;
+
+#define DEV_NAME(x) \
+ x != NULL && strlen(x) > 5 && strncmp(x, "/dev/", 5) == 0 ? x + 5 : x
+ if ((buflen = readlink(path, buf, 254)) == -1)
+ return DEV_NAME(path);
+ buf[buflen] = '\0';
+ return DEV_NAME(buf);
+#undef DEV_NAME
+}
/* 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,
- struct text_object *text_objects, long line)
+ const char *arg, long line, char allow_threaded)
{
// struct text_object *obj = new_text_object();
struct text_object *obj = new_text_object_internal();
#define OBJ(a, n) if (strcmp(s, #a) == 0) { \
obj->type = OBJ_##a; need_mask |= (1 << n); {
+#define OBJ_THREAD(a, n) if (strcmp(s, #a) == 0 && allow_threaded) { \
+ obj->type = OBJ_##a; need_mask |= (1 << n); {
#define END } } else
#ifdef X11
#else
OBJ(acpitemp, 0)
obj->data.i = open_acpi_temperature(arg);
- END OBJ(acpitempf, 0)
- obj->data.i = open_acpi_temperature(arg);
END OBJ(acpiacadapter, 0)
END OBJ(freq, INFO_FREQ)
#endif /* !__OpenBSD__ */
#endif /* HAVE_IWLIB */
#endif /* __linux__ */
- END OBJ(freq_dyn, 0)
- END OBJ(freq_dyn_g, 0)
#ifndef __OpenBSD__
END OBJ(acpifan, 0)
#if defined(__linux__)
END OBJ(disk_protect, 0)
if (arg)
- obj->data.s = strndup(DEV_NAME(arg), text_buffer_size);
+ obj->data.s = strndup(dev_name(arg), text_buffer_size);
else
CRIT_ERR("disk_protect needs an argument");
END OBJ(i8k_version, INFO_I8K)
END OBJ(i8k_bios, INFO_I8K)
END OBJ(i8k_serial, INFO_I8K)
END OBJ(i8k_cpu_temp, INFO_I8K)
- END OBJ(i8k_cpu_tempf, INFO_I8K)
END OBJ(i8k_left_fan_status, INFO_I8K)
END OBJ(i8k_right_fan_status, INFO_I8K)
END OBJ(i8k_left_fan_rpm, INFO_I8K)
END OBJ(ibm_volume, 0)
END OBJ(ibm_brightness, 0)
END OBJ(if_up, 0)
- if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
- CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
- }
if (!arg) {
ERR("if_up needs an argument");
obj->data.ifblock.s = 0;
} else
obj->data.ifblock.s = strndup(arg, text_buffer_size);
- blockstart[blockdepth] = object_count;
- obj->data.ifblock.pos = object_count + 2;
- blockdepth++;
+ obj_be_ifblock_if(obj);
END OBJ(if_gw, 0)
- if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
- CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
- }
- blockstart[blockdepth] = object_count;
- obj->data.ifblock.pos = object_count + 2;
- blockdepth++;
+ obj_be_ifblock_if(obj);
END OBJ(ioscheduler, 0)
if (!arg) {
CRIT_ERR("get_ioscheduler needs an argument (e.g. hda)");
obj->data.s = 0;
} else
- obj->data.s = strndup(DEV_NAME(arg), text_buffer_size);
+ 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) {
+ if (arg && strcmp(arg, "status") == EQUAL) {
obj->data.i = PB_BATT_STATUS;
- } else if (arg && strcmp(arg, "percent") == 0) {
+ } else if (arg && strcmp(arg, "percent") == EQUAL) {
obj->data.i = PB_BATT_PERCENT;
- } else if (arg && strcmp(arg, "time") == 0) {
+ } else if (arg && strcmp(arg, "time") == EQUAL) {
obj->data.i = PB_BATT_TIME;
} else {
ERR("pb_battery: needs one argument: status, percent or time");
END OBJ(cached, INFO_BUFFERS)
END OBJ(cpu, INFO_CPU)
if (arg) {
- if (strncmp(arg, "cpu", 3) == 0 && isdigit(arg[3])) {
+ if (strncmp(arg, "cpu", 3) == EQUAL && isdigit(arg[3])) {
obj->data.cpu_index = atoi(&arg[3]);
arg += 4;
} else {
obj->data.cpu_index = 0;
}
+ DBGP2("Adding $cpu for CPU %d", obj->data.cpu_index);
} else {
obj->data.cpu_index = 0;
}
END OBJ(cpubar, INFO_CPU)
if (arg) {
- if (strncmp(arg, "cpu", 3) == 0 && isdigit(arg[3])) {
+ if (strncmp(arg, "cpu", 3) == EQUAL && isdigit(arg[3])) {
obj->data.cpu_index = atoi(&arg[3]);
arg += 4;
} else {
scan_bar(arg, &obj->a, &obj->b);
obj->data.cpu_index = 0;
}
+ DBGP2("Adding $cpubar for CPU %d", obj->data.cpu_index);
END OBJ(cpugraph, INFO_CPU)
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
- &obj->e);
+ &obj->e, &obj->showaslog);
if (buf) {
- if (strncmp(buf, "cpu", 3) == 0 && isdigit(buf[3])) {
+ if (strncmp(buf, "cpu", 3) == EQUAL && isdigit(buf[3])) {
obj->data.cpu_index = atoi(&buf[3]);
} else {
obj->data.cpu_index = 0;
}
free(buf);
}
+ DBGP2("Adding $cpugraph for CPU %d", obj->data.cpu_index);
END OBJ(loadgraph, INFO_LOADAVG)
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
- &obj->e);
+ &obj->e, &obj->showaslog);
if (buf) {
int a = 1, r = 3;
if (arg) {
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(DEV_NAME(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(DEV_NAME(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(DEV_NAME(arg));
+ obj->data.diskio = prepare_diskio_stat(dev_name(arg));
} else {
obj->data.diskio = NULL;
}
END OBJ(diskiograph, INFO_DISKIO)
- char *buf = scan_graph(DEV_NAME(arg), &obj->a, &obj->b, &obj->c, &obj->d,
- &obj->e);
+ char *buf = scan_graph(dev_name(arg), &obj->a, &obj->b, &obj->c, &obj->d,
+ &obj->e, &obj->showaslog);
if (buf) {
obj->data.diskio = prepare_diskio_stat(buf);
obj->data.diskio = NULL;
}
END OBJ(diskiograph_read, INFO_DISKIO)
- char *buf = scan_graph(DEV_NAME(arg), &obj->a, &obj->b, &obj->c, &obj->d,
- &obj->e);
+ char *buf = scan_graph(dev_name(arg), &obj->a, &obj->b, &obj->c, &obj->d,
+ &obj->e, &obj->showaslog);
if (buf) {
obj->data.diskio = prepare_diskio_stat(buf);
obj->data.diskio = NULL;
}
END OBJ(diskiograph_write, INFO_DISKIO)
- char *buf = scan_graph(DEV_NAME(arg), &obj->a, &obj->b, &obj->c, &obj->d,
- &obj->e);
+ char *buf = scan_graph(dev_name(arg), &obj->a, &obj->b, &obj->c, &obj->d,
+ &obj->e, &obj->showaslog);
if (buf) {
obj->data.diskio = prepare_diskio_stat(buf);
} else {
obj->data.diskio = NULL;
}
+#endif
END OBJ(color, 0)
#ifdef X11
obj->data.l = arg ? get_x11_color(arg) : default_fg_color;
}
END OBJ(downspeedgraph, INFO_NET)
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
- &obj->e);
+ &obj->e, &obj->showaslog);
- if (buf) {
- obj->data.net = get_net_stat(buf);
- free(buf);
- }
+ // default to DEFAULTNETDEV
+ buf = strndup(buf ? buf : "DEFAULTNETDEV", text_buffer_size);
+ obj->data.net = get_net_stat(buf);
+ free(buf);
END OBJ(else, 0)
- if (blockdepth) {
- (text_objects[blockstart[blockdepth - 1]]).data.ifblock.pos =
- object_count;
- blockstart[blockdepth - 1] = object_count;
- obj->data.ifblock.pos = object_count + 2;
- } else {
- ERR("$else: no matching $if_*");
- }
+ obj_be_ifblock_else(obj);
END OBJ(endif, 0)
- if (blockdepth) {
- blockdepth--;
- text_objects[blockstart[blockdepth]].data.ifblock.pos =
- object_count;
- } else {
- ERR("$endif: no matching $if_*");
- }
+ obj_be_ifblock_endif(obj);
END OBJ(image, 0)
obj->data.s = strndup(arg ? arg : "", text_buffer_size);
#ifdef HAVE_POPEN
obj->data.execi.cmd = strndup(arg + n, text_buffer_size);
obj->data.execi.buffer = malloc(text_buffer_size);
}
- END OBJ(texeci, 0)
- 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 = strndup(buf, text_buffer_size);
- } else {
- 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;
- END OBJ(pre_exec, 0)
- obj->type = OBJ_text;
- if (arg) {
- FILE *fp = popen(arg, "r");
- unsigned int n;
- char buf[2048];
+ END OBJ_THREAD(texeci, 0)
+ int n;
- n = fread(buf, 1, 2048, fp);
- buf[n] = '\0';
+ if (!arg || sscanf(arg, "%f %n", &obj->data.texeci.interval, &n) <= 0) {
+ char buf[256];
- if (n && buf[n - 1] == '\n') {
- buf[n - 1] = '\0';
+ ERR("${texeci <interval> command}");
+ obj->type = OBJ_text;
+ snprintf(buf, 256, "${%s}", s);
+ obj->data.s = strndup(buf, text_buffer_size);
+ } else {
+ 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;
+ END OBJ(pre_exec, 0)
+ obj->type = OBJ_text;
+ if (arg) {
+ char buf[2048];
- pclose(fp);
-
- obj->data.s = strndup(buf, text_buffer_size);
- } else {
- obj->data.s = strndup("", text_buffer_size);
- }
+ read_exec(arg, buf, sizeof(buf));
+ obj->data.s = strndup(buf, text_buffer_size);
+ } else {
+ obj->data.s = strndup("", text_buffer_size);
+ }
#endif
END OBJ(fs_bar, INFO_FS)
arg = scan_bar(arg, &obj->data.fsbar.w, &obj->data.fsbar.h);
- if (arg) {
+ if (arg) {
while (isspace(*arg)) {
arg++;
}
return NULL;
}
if (sscanf(arg, "%63s %i", buf, &n) == 2) {
- if (strcmp(buf, "name") == 0) {
+ if (strcmp(buf, "name") == EQUAL) {
obj->data.top.type = TOP_NAME;
- } else if (strcmp(buf, "cpu") == 0) {
+ } else if (strcmp(buf, "cpu") == EQUAL) {
obj->data.top.type = TOP_CPU;
- } else if (strcmp(buf, "pid") == 0) {
+ } else if (strcmp(buf, "pid") == EQUAL) {
obj->data.top.type = TOP_PID;
- } else if (strcmp(buf, "mem") == 0) {
+ } else if (strcmp(buf, "mem") == EQUAL) {
obj->data.top.type = TOP_MEM;
- } else if (strcmp(buf, "time") == 0) {
+ } else if (strcmp(buf, "time") == EQUAL) {
obj->data.top.type = TOP_TIME;
- } else if (strcmp(buf, "mem_res") == 0) {
+ } else if (strcmp(buf, "mem_res") == EQUAL) {
obj->data.top.type = TOP_MEM_RES;
- } else if (strcmp(buf, "mem_vsize") == 0) {
+ } else if (strcmp(buf, "mem_vsize") == EQUAL) {
obj->data.top.type = TOP_MEM_VSIZE;
} else {
ERR("invalid arg for top");
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) {
return NULL;
}
if (sscanf(arg, "%63s %i", buf, &n) == 2) {
- if (strcmp(buf, "name") == 0) {
+ if (strcmp(buf, "name") == EQUAL) {
obj->data.top.type = TOP_NAME;
- } else if (strcmp(buf, "cpu") == 0) {
+ } else if (strcmp(buf, "cpu") == EQUAL) {
obj->data.top.type = TOP_CPU;
- } else if (strcmp(buf, "pid") == 0) {
+ } else if (strcmp(buf, "pid") == EQUAL) {
obj->data.top.type = TOP_PID;
- } else if (strcmp(buf, "mem") == 0) {
+ } else if (strcmp(buf, "mem") == EQUAL) {
obj->data.top.type = TOP_MEM;
- } else if (strcmp(buf, "time") == 0) {
+ } else if (strcmp(buf, "time") == EQUAL) {
obj->data.top.type = TOP_TIME;
- } else if (strcmp(buf, "mem_res") == 0) {
+ } else if (strcmp(buf, "mem_res") == EQUAL) {
obj->data.top.type = TOP_MEM_RES;
- } else if (strcmp(buf, "mem_vsize") == 0) {
+ } else if (strcmp(buf, "mem_vsize") == EQUAL) {
obj->data.top.type = TOP_MEM_VSIZE;
} else {
ERR("invalid arg for top");
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;
return NULL;
} else if (n2 < 1 || n2 < update_interval) {
CRIT_ERR("invalid arg for tail, interval must be greater than "
- "0 and Conky's interval");
+ "0 and "PACKAGE_NAME"'s interval");
return NULL;
} else {
FILE *fp = 0;
return NULL;
} else if (n2 < 1 || n2 < update_interval) {
CRIT_ERR("invalid arg for head, interval must be greater than "
- "0 and Conky's interval");
+ "0 and "PACKAGE_NAME"'s interval");
return NULL;
} else {
FILE *fp;
}
/* asumming all else worked */
obj->data.tail.buffer = malloc(text_buffer_size * 20);
+ END OBJ(lines, 0)
+ if (arg) {
+ obj->data.s = strdup(arg);
+ }else{
+ CRIT_ERR("lines needs a argument");
+ }
+ END OBJ(words, 0)
+ if (arg) {
+ obj->data.s = strdup(arg);
+ }else{
+ CRIT_ERR("words needs a argument");
+ }
END OBJ(loadavg, INFO_LOADAVG)
int a = 1, b = 2, c = 3, r = 3;
obj->data.loadavg[1] = (r >= 2) ? (unsigned char) b : 0;
obj->data.loadavg[2] = (r >= 3) ? (unsigned char) c : 0;
END OBJ(if_empty, 0)
- if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
- CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
- }
if (!arg) {
ERR("if_empty needs an argument");
obj->data.ifblock.s = 0;
} else {
obj->data.ifblock.s = strndup(arg, text_buffer_size);
}
- blockstart[blockdepth] = object_count;
- obj->data.ifblock.pos = object_count + 2;
- blockdepth++;
+ obj_be_ifblock_if(obj);
END OBJ(if_existing, 0)
- if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
- CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
- }
if (!arg) {
ERR("if_existing needs an argument or two");
obj->data.ifblock.s = NULL;
obj->data.ifblock.str = strndup(buf2, text_buffer_size);
}
}
- blockstart[blockdepth] = object_count;
- obj->data.ifblock.pos = object_count + 2;
- blockdepth++;
+ DBGP("if_existing: '%s' '%s'", obj->data.ifblock.s, obj->data.ifblock.str);
+ obj_be_ifblock_if(obj);
END OBJ(if_mounted, 0)
- if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
- CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
- }
if (!arg) {
ERR("if_mounted needs an argument");
obj->data.ifblock.s = 0;
} else {
obj->data.ifblock.s = strndup(arg, text_buffer_size);
}
- blockstart[blockdepth] = object_count;
- obj->data.ifblock.pos = object_count + 2;
- blockdepth++;
+ obj_be_ifblock_if(obj);
END OBJ(if_running, 0)
- if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
- CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
- }
if (arg) {
char buf[256];
ERR("if_running needs an argument");
obj->data.ifblock.s = 0;
}
- blockstart[blockdepth] = object_count;
- obj->data.ifblock.pos = object_count + 2;
- blockdepth++;
+ obj_be_ifblock_if(obj);
END OBJ(kernel, 0)
END OBJ(machine, 0)
END OBJ(mails, 0)
obj->data.mboxscan.output[0] = 1;
strncpy(obj->data.mboxscan.args, arg, text_buffer_size);
END OBJ(mem, INFO_MEM)
+ END OBJ(memeasyfree, INFO_MEM)
+ END OBJ(memfree, INFO_MEM)
END OBJ(memmax, INFO_MEM)
END OBJ(memperc, INFO_MEM)
END OBJ(membar, INFO_MEM)
scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
END OBJ(memgraph, INFO_MEM)
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
- &obj->e);
+ &obj->e, &obj->showaslog);
if (buf) {
free(buf);
END OBJ(mixerrbar, INFO_MIXER)
scan_mixer_bar(arg, &obj->data.mixerbar.l, &obj->data.mixerbar.w,
&obj->data.mixerbar.h);
+#ifdef X11
+ END OBJ(monitor, INFO_X11)
+ END OBJ(monitor_number, INFO_X11)
+#endif
END OBJ(new_mails, 0)
float n1;
char box[256], dst[256];
END OBJ(upspeedgraph, INFO_NET)
char *buf = scan_graph(arg, &obj->a, &obj->b, &obj->c, &obj->d,
- &obj->e);
+ &obj->e, &obj->showaslog);
- if (buf) {
- obj->data.net = get_net_stat(buf);
- free(buf);
- }
+ // default to DEFAULTNETDEV
+ buf = strndup(buf ? buf : "DEFAULTNETDEV", text_buffer_size);
+ obj->data.net = get_net_stat(buf);
+ free(buf);
END OBJ(uptime_short, INFO_UPTIME)
END OBJ(uptime, INFO_UPTIME)
END OBJ(user_names, INFO_USERS)
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)
END OBJ(apm_battery_life, 0)
END OBJ(apm_battery_time, 0)
#endif /* __FreeBSD__ */
- END OBJ(imap_unseen, 0)
+ END OBJ_THREAD(imap_unseen, 0)
if (arg) {
// proccss
- obj->data.mail = parse_mail_args(IMAP, arg);
+ obj->data.mail = parse_mail_args(IMAP_TYPE, arg);
obj->global_mode = 0;
} else {
obj->global_mode = 1;
}
- END OBJ(imap_messages, 0)
+ END OBJ_THREAD(imap_messages, 0)
if (arg) {
// proccss
- obj->data.mail = parse_mail_args(IMAP, arg);
+ obj->data.mail = parse_mail_args(IMAP_TYPE, arg);
obj->global_mode = 0;
} else {
obj->global_mode = 1;
}
- END OBJ(pop3_unseen, 0)
+ END OBJ_THREAD(pop3_unseen, 0)
if (arg) {
// proccss
- obj->data.mail = parse_mail_args(POP3, arg);
+ obj->data.mail = parse_mail_args(POP3_TYPE, arg);
obj->global_mode = 0;
} else {
obj->global_mode = 1;
}
- END OBJ(pop3_used, 0)
+ END OBJ_THREAD(pop3_used, 0)
if (arg) {
// proccss
- obj->data.mail = parse_mail_args(POP3, arg);
+ obj->data.mail = parse_mail_args(POP3_TYPE, arg);
obj->global_mode = 0;
} else {
obj->global_mode = 1;
else
ERR("smapi needs an argument");
END OBJ(if_smapi_bat_installed, 0)
- if (blockdepth >= MAX_IF_BLOCK_DEPTH) {
- CRIT_ERR("MAX_IF_BLOCK_DEPTH exceeded");
- }
if (!arg) {
ERR("if_smapi_bat_installed needs an argument");
obj->data.ifblock.s = 0;
} else
obj->data.ifblock.s = strndup(arg, text_buffer_size);
- blockstart[blockdepth] = object_count;
- obj->data.ifblock.pos = object_count + 2;
- blockdepth++;
+ obj_be_ifblock_if(obj);
END OBJ(smapi_bat_perc, 0)
if (arg)
obj->data.s = strndup(arg, text_buffer_size);
else
ERR("smapi_bat_perc needs an argument");
+ END OBJ(smapi_bat_temp, 0)
+ if (arg)
+ obj->data.s = strndup(arg, text_buffer_size);
+ else
+ ERR("smapi_bat_temp needs an argument");
+ END OBJ(smapi_bat_power, 0)
+ if (arg)
+ obj->data.s = strndup(arg, text_buffer_size);
+ else
+ ERR("smapi_bat_power needs an argument");
END OBJ(smapi_bat_bar, 0)
if(arg) {
int cnt;
arg = scan_bar(arg + cnt, &obj->a, &obj->b);
}
} else
- ERR("if_smapi_bat_bar needs an argument");
+ ERR("smapi_bat_bar needs an argument");
#endif /* SMAPI */
#ifdef MPD
- END OBJ(mpd_artist, INFO_MPD)
- END OBJ(mpd_title, INFO_MPD)
- if (arg) {
- sscanf(arg, "%d", &info.mpd.max_title_len);
- if (info.mpd.max_title_len > 0) {
- info.mpd.max_title_len++;
- } else {
- CRIT_ERR("mpd_title: invalid length argument");
- }
+ END OBJ_THREAD(mpd_artist, INFO_MPD)
+ if (arg) {
+ sscanf(arg, "%d", &obj->data.i);
+ if (obj->data.i > 0) {
+ obj->data.i++;
+ } else {
+ ERR("mpd_artist: invalid length argument");
+ obj->data.i = 0;
+ }
} else {
- info.mpd.max_title_len = 0;
- }
- END OBJ(mpd_random, INFO_MPD)
- END OBJ(mpd_repeat, INFO_MPD)
- END OBJ(mpd_elapsed, INFO_MPD)
- END OBJ(mpd_length, INFO_MPD)
- END OBJ(mpd_track, INFO_MPD)
- END OBJ(mpd_name, INFO_MPD)
- END OBJ(mpd_file, INFO_MPD)
- END OBJ(mpd_percent, INFO_MPD)
- END OBJ(mpd_album, INFO_MPD)
- END OBJ(mpd_vol, INFO_MPD)
- END OBJ(mpd_bitrate, INFO_MPD)
- END OBJ(mpd_status, INFO_MPD)
- END OBJ(mpd_bar, INFO_MPD)
+ obj->data.i = 0;
+ }
+ END OBJ_THREAD(mpd_title, INFO_MPD)
+ if (arg) {
+ sscanf(arg, "%d", &obj->data.i);
+ if (obj->data.i > 0) {
+ obj->data.i++;
+ } else {
+ ERR("mpd_title: invalid length argument");
+ obj->data.i = 0;
+ }
+ } else {
+ obj->data.i = 0;
+ }
+ END OBJ_THREAD(mpd_random, INFO_MPD)
+ END OBJ_THREAD(mpd_repeat, INFO_MPD)
+ END OBJ_THREAD(mpd_elapsed, INFO_MPD)
+ END OBJ_THREAD(mpd_length, INFO_MPD)
+ END OBJ_THREAD(mpd_track, INFO_MPD)
+ if (arg) {
+ sscanf(arg, "%d", &obj->data.i);
+ if (obj->data.i > 0) {
+ obj->data.i++;
+ } else {
+ ERR("mpd_track: invalid length argument");
+ obj->data.i = 0;
+ }
+ } else {
+ obj->data.i = 0;
+ }
+ END OBJ_THREAD(mpd_name, INFO_MPD)
+ if (arg) {
+ sscanf(arg, "%d", &obj->data.i);
+ if (obj->data.i > 0) {
+ obj->data.i++;
+ } else {
+ ERR("mpd_name: invalid length argument");
+ obj->data.i = 0;
+ }
+ } else {
+ obj->data.i = 0;
+ }
+ END OBJ_THREAD(mpd_file, INFO_MPD)
+ if (arg) {
+ sscanf(arg, "%d", &obj->data.i);
+ if (obj->data.i > 0) {
+ obj->data.i++;
+ } else {
+ ERR("mpd_file: invalid length argument");
+ obj->data.i = 0;
+ }
+ } else {
+ obj->data.i = 0;
+ }
+ END OBJ_THREAD(mpd_percent, INFO_MPD)
+ END OBJ_THREAD(mpd_album, INFO_MPD)
+ if (arg) {
+ sscanf(arg, "%d", &obj->data.i);
+ if (obj->data.i > 0) {
+ obj->data.i++;
+ } else {
+ ERR("mpd_album: invalid length argument");
+ obj->data.i = 0;
+ }
+ } else {
+ obj->data.i = 0;
+ }
+ END OBJ_THREAD(mpd_vol, INFO_MPD)
+ END OBJ_THREAD(mpd_bitrate, INFO_MPD)
+ END OBJ_THREAD(mpd_status, INFO_MPD)
+ END OBJ_THREAD(mpd_bar, INFO_MPD)
scan_bar(arg, &obj->data.pair.a, &obj->data.pair.b);
- END OBJ(mpd_smart, INFO_MPD)
-#endif
+ END OBJ_THREAD(mpd_smart, INFO_MPD)
+ if (arg) {
+ sscanf(arg, "%d", &obj->data.i);
+ if (obj->data.i > 0) {
+ obj->data.i++;
+ } else {
+ ERR("mpd_smart: invalid length argument");
+ obj->data.i = 0;
+ }
+ } else {
+ obj->data.i = 0;
+ }
+ END OBJ_THREAD(if_mpd_playing, INFO_MPD)
+ obj_be_ifblock_if(obj);
+#endif /* MPD */
+#ifdef MOC
+ END OBJ_THREAD(moc_state, INFO_MOC)
+ END OBJ_THREAD(moc_file, INFO_MOC)
+ END OBJ_THREAD(moc_title, INFO_MOC)
+ END OBJ_THREAD(moc_artist, INFO_MOC)
+ END OBJ_THREAD(moc_song, INFO_MOC)
+ END OBJ_THREAD(moc_album, INFO_MOC)
+ END OBJ_THREAD(moc_totaltime, INFO_MOC)
+ END OBJ_THREAD(moc_timeleft, INFO_MOC)
+ END OBJ_THREAD(moc_curtime, INFO_MOC)
+ END OBJ_THREAD(moc_bitrate, INFO_MOC)
+ END OBJ_THREAD(moc_rate, INFO_MOC)
+#endif /* MOC */
#ifdef XMMS2
END OBJ(xmms2_artist, INFO_XMMS2)
END OBJ(xmms2_album, INFO_XMMS2)
END OBJ(xmms2_smart, INFO_XMMS2)
END OBJ(xmms2_playlist, INFO_XMMS2)
END OBJ(xmms2_timesplayed, INFO_XMMS2)
+ END OBJ(if_xmms2_connected, INFO_XMMS2)
+ obj_be_ifblock_if(obj);
#endif
#ifdef AUDACIOUS
END OBJ(audacious_status, INFO_AUDACIOUS)
END OBJ(audacious_filename, INFO_AUDACIOUS)
END OBJ(audacious_playlist_length, INFO_AUDACIOUS)
END OBJ(audacious_playlist_position, INFO_AUDACIOUS)
+ END OBJ(audacious_main_volume, INFO_AUDACIOUS)
END OBJ(audacious_bar, INFO_AUDACIOUS)
scan_bar(arg, &obj->a, &obj->b);
#endif
END OBJ(bmpx_bitrate, INFO_BMPX)
memset(&(info.bmpx), 0, sizeof(struct bmpx_s));
#endif
+#ifdef EVE
+ END OBJ(eve, 0)
+ if(arg) {
+ int argc;
+ char *userid = (char *) malloc(20 * sizeof(char));
+ char *apikey = (char *) malloc(64 * sizeof(char));
+ char *charid = (char *) malloc(20 * sizeof(char));
+
+ argc = sscanf(arg, "%20s %64s %20s", userid, apikey, charid);
+ obj->data.eve.charid = charid;
+ obj->data.eve.userid = userid;
+ obj->data.eve.apikey = apikey;
+
+ init_eve();
+ } else {
+ CRIT_ERR("eve needs arguments: <userid> <apikey> <characterid>");
+ }
+#endif
#ifdef RSS
END OBJ(rss, 0)
if (arg) {
char *action = (char *) malloc(64 * sizeof(char));
argc = sscanf(arg, "%127s %d %63s %d", uri, &delay, action,
- &act_par);
+ &act_par);
obj->data.rss.uri = uri;
obj->data.rss.delay = delay;
obj->data.rss.action = action;
init_rss_info();
} else {
CRIT_ERR("rss needs arguments: <uri> <delay in minutes> <action> "
- "[act_par]");
+ "[act_par]");
}
#endif
#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.temp)) {
+ if (scan_hddtemp(arg, &obj->data.hddtemp.dev,
+ &obj->data.hddtemp.addr, &obj->data.hddtemp.port)) {
ERR("hddtemp needs arguments");
obj->type = OBJ_text;
obj->data.s = strndup("${hddtemp}", text_buffer_size);
obj->data.hddtemp.update_time = 0;
- return NULL;
- }
+ } else
+ obj->data.hddtemp.temp = NULL;
#endif
#ifdef TCP_PORT_MONITOR
END OBJ(tcp_portmon, INFO_TCP_PORT_MONITOR)
- int argc, port_begin, port_end, item, connection_index;
- char itembuf[32];
+ tcp_portmon_init(arg, &obj->data.tcp_port_monitor);
+#endif
+ END OBJ(entropy_avail, INFO_ENTROPY)
+ END OBJ(entropy_poolsize, INFO_ENTROPY)
+ END OBJ(entropy_bar, INFO_ENTROPY)
+ scan_bar(arg, &obj->a, &obj->b);
+ END OBJ(scroll, 0)
+ int n1, n2;
- memset(itembuf, 0, sizeof(itembuf));
- connection_index = 0;
- /* massive argument checking */
- if (!arg) {
- CRIT_ERR("tcp_portmon: needs arguments");
- }
- argc = sscanf(arg, "%d %d %31s %d", &port_begin, &port_end, itembuf,
- &connection_index);
- if ((argc != 3) && (argc != 4)) {
- CRIT_ERR("tcp_portmon: requires 3 or 4 arguments");
- }
- if ((port_begin < 1) || (port_begin > 65535) || (port_end < 1)
- || (port_end > 65535)) {
- CRIT_ERR("tcp_portmon: port values must be from 1 to 65535");
- }
- if (port_begin > port_end) {
- CRIT_ERR("tcp_portmon: starting port must be <= ending port");
- }
- if (strncmp(itembuf, "count", 31) == 0) {
- item = COUNT;
- } else if (strncmp(itembuf, "rip", 31) == 0) {
- item = REMOTEIP;
- } else if (strncmp(itembuf, "rhost", 31) == 0) {
- item = REMOTEHOST;
- } else if (strncmp(itembuf, "rport", 31) == 0) {
- item = REMOTEPORT;
- } else if (strncmp(itembuf, "rservice", 31) == 0) {
- item = REMOTESERVICE;
- } else if (strncmp(itembuf, "lip", 31) == 0) {
- item = LOCALIP;
- } else if (strncmp(itembuf, "lhost", 31) == 0) {
- item = LOCALHOST;
- } else if (strncmp(itembuf, "lport", 31) == 0) {
- item = LOCALPORT;
- } else if (strncmp(itembuf, "lservice", 31) == 0) {
- item = LOCALSERVICE;
+ obj->data.scroll.step = 1;
+ if (arg && sscanf(arg, "%u %n", &obj->data.scroll.show, &n1) > 0) {
+ if (sscanf(arg + n1, "%u %n", &obj->data.scroll.step, &n2) > 0)
+ n1 += n2;
+ obj->data.scroll.text = strndup(arg + n1, text_buffer_size);
+ obj->data.scroll.start = 0;
} else {
- CRIT_ERR("tcp_portmon: invalid item specified");
- }
- if ((argc == 3) && (item != COUNT)) {
- CRIT_ERR("tcp_portmon: 3 argument form valid only for \"count\" "
- "item");
- }
- if ((argc == 4) && (connection_index < 0)) {
- CRIT_ERR("tcp_portmon: connection index must be non-negative");
+ CRIT_ERR("scroll needs arguments: <length> [<step>] <text>");
}
- /* ok, args looks good. save the text object data */
- obj->data.tcp_port_monitor.port_range_begin = (in_port_t) port_begin;
- obj->data.tcp_port_monitor.port_range_end = (in_port_t) port_end;
- obj->data.tcp_port_monitor.item = item;
- obj->data.tcp_port_monitor.connection_index = connection_index;
-
- /* if the port monitor collection hasn't been created,
- * we must create it */
- if (!info.p_tcp_port_monitor_collection) {
- info.p_tcp_port_monitor_collection =
- create_tcp_port_monitor_collection();
- if (!info.p_tcp_port_monitor_collection) {
- CRIT_ERR("tcp_portmon: unable to create port monitor "
- "collection");
- }
- }
-
- /* if a port monitor for this port does not exist,
- * create one and add it to the collection */
- if (find_tcp_port_monitor(info.p_tcp_port_monitor_collection,
- port_begin, port_end) == NULL) {
- tcp_port_monitor_t *p_monitor = create_tcp_port_monitor(port_begin,
- port_end, &tcp_port_monitor_args);
-
- if (!p_monitor) {
- CRIT_ERR("tcp_portmon: unable to create port monitor");
- }
- /* add the newly created monitor to the collection */
- if (insert_tcp_port_monitor_into_collection(
- info.p_tcp_port_monitor_collection, p_monitor) != 0) {
- CRIT_ERR("tcp_portmon: unable to add port monitor to "
- "collection");
- }
+#ifdef NVIDIA
+ END OBJ(nvidia, 0)
+ if (!arg) {
+ CRIT_ERR("nvidia needs an argument\n");
+ } else if (set_nvidia_type(&obj->data.nvidia, arg)) {
+ CRIT_ERR("nvidia: invalid argument"
+ " specified: '%s'\n", arg);
}
-#endif
- END OBJ(entropy_avail, INFO_ENTROPY)
- END OBJ(entropy_poolsize, INFO_ENTROPY)
- END OBJ(entropy_bar, INFO_ENTROPY)
- scan_bar(arg, &obj->a, &obj->b);
+#endif /* NVIDIA */
END {
char buf[256];
return obj;
}
-static struct text_object_list *extract_variable_text_internal(const char *const_p)
+/* backslash_escape - do the actual substitution task for template objects
+ *
+ * The field templates is used for substituting the \N occurences. Set it to
+ * NULL to leave them as they are.
+ */
+static char *backslash_escape(const char *src, char **templates, unsigned int template_count)
+{
+ char *src_dup;
+ const char *p;
+ unsigned int dup_idx = 0, dup_len;
+
+ dup_len = strlen(src);
+ src_dup = malloc(dup_len * sizeof(char));
+
+ p = src;
+ while (*p) {
+ switch (*p) {
+ case '\\':
+ if (!*(p + 1))
+ break;
+ if (*(p + 1) == '\\') {
+ src_dup[dup_idx++] = '\\';
+ p++;
+ } else if (*(p + 1) == ' ') {
+ src_dup[dup_idx++] = ' ';
+ p++;
+ } else if (*(p + 1) == 'n') {
+ src_dup[dup_idx++] = '\n';
+ p++;
+ } else if (templates) {
+ unsigned int tmpl_num;
+ int digits;
+ if ((sscanf(p + 1, "%u%n", &tmpl_num, &digits) <= 0) ||
+ (tmpl_num > template_count))
+ break;
+ dup_len += strlen(templates[tmpl_num - 1]);
+ src_dup = realloc(src_dup, dup_len * sizeof(char));
+ sprintf(src_dup + dup_idx, "%s", templates[tmpl_num - 1]);
+ dup_idx += strlen(templates[tmpl_num - 1]);
+ p += digits;
+ }
+ break;
+ default:
+ src_dup[dup_idx++] = *p;
+ break;
+ }
+ p++;
+ }
+ src_dup[dup_idx] = '\0';
+ src_dup = realloc(src_dup, (strlen(src_dup) + 1) * sizeof(char));
+ return src_dup;
+}
+
+/* handle_template_object - core logic of the template object
+ *
+ * use config variables like this:
+ * template1 = "$\1\2"
+ * template2 = "\1: ${fs_bar 4,100 \2} ${fs_used \2} / ${fs_size \2}"
+ *
+ * and use them like this:
+ * ${template1 node name}
+ * ${template2 root /}
+ * ${template2 cdrom /mnt/cdrom}
+ */
+static char *handle_template(const char *tmpl, const char *args)
+{
+ char *args_dup, *p, *p_old;
+ char **argsp = NULL;
+ unsigned int argcnt = 0, template_idx, i;
+ char *eval_text;
+
+ if ((sscanf(tmpl, "template%u", &template_idx) != 1) ||
+ (template_idx > 9))
+ return NULL;
+
+ args_dup = strdup(args);
+ p = args_dup;
+ while (*p) {
+ while (*p && (*p == ' ' && *(p - 1) != '\\'))
+ p++;
+ if (*(p - 1) == '\\')
+ p--;
+ p_old = p;
+ while (*p && (*p != ' ' || *(p - 1) == '\\'))
+ p++;
+ if (*p) {
+ (*p) = '\0';
+ p++;
+ }
+ argsp = realloc(argsp, ++argcnt * sizeof(char *));
+ argsp[argcnt - 1] = p_old;
+ }
+ for (i = 0; i < argcnt; i++) {
+ char *tmp;
+ tmp = backslash_escape(argsp[i], NULL, 0);
+ DBGP2("%s: substituted arg '%s' to '%s'", tmpl, argsp[i], tmp);
+ argsp[i] = tmp;
+ }
+
+ eval_text = backslash_escape(template[template_idx], argsp, argcnt);
+ DBGP("substituted %s, output is '%s'", tmpl, eval_text);
+ free(args_dup);
+ for (i = 0; i < argcnt; i++)
+ free(argsp[i]);
+ free(argsp);
+ return eval_text;
+}
+
+static char *find_and_replace_templates(const char *inbuf)
+{
+ char *outbuf, *indup, *p, *o, *templ, *args, *tmpl_out;
+ int stack, outlen;
+
+ outlen = strlen(inbuf) + 1;
+ o = outbuf = calloc(outlen, sizeof(char));
+ memset(outbuf, 0, outlen * sizeof(char));
+
+ p = indup = strdup(inbuf);
+ while (*p) {
+ while (*p && *p != '$')
+ *(o++) = *(p++);
+
+ if (!(*p))
+ break;
+
+ if (strncmp(p, "$template", 9) && strncmp(p, "${template", 10)) {
+ *(o++) = *(p++);
+ continue;
+ }
+
+ if (*(p + 1) == '{') {
+ templ = p + 2;
+ while (*p != ' ')
+ p++;
+ *(p++) = '\0';
+ args = p;
+ stack = 1;
+ while (stack > 0) {
+ p++;
+ if (*p == '{')
+ stack++;
+ else if (*p == '}')
+ stack--;
+ }
+ *(p++) = '\0';
+ } else {
+ templ = p + 1;
+ while (*p != ' ')
+ p++;
+ *(p++) = '\0';
+ args = NULL;
+ }
+ tmpl_out = handle_template(templ, args);
+ if (tmpl_out) {
+ outlen += strlen(tmpl_out);
+ outbuf = realloc(outbuf, outlen * sizeof(char));
+ strcat (outbuf, tmpl_out);
+ free(tmpl_out);
+ o = outbuf + strlen(outbuf);
+ } else {
+ ERR("failed to handle template '%s' with args '%s'", templ, args);
+ }
+ }
+ *o = '\0';
+ outbuf = realloc(outbuf, (strlen(outbuf) + 1) * sizeof(char));
+ free(indup);
+ return outbuf;
+}
+
+static int text_contains_templates(const char *text)
+{
+ if (strcasestr(text, "${template") != NULL)
+ return 1;
+ if (strcasestr(text, "$template") != NULL)
+ return 1;
+ return 0;
+}
+
+static int extract_variable_text_internal(struct text_object *retval, const char *const_p, char allow_threaded)
{
- struct text_object_list *retval;
struct text_object *obj;
char *p, *s, *orig_p;
long line;
- p = strndup(const_p, max_user_text);
+ p = strndup(const_p, max_user_text - 1);
+ while (text_contains_templates(p)) {
+ char *tmp;
+ tmp = find_and_replace_templates(p);
+ free(p);
+ p = tmp;
+ }
s = orig_p = p;
- retval = malloc(sizeof(struct text_object_list));
- memset(retval, 0, sizeof(struct text_object_list));
- retval->text_object_count = 0;
+ if (strcmp(p, const_p)) {
+ DBGP("replaced all templates in text: input is\n'%s'\noutput is\n'%s'", const_p, p);
+ } else {
+ DBGP("no templates to replace");
+ }
+
+ memset(retval, 0, sizeof(struct text_object));
- line = text_lines;
+ line = global_text_lines;
while (*p) {
if (*p == '\n') {
*p = '\0';
obj = create_plain_text(s);
if (obj != NULL) {
- // allocate memory for the object
- retval->text_objects = realloc(retval->text_objects,
- sizeof(struct text_object) *
- (retval->text_object_count + 1));
- // assign the new object to the end of the list.
- memcpy(&retval->text_objects[retval->text_object_count++], obj,
- sizeof(struct text_object));
- free(obj);
+ append_object(retval, obj);
}
*p = '$';
p++;
tmp_p++;
}
- // create new object
- obj = construct_text_object(buf, arg,
- retval->text_object_count, retval->text_objects, line);
+ obj = construct_text_object(buf, arg, line, allow_threaded);
if (obj != NULL) {
- // allocate memory for the object
- retval->text_objects = realloc(retval->text_objects,
- sizeof(struct text_object) *
- (retval->text_object_count + 1));
- // assign the new object to the end of the list.
- memcpy(
- &retval->text_objects[retval->text_object_count++],
- obj, sizeof(struct text_object));
- free(obj);
+ append_object(retval, obj);
}
}
continue;
} else {
obj = create_plain_text("$");
if (obj != NULL) {
- // allocate memory for the object
- retval->text_objects = realloc(retval->text_objects,
- sizeof(struct text_object) *
- (retval->text_object_count + 1));
- // assign the new object to the end of the list.
- memcpy(&retval->text_objects[retval->text_object_count++],
- obj, sizeof(struct text_object));
- free(obj);
+ append_object(retval, obj);
}
}
}
}
obj = create_plain_text(s);
if (obj != NULL) {
- // allocate memory for the object
- retval->text_objects = realloc(retval->text_objects,
- sizeof(struct text_object) * (retval->text_object_count + 1));
- // assign the new object to the end of the list.
- memcpy(&retval->text_objects[retval->text_object_count++], obj,
- sizeof(struct text_object));
- free(obj);
+ append_object(retval, obj);
}
- if (blockdepth) {
+ if (!ifblock_stack_empty()) {
ERR("one or more $endif's are missing");
}
free(orig_p);
- return retval;
+ return 0;
}
static void extract_variable_text(const char *p)
{
- struct text_object_list *list;
-
- free_text_objects(global_text_object_count, global_text_objects);
+ free_text_objects(&global_root_object, 1);
if (tmpstring1) {
free(tmpstring1);
tmpstring1 = 0;
free(text_buffer);
text_buffer = 0;
}
- global_text_object_count = 0;
- global_text_objects = NULL;
-
- list = extract_variable_text_internal(p);
- global_text_objects = list->text_objects;
- global_text_object_count = list->text_object_count;
- free(list);
+ extract_variable_text_internal(&global_root_object, p, 1);
}
-struct text_object_list *parse_conky_vars(char *txt, char *p, struct information *cur)
+int parse_conky_vars(struct text_object *root, char *txt, char *p, struct information *cur)
{
- struct text_object_list *object_list =
- extract_variable_text_internal(txt);
-
- generate_text_internal(p, max_user_text, object_list->text_objects,
- object_list->text_object_count, cur);
- return object_list;
+ extract_variable_text_internal(root, txt, 0);
+ generate_text_internal(p, max_user_text, *root, cur);
+ return 0;
}
/* Allows reading from a FIFO (i.e., /dev/xconsole).
p = obj->data.tail.buffer + first_line;
pos = n - first_line;
memmove(obj->data.tail.buffer,
- obj->data.tail.buffer + first_line, strlen(p));
+ obj->data.tail.buffer + first_line, strlen(p));
obj->data.tail.buffer[pos] = 0;
break;
}
snprintf(dst, dst_size, "%s", obj->data.tail.buffer);
}
+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];
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 inline double get_barnum(char *buf)
+{
+ char *c = buf;
+ double barnum;
+
+ while (*c) {
+ if (*c == '\001') {
+ *c = ' ';
+ }
+ c++;
+ }
+
+ if (sscanf(buf, "%lf", &barnum) == 0) {
+ ERR("reading execbar value failed (perhaps it's not the "
+ "correct format?)");
+ return -1;
+ }
+ if (barnum > 100.0 || barnum < 0.0) {
+ ERR("your execbar value is not between 0 and 100, "
+ "therefore it will be ignored");
+ return -1;
+ }
+ return barnum;
+}
+
static void generate_text_internal(char *p, int p_max_size,
- struct text_object *objs, unsigned int object_count,
- struct information *cur)
+ struct text_object root, struct information *cur)
{
- unsigned int i;
+ struct text_object *obj;
#ifdef HAVE_ICONV
char buff_in[p_max_size];
iconv_converting = 0;
#endif
- for (i = 0; i < object_count; i++) {
- struct text_object *obj = &objs[i];
+ p[0] = 0;
+ for (obj = root.next; obj && p_max_size > 0; obj = obj->next) {
- if (p_max_size < 1) {
- break;
- };
+/* IFBLOCK jumping algorithm
+ *
+ * This is easier as it looks like:
+ * - each IF checks it's condition
+ * - on FALSE: call DO_JUMP
+ * - on TRUE: don't care
+ * - each ELSE calls DO_JUMP unconditionally
+ * - each ENDIF is silently being ignored
+ *
+ * Why this works:
+ * DO_JUMP overwrites the "obj" variable of the loop and sets it to the target
+ * (i.e. the corresponding ELSE or ENDIF). After that, processing for the given
+ * object can continue, free()ing stuff e.g., then the for-loop does the rest: as
+ * regularly, "obj" is being updated to point to obj->next, so object parsing
+ * continues right after the corresponding ELSE or ENDIF. This means that if we
+ * find an ELSE, it's corresponding IF must not have jumped, so we need to jump
+ * always. If we encounter an ENDIF, it's corresponding IF or ELSE has not
+ * jumped, and there is nothing to do.
+ */
+#define DO_JUMP { \
+ DBGP2("jumping"); \
+ obj = obj->data.ifblock.next; \
+}
#define OBJ(a) break; case OBJ_##a:
ERR("not implemented obj type %d", obj->type);
#ifndef __OpenBSD__
OBJ(acpitemp) {
- /* does anyone have decimals in acpi temperature? */
- spaced_print(p, p_max_size, "%d", 5, "acpitemp",
- round_to_int(get_acpi_temperature(obj->data.i)));
- }
- OBJ(acpitempf) {
- /* does anyone have decimals in acpi temperature? */
- spaced_print(p, p_max_size, "%d", 5, "acpitemp",
- round_to_int((get_acpi_temperature(obj->data.i) + 40) *
- 9.0 / 5 - 40));
+ temp_print(p, p_max_size, get_acpi_temperature(obj->data.i), TEMP_CELSIUS);
}
#endif /* !__OpenBSD__ */
OBJ(freq) {
if (obj->a) {
obj->a = get_freq(p, p_max_size, "%.0f", 1,
- obj->data.cpu_index);
+ obj->data.cpu_index);
}
}
OBJ(freq_g) {
if (obj->a) {
#ifndef __OpenBSD__
obj->a = get_freq(p, p_max_size, "%'.2f", 1000,
- obj->data.cpu_index);
+ obj->data.cpu_index);
#else
/* OpenBSD has no such flag (SUSv2) */
obj->a = get_freq(p, p_max_size, "%.2f", 1000,
- obj->data.cpu_index);
+ obj->data.cpu_index);
#endif
}
}
OBJ(voltage_mv) {
if (obj->a) {
obj->a = get_voltage(p, p_max_size, "%.0f", 1,
- obj->data.cpu_index);
+ obj->data.cpu_index);
}
}
OBJ(voltage_v) {
if (obj->a) {
obj->a = get_voltage(p, p_max_size, "%'.3f", 1000,
- obj->data.cpu_index);
+ obj->data.cpu_index);
}
}
}
OBJ(wireless_link_qual) {
spaced_print(p, p_max_size, "%d", 4, "wireless_link_qual",
- obj->data.net->link_qual);
+ obj->data.net->link_qual);
}
OBJ(wireless_link_qual_max) {
spaced_print(p, p_max_size, "%d", 4,
- "wireless_link_qual_max", obj->data.net->link_qual_max);
+ "wireless_link_qual_max", obj->data.net->link_qual_max);
}
OBJ(wireless_link_qual_perc) {
if (obj->data.net->link_qual_max > 0) {
spaced_print(p, p_max_size, "%.0f", 5,
- "wireless_link_qual_perc",
- (double) obj->data.net->link_qual /
- obj->data.net->link_qual_max * 100);
+ "wireless_link_qual_perc",
+ (double) obj->data.net->link_qual /
+ obj->data.net->link_qual_max * 100);
} else {
spaced_print(p, p_max_size, "unk", 5,
- "wireless_link_qual_perc");
+ "wireless_link_qual_perc");
}
}
OBJ(wireless_link_bar) {
new_bar(p, obj->a, obj->b, ((double) obj->data.net->link_qual /
- obj->data.net->link_qual_max) * 255.0);
+ obj->data.net->link_qual_max) * 255.0);
}
#endif /* HAVE_IWLIB */
#endif /* __linux__ */
- OBJ(freq_dyn) {
- get_freq_dynamic(p, p_max_size, "%.0f", 1);
- spaced_print(p, p_max_size, "%s", 6, "freq_dyn", p);
- }
- OBJ(freq_dyn_g) {
-#ifndef __OpenBSD__
- get_freq_dynamic(p, p_max_size, "%'.2f", 1000);
-#else
- get_freq_dynamic(p, p_max_size, "%.2f", 1000);
-#endif
- spaced_print(p, p_max_size, "%s", 6, "freq_dyn", p);
- }
-
#ifndef __OpenBSD__
OBJ(adt746xcpu) {
get_adt746x_cpu(p, p_max_size);
OBJ(cpu) {
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);
+ obj->data.cpu_index, info.cpu_count);
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.0));
}
OBJ(cpubar) {
new_bar(p, obj->a, obj->b,
- round_to_int(cur->cpu_usage[obj->data.cpu_index] * 255.0));
+ round_to_int(cur->cpu_usage[obj->data.cpu_index] * 255.0));
}
OBJ(cpugraph) {
new_graph(p, obj->a, obj->b, obj->c, obj->d, (unsigned int)
- round_to_int(cur->cpu_usage[obj->data.cpu_index] * 100),
- 100, 1);
+ round_to_int(cur->cpu_usage[obj->data.cpu_index] * 100),
+ 100, 1, obj->showaslog);
}
OBJ(loadgraph) {
new_graph(p, obj->a, obj->b, obj->c, obj->d, cur->loadavg[0],
- obj->e, 1);
+ obj->e, 1, obj->showaslog);
}
OBJ(color) {
new_fg(p, obj->data.l);
#if defined(__linux__)
OBJ(disk_protect) {
snprintf(p, p_max_size, "%s",
- get_disk_protect_queue(obj->data.s));
+ get_disk_protect_queue(obj->data.s));
}
OBJ(i8k_version) {
snprintf(p, p_max_size, "%s", i8k.version);
snprintf(p, p_max_size, "%s", i8k.serial);
}
OBJ(i8k_cpu_temp) {
- snprintf(p, p_max_size, "%s", i8k.cpu_temp);
- }
- OBJ(i8k_cpu_tempf) {
int cpu_temp;
sscanf(i8k.cpu_temp, "%d", &cpu_temp);
- snprintf(p, p_max_size, "%.1f", cpu_temp * (9.0 / 5.0) + 32.0);
+ temp_print(p, p_max_size, (double)cpu_temp, TEMP_CELSIUS);
}
OBJ(i8k_left_fan_status) {
int left_fan_status;
}
OBJ(ibm_temps) {
get_ibm_acpi_temps();
- snprintf(p, p_max_size, "%d", ibm_acpi.temps[obj->data.sensor]);
+ temp_print(p, p_max_size,
+ ibm_acpi.temps[obj->data.sensor], TEMP_CELSIUS);
}
OBJ(ibm_volume) {
get_ibm_acpi_volume(p, p_max_size);
OBJ(if_up) {
if ((obj->data.ifblock.s)
&& (!interface_up(obj->data.ifblock.s))) {
- i = obj->data.ifblock.pos;
- if_jumped = 1;
- } else {
- if_jumped = 0;
+ DO_JUMP;
}
}
OBJ(if_gw) {
if (!cur->gw_info.count) {
- i = obj->data.ifblock.pos;
- if_jumped = 1;
- } else {
- if_jumped = 0;
+ DO_JUMP;
}
}
OBJ(gw_iface) {
OBJ(obsd_sensors_temp) {
obsd_sensors.device = sensor_device;
update_obsd_sensors();
- snprintf(p, p_max_size, "%.1f",
- obsd_sensors.temp[obsd_sensors.device][obj->data.sensor]);
+ temp_print(p, p_max_size,
+ obsd_sensors.temp[obsd_sensors.device][obj->data.sensor],
+ TEMP_CELSIUS);
}
OBJ(obsd_sensors_fan) {
obsd_sensors.device = sensor_device;
update_obsd_sensors();
snprintf(p, p_max_size, "%d",
- obsd_sensors.fan[obsd_sensors.device][obj->data.sensor]);
+ obsd_sensors.fan[obsd_sensors.device][obj->data.sensor]);
}
OBJ(obsd_sensors_volt) {
obsd_sensors.device = sensor_device;
update_obsd_sensors();
snprintf(p, p_max_size, "%.2f",
- obsd_sensors.volt[obsd_sensors.device][obj->data.sensor]);
+ obsd_sensors.volt[obsd_sensors.device][obj->data.sensor]);
}
OBJ(obsd_vendor) {
get_obsd_vendor(p, p_max_size);
OBJ(diskio) {
if (obj->data.diskio) {
human_readable(
- (obj->data.diskio->current / update_interval) * 1024LL,
- p, p_max_size, "diskio");
+ (obj->data.diskio->current / update_interval) * 1024LL,
+ p, p_max_size, "diskio");
} else {
- human_readable(diskio_value * 1024LL, p, p_max_size,
- "diskio");
+ human_readable(info.diskio_value * 1024LL, p, p_max_size,
+ "diskio");
}
}
OBJ(diskio_write) {
if (obj->data.diskio) {
human_readable((obj->data.diskio->current_write / update_interval) * 1024LL, p, p_max_size,
- "diskio_write");
+ "diskio_write");
} else {
- human_readable(diskio_write_value * 1024LL, p, p_max_size,
- "diskio_write");
+ human_readable(info.diskio_write_value * 1024LL, p, p_max_size,
+ "diskio_write");
}
}
OBJ(diskio_read) {
if (obj->data.diskio) {
human_readable((obj->data.diskio->current_read / update_interval) * 1024LL, p, p_max_size,
- "diskio_read");
+ "diskio_read");
} else {
- human_readable(diskio_read_value * 1024LL, p, p_max_size,
- "diskio_read");
+ human_readable(info.diskio_read_value * 1024LL, p, p_max_size,
+ "diskio_read");
}
}
OBJ(diskiograph) {
if (obj->data.diskio) {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
- obj->data.diskio->current, obj->e, 1);
+ obj->data.diskio->current, obj->e, 1, obj->showaslog);
} else {
- new_graph(p, obj->a, obj->b, obj->c, obj->d, diskio_value,
- obj->e, 1);
+ new_graph(p, obj->a, obj->b, obj->c, obj->d, info.diskio_value,
+ obj->e, 1, obj->showaslog);
}
}
OBJ(diskiograph_read) {
if (obj->data.diskio) {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
- obj->data.diskio->current_read, obj->e, 1);
+ obj->data.diskio->current_read, obj->e, 1, obj->showaslog);
} 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->showaslog);
}
}
OBJ(diskiograph_write) {
if (obj->data.diskio) {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
- obj->data.diskio->current_write, obj->e, 1);
+ obj->data.diskio->current_write, obj->e, 1, obj->showaslog);
} 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->showaslog);
}
}
OBJ(downspeed) {
spaced_print(p, p_max_size, "%d", 6, "downspeed",
- round_to_int(obj->data.net->recv_speed / 1024));
+ round_to_int(obj->data.net->recv_speed / 1024));
}
OBJ(downspeedf) {
spaced_print(p, p_max_size, "%.1f", 8, "downspeedf",
- obj->data.net->recv_speed / 1024.0);
+ obj->data.net->recv_speed / 1024.0);
}
OBJ(downspeedgraph) {
- new_graph(p, obj->a, obj->b, obj->c, obj->d,
- obj->data.net->recv_speed / 1024.0, obj->e, 1);
+ new_graph(p, obj->a, obj->b, obj->c, obj->d,
+ obj->data.net->recv_speed / 1024.0, obj->e, 1, obj->showaslog);
}
OBJ(else) {
- if (!if_jumped) {
- i = obj->data.ifblock.pos - 1;
- } else {
- if_jumped = 0;
- }
+ /* Since we see you, you're if has not jumped.
+ * Do Ninja jump here: without leaving traces.
+ * This is to prevent us from stale jumped flags.
+ */
+ obj = obj->data.ifblock.next;
+ continue;
}
OBJ(endif) {
- if_jumped = 0;
+ /* harmless object, just ignore */
}
#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__ */
#endif /* IMLIB2 */
OBJ(exec) {
- FILE *fp = popen(obj->data.s, "r");
- int length = fread(p, 1, p_max_size, fp);
-
- pclose(fp);
-
- p[length] = '\0';
- if (length > 0 && p[length - 1] == '\n') {
- p[length - 1] = '\0';
- }
+ read_exec(obj->data.s, p, text_buffer_size);
+ remove_deleted_chars(p);
}
OBJ(execp) {
- FILE *fp;
- struct information *my_info;
- struct text_object_list *text_objects;
- int length;
-
- fp = popen(obj->data.s, "r");
- fread(p, 1, p_max_size, fp);
- pclose(fp);
+ struct information *tmp_info;
+ struct text_object subroot;
- my_info = malloc(sizeof(struct information));
- memcpy(my_info, cur, sizeof(struct information));
- text_objects = parse_conky_vars(p, p, my_info);
+ read_exec(obj->data.s, p, text_buffer_size);
- length = strlen(p);
-
- p[length] = '\0';
- if (length > 0 && p[length - 1] == '\n') {
- p[length - 1] = '\0';
- }
+ tmp_info = malloc(sizeof(struct information));
+ memcpy(tmp_info, cur, sizeof(struct information));
+ parse_conky_vars(&subroot, p, p, tmp_info);
- free_text_objects(text_objects->text_object_count, text_objects->text_objects);
- free(text_objects);
- free(my_info);
+ free_text_objects(&subroot, 0);
+ 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';
- if (n2 && p[n2 - 1] == '\n') {
- p[n2 - 1] = '\0';
- }
-
- while (*p2) {
- if (*p2 == '\001') {
- *p2 = ' ';
- }
- p2++;
- }
+ read_exec(obj->data.s, p, text_buffer_size);
+ barnum = get_barnum(p);
- if (sscanf(p, "%lf", &barnum) == 0) {
- ERR("reading execbar value failed (perhaps it's not the "
- "correct format?)");
- }
- if (barnum > 100 || barnum < 0) {
- ERR("your execbar value is not between 0 and 100, "
- "therefore it will be ignored");
- } else {
- barnum = barnum / 100.0;
- new_bar(p, 0, 4, (int) (barnum * 255.0));
+ if (barnum >= 0.0) {
+ barnum /= 100;
+ new_bar(p, 0, 4, round_to_int(barnum * 255.0));
}
}
OBJ(execgraph) {
- char *p2 = p;
- FILE *fp = popen(obj->data.s, "r");
- int n2 = fread(p, 1, p_max_size, fp);
+ char showaslog = FALSE;
double barnum;
- pclose(fp);
- p[n2] = '\0';
- if (n2 && p[n2 - 1] == '\n') {
- p[n2 - 1] = '\0';
- }
- while (*p2) {
- if (*p2 == '\001') {
- *p2 = ' ';
- }
- p2++;
+ if(strncasecmp(obj->data.s, LOGGRAPH" ", strlen(LOGGRAPH" ")) == EQUAL) {
+ showaslog = TRUE;
+ read_exec(obj->data.s + strlen(LOGGRAPH" ") * sizeof(char), p, text_buffer_size);
+ } else if(strncasecmp(obj->data.s, NORMGRAPH" ", strlen(NORMGRAPH" ")) == EQUAL) {
+ read_exec(obj->data.s + strlen(NORMGRAPH" ") * sizeof(char), p, text_buffer_size);
+ } else {
+ read_exec(obj->data.s, p, text_buffer_size);
}
+ barnum = get_barnum(p);
- if (sscanf(p, "%lf", &barnum) == 0) {
- ERR("reading execgraph value failed (perhaps it's not the "
- "correct format?)");
- }
- if (barnum > 100 || barnum < 0) {
- 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);
+ if (barnum >= 0.0) {
+ new_graph(p, 0, 25, obj->c, obj->d, round_to_int(barnum),
+ 100, 1, showaslog);
}
}
OBJ(execibar) {
if (current_update_time - obj->data.execi.last_update
- < obj->data.execi.interval) {
- new_bar(p, 0, 4, (int) obj->f);
- } else {
- 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';
- if (n2 && p[n2 - 1] == '\n') {
- p[n2 - 1] = '\0';
- }
+ >= obj->data.execi.interval) {
+ double barnum;
- while (*p2) {
- if (*p2 == '\001') {
- *p2 = ' ';
- }
- p2++;
- }
+ read_exec(obj->data.execi.cmd, p, text_buffer_size);
+ barnum = get_barnum(p);
- if (sscanf(p, "%f", &barnum) == 0) {
- ERR("reading execibar value failed (perhaps it's not "
- "the correct format?)");
- }
- if (barnum > 100 || barnum < 0) {
- ERR("your execibar value is not between 0 and 100, "
- "therefore it will be ignored");
- } else {
+ if (barnum >= 0.0) {
obj->f = 255 * barnum / 100.0;
- new_bar(p, 0, 4, (int) obj->f);
}
obj->data.execi.last_update = current_update_time;
}
+ new_bar(p, 0, 4, round_to_int(obj->f));
}
OBJ(execigraph) {
if (current_update_time - obj->data.execi.last_update
- < obj->data.execi.interval) {
- new_graph(p, 0, 25, obj->c, obj->d, (int) (obj->f), 100, 0);
- } else {
- 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';
- if (n2 && p[n2 - 1] == '\n') {
- p[n2 - 1] = '\0';
- }
+ >= obj->data.execi.interval) {
+ double barnum;
- while (*p2) {
- if (*p2 == '\001') {
- *p2 = ' ';
- }
- p2++;
- }
+ read_exec(obj->data.execi.cmd, p, text_buffer_size);
+ barnum = get_barnum(p);
- if (sscanf(p, "%f", &barnum) == 0) {
- ERR("reading execigraph value failed (perhaps it's not "
- "the correct format?)");
- }
- if (barnum > 100 || barnum < 0) {
- ERR("your execigraph value is not between 0 and 100, "
- "therefore it will be ignored");
- } else {
+ if (barnum >= 0.0) {
obj->f = barnum;
- new_graph(p, 0, 25, obj->c, obj->d, (int) (obj->f),
- 100, 1);
}
obj->data.execi.last_update = current_update_time;
}
+ new_graph(p, 0, 25, obj->c, obj->d, (int) (obj->f), 100, 1, FALSE);
}
OBJ(execi) {
if (current_update_time - obj->data.execi.last_update
- < obj->data.execi.interval
- || obj->data.execi.interval == 0) {
- snprintf(p, p_max_size, "%s", obj->data.execi.buffer);
- } else {
- char *output = obj->data.execi.buffer;
- FILE *fp = popen(obj->data.execi.cmd, "r");
-
- int length = fread(output, 1, text_buffer_size, fp);
-
- pclose(fp);
- output[length] = '\0';
- if (length > 0 && output[length - 1] == '\n') {
- output[length - 1] = '\0';
- }
+ >= obj->data.execi.interval
+ && obj->data.execi.interval != 0) {
+ read_exec(obj->data.execi.cmd, obj->data.execi.buffer,
+ text_buffer_size);
obj->data.execi.last_update = current_update_time;
- snprintf(p, p_max_size, "%s", output);
}
- // parse_conky_vars(output, p, cur);
+ snprintf(p, text_buffer_size, "%s", obj->data.execi.buffer);
}
OBJ(execpi) {
- struct text_object_list *text_objects = 0;
- struct information *my_info =
+ struct text_object subroot;
+ struct information *tmp_info =
malloc(sizeof(struct information));
- memcpy(my_info, cur, 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);
+ parse_conky_vars(&subroot, 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);
+
+ parse_conky_vars(&subroot, 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);
- free(my_info);
+ free_text_objects(&subroot, 0);
+ free(tmp_info);
}
OBJ(texeci) {
if (!obj->data.texeci.p_timed_thread) {
}
}
timed_thread_lock(obj->data.texeci.p_timed_thread);
- snprintf(p, p_max_size, "%s", obj->data.texeci.buffer);
+ snprintf(p, text_buffer_size, "%s", obj->data.texeci.buffer);
timed_thread_unlock(obj->data.texeci.p_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(&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(&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(&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(&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(&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(&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(&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(&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) {
snprintf(p, p_max_size, "%s",
cur->nameserver_info.ns_list[obj->data.i]);
}
+#ifdef EVE
+ OBJ(eve) {
+ char *skill = eve(obj->data.eve.userid, obj->data.eve.apikey, obj->data.eve.charid);
+ snprintf(p, p_max_size, "%s", skill);
+ }
+#endif
#ifdef RSS
OBJ(rss) {
PRSS *data = get_rss_info(obj->data.rss.uri,
if (data == NULL) {
snprintf(p, p_max_size, "prss: Error reading RSS data\n");
} else {
- if (!strcmp(obj->data.rss.action, "feed_title")) {
+ if (strcmp(obj->data.rss.action, "feed_title") == EQUAL) {
str = data->title;
// remove trailing new line if one exists
if (str[strlen(str) - 1] == '\n') {
str[strlen(str) - 1] = 0;
}
snprintf(p, p_max_size, "%s", str);
- } else if (!strcmp(obj->data.rss.action, "item_title")) {
+ } else if (strcmp(obj->data.rss.action, "item_title") == EQUAL) {
if (obj->data.rss.act_par < data->item_count) {
str = data->items[obj->data.rss.act_par].title;
// remove trailing new line if one exists
}
snprintf(p, p_max_size, "%s", str);
}
- } else if (!strcmp(obj->data.rss.action, "item_desc")) {
+ } else if (strcmp(obj->data.rss.action, "item_desc") == EQUAL) {
if (obj->data.rss.act_par < data->item_count) {
str =
data->items[obj->data.rss.act_par].description;
}
snprintf(p, p_max_size, "%s", str);
}
- } else if (!strcmp(obj->data.rss.action, "item_titles")) {
+ } else if (strcmp(obj->data.rss.action, "item_titles") == EQUAL) {
if (data->item_count > 0) {
int itmp;
int show;
#endif
#ifdef HDDTEMP
OBJ(hddtemp) {
+ char *endptr, unit;
+ long val;
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;
- }
+ if (obj->data.hddtemp.temp)
+ free(obj->data.hddtemp.temp);
+ obj->data.hddtemp.temp = get_hddtemp_info(obj->data.hddtemp.dev,
+ obj->data.hddtemp.addr, obj->data.hddtemp.port);
obj->data.hddtemp.update_time = current_update_time;
}
if (!obj->data.hddtemp.temp) {
snprintf(p, p_max_size, "N/A");
- } else if (obj->data.hddtemp.unit == '*') {
- snprintf(p, p_max_size, "%s", obj->data.hddtemp.temp);
} else {
- snprintf(p, p_max_size, "%s%c", obj->data.hddtemp.temp, obj->data.hddtemp.unit);
+ val = strtol(obj->data.hddtemp.temp + 1, &endptr, 10);
+ unit = obj->data.hddtemp.temp[0];
+
+ if (*endptr != '\0')
+ snprintf(p, p_max_size, "N/A");
+ else if (unit == 'C')
+ temp_print(p, p_max_size, (double)val, TEMP_CELSIUS);
+ else if (unit == 'F')
+ temp_print(p, p_max_size, (double)val, TEMP_FAHRENHEIT);
+ else
+ snprintf(p, p_max_size, "N/A");
}
}
#endif
r = get_sysfs_info(&obj->data.sysfs.fd, obj->data.sysfs.arg,
obj->data.sysfs.devtype, obj->data.sysfs.type);
- if (r >= 100.0 || r == 0) {
+ if (!strncmp(obj->data.sysfs.type, "temp", 4)) {
+ temp_print(p, p_max_size, r, TEMP_CELSIUS);
+ } else if (r >= 100.0 || r == 0) {
snprintf(p, p_max_size, "%d", (int) r);
} else {
snprintf(p, p_max_size, "%.1f", r);
r = get_sysfs_info(&obj->data.sysfs.fd, obj->data.sysfs.arg,
obj->data.sysfs.devtype, obj->data.sysfs.type);
- if (r >= 100.0 || r == 0) {
+ if (!strncmp(obj->data.sysfs.type, "temp", 4)) {
+ temp_print(p, p_max_size, r, TEMP_CELSIUS);
+ } else if (r >= 100.0 || r == 0) {
snprintf(p, p_max_size, "%d", (int) r);
} else {
snprintf(p, p_max_size, "%.1f", r);
r = get_sysfs_info(&obj->data.sysfs.fd, obj->data.sysfs.arg,
obj->data.sysfs.devtype, obj->data.sysfs.type);
- if (r >= 100.0 || r == 0) {
+ if (!strncmp(obj->data.sysfs.type, "temp", 4)) {
+ temp_print(p, p_max_size, r, TEMP_CELSIUS);
+ } else if (r >= 100.0 || r == 0) {
snprintf(p, p_max_size, "%d", (int) r);
} else {
snprintf(p, p_max_size, "%.1f", r);
new_alignc(p, obj->data.i);
}
OBJ(if_empty) {
- struct text_object_list *text_objects;
- struct information *my_info =
+ struct text_object subroot;
+ struct information *tmp_info =
malloc(sizeof(struct information));
- memcpy(my_info, cur, sizeof(struct information));
- text_objects = parse_conky_vars(obj->data.ifblock.s, p, my_info);
+ memcpy(tmp_info, cur, sizeof(struct information));
+ parse_conky_vars(&subroot, obj->data.ifblock.s, p, tmp_info);
if (strlen(p) != 0) {
- i = obj->data.ifblock.pos;
- if_jumped = 1;
- } else {
- if_jumped = 0;
+ DO_JUMP;
}
p[0] = '\0';
- free_text_objects(text_objects->text_object_count, text_objects->text_objects);
- free(text_objects);
- free(my_info);
+ free_text_objects(&subroot, 0);
+ free(tmp_info);
}
OBJ(if_existing) {
- struct stat tmp;
-
- if ((obj->data.ifblock.s)
- && (stat(obj->data.ifblock.s, &tmp) == -1)) {
- i = obj->data.ifblock.pos;
- if_jumped = 1;
- } else {
- if (obj->data.ifblock.str) {
- if (!check_contains(obj->data.ifblock.s,
- obj->data.ifblock.str)) {
- i = obj->data.ifblock.pos;
- if_jumped = 1;
- } else {
- if_jumped = 0;
- }
- } else {
- if_jumped = 0;
- }
+ if (obj->data.ifblock.str
+ && !check_contains(obj->data.ifblock.s,
+ obj->data.ifblock.str)) {
+ DO_JUMP;
+ } else if (obj->data.ifblock.s
+ && access(obj->data.ifblock.s, F_OK)) {
+ DO_JUMP;
}
}
OBJ(if_mounted) {
if ((obj->data.ifblock.s)
&& (!check_mount(obj->data.ifblock.s))) {
- i = obj->data.ifblock.pos;
- if_jumped = 1;
- } else {
- if_jumped = 0;
+ DO_JUMP;
}
}
OBJ(if_running) {
if ((obj->data.ifblock.s) && system(obj->data.ifblock.s)) {
- i = obj->data.ifblock.pos;
- if_jumped = 1;
- } else {
- if_jumped = 0;
+ DO_JUMP;
}
}
+#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(mem) {
human_readable(cur->mem * 1024, p, 255, "mem");
}
+ OBJ(memeasyfree) {
+ human_readable(cur->memeasyfree * 1024, p, 255, "memeasyfree");
+ }
+ OBJ(memfree) {
+ human_readable(cur->memfree * 1024, p, 255, "memfree");
+ }
OBJ(memmax) {
human_readable(cur->memmax * 1024, p, 255, "memmax");
}
OBJ(memgraph) {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
cur->memmax ? (cur->mem * 100.0) / (cur->memmax) : 0.0,
- 100, 0);
+ 100, 1, obj->showaslog);
}
/* mixer stuff */
new_bar(p, obj->data.mixerbar.w, obj->data.mixerbar.h,
mixer_get_right(obj->data.mixerbar.l) * 255 / 100);
}
+#ifdef X11
+ OBJ(monitor) {
+ snprintf(p, p_max_size, "%d", cur->x11.monitor.current);
+ }
+ OBJ(monitor_number) {
+ snprintf(p, p_max_size, "%d", cur->x11.monitor.number);
+ }
+#endif
/* mail stuff */
OBJ(mails) {
}
OBJ(upspeedgraph) {
new_graph(p, obj->a, obj->b, obj->c, obj->d,
- obj->data.net->trans_speed / 1024.0, obj->e, 1);
+ obj->data.net->trans_speed / 1024.0, obj->e, 1, obj->showaslog);
}
OBJ(uptime_short) {
format_seconds_short(p, p_max_size, (int) cur->uptime);
#ifdef MPD
OBJ(mpd_title) {
- snprintf(p, cur->mpd.max_title_len > 0
- ? cur->mpd.max_title_len : p_max_size, "%s",
- cur->mpd.title);
+ int len = obj->data.i;
+ if (len == 0 || len > p_max_size)
+ len = p_max_size;
+ snprintf(p, len, "%s", cur->mpd.title);
}
OBJ(mpd_artist) {
- snprintf(p, p_max_size, "%s", cur->mpd.artist);
+ int len = obj->data.i;
+ if (len == 0 || len > p_max_size)
+ len = p_max_size;
+ snprintf(p, len, "%s", cur->mpd.artist);
}
OBJ(mpd_album) {
- snprintf(p, p_max_size, "%s", cur->mpd.album);
+ int len = obj->data.i;
+ if (len == 0 || len > p_max_size)
+ len = p_max_size;
+ snprintf(p, len, "%s", cur->mpd.album);
}
OBJ(mpd_random) {
snprintf(p, p_max_size, "%s", cur->mpd.random);
snprintf(p, p_max_size, "%s", cur->mpd.repeat);
}
OBJ(mpd_track) {
- snprintf(p, p_max_size, "%s", cur->mpd.track);
+ int len = obj->data.i;
+ if (len == 0 || len > p_max_size)
+ len = p_max_size;
+ snprintf(p, len, "%s", cur->mpd.track);
}
OBJ(mpd_name) {
- snprintf(p, p_max_size, "%s", cur->mpd.name);
+ int len = obj->data.i;
+ if (len == 0 || len > p_max_size)
+ len = p_max_size;
+ snprintf(p, len, "%s", cur->mpd.name);
}
OBJ(mpd_file) {
- snprintf(p, p_max_size, "%s", cur->mpd.file);
+ int len = obj->data.i;
+ if (len == 0 || len > p_max_size)
+ len = p_max_size;
+ snprintf(p, len, "%s", cur->mpd.file);
}
OBJ(mpd_vol) {
snprintf(p, p_max_size, "%i", cur->mpd.volume);
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", 4, "mpd_percent",
(int) (cur->mpd.progress * 255.0f));
}
OBJ(mpd_smart) {
+ int len = obj->data.i;
+ if (len == 0 || len > p_max_size)
+ len = p_max_size;
+
memset(p, 0, p_max_size);
if (cur->mpd.artist && *cur->mpd.artist && cur->mpd.title
&& *cur->mpd.title) {
- snprintf(p, p_max_size, "%s - %s", cur->mpd.artist,
+ snprintf(p, len, "%s - %s", cur->mpd.artist,
cur->mpd.title);
} else if (cur->mpd.title && *cur->mpd.title) {
- snprintf(p, p_max_size, "%s", cur->mpd.title);
+ snprintf(p, len, "%s", cur->mpd.title);
} else if (cur->mpd.artist && *cur->mpd.artist) {
- snprintf(p, p_max_size, "%s", cur->mpd.artist);
+ snprintf(p, len, "%s", cur->mpd.artist);
} else if (cur->mpd.file && *cur->mpd.file) {
- snprintf(p, p_max_size, "%s", cur->mpd.file);
+ snprintf(p, len, "%s", cur->mpd.file);
} else {
*p = 0;
}
}
+ OBJ(if_mpd_playing) {
+ if (!cur->mpd.is_playing) {
+ DO_JUMP;
+ }
+ }
#endif
+#ifdef MOC
+ OBJ(moc_state) {
+ snprintf(p, p_max_size, "%s", (cur->moc.state ? cur->moc.state : "??"));
+ }
+ OBJ(moc_file) {
+ snprintf(p, p_max_size, "%s", (cur->moc.file ? cur->moc.file : "no file"));
+ }
+ OBJ(moc_title) {
+ snprintf(p, p_max_size, "%s", (cur->moc.title ? cur->moc.title : "no title"));
+ }
+ OBJ(moc_artist) {
+ snprintf(p, p_max_size, "%s", (cur->moc.artist ? cur->moc.artist : "no artist"));
+ }
+ OBJ(moc_song) {
+ snprintf(p, p_max_size, "%s", (cur->moc.song ? cur->moc.song : "no song"));
+ }
+ OBJ(moc_album) {
+ snprintf(p, p_max_size, "%s", (cur->moc.album ? cur->moc.album : "no album"));
+ }
+ OBJ(moc_totaltime) {
+ snprintf(p, p_max_size, "%s", (cur->moc.totaltime ? cur->moc.totaltime : "0:00"));
+ }
+ OBJ(moc_timeleft) {
+ snprintf(p, p_max_size, "%s", (cur->moc.timeleft ? cur->moc.timeleft : "0:00"));
+ }
+ OBJ(moc_curtime) {
+ snprintf(p, p_max_size, "%s", (cur->moc.curtime ? cur->moc.curtime : "0:00"));
+ }
+ OBJ(moc_bitrate) {
+ snprintf(p, p_max_size, "%s", (cur->moc.bitrate ? cur->moc.bitrate : "0Kbps"));
+ }
+ OBJ(moc_rate) {
+ snprintf(p, p_max_size, "%s", (cur->moc.rate ? cur->moc.rate : "0KHz"));
+ }
+#endif /* MOC */
#ifdef XMMS2
OBJ(xmms2_artist) {
snprintf(p, p_max_size, "%s", cur->xmms2.artist);
cur->xmms2.title);
}
}
+ OBJ(if_xmms2_connected) {
+ if (cur->xmms2_conn_state != 1) {
+ DO_JUMP;
+ }
+ }
#endif
#ifdef AUDACIOUS
OBJ(audacious_status) {
snprintf(p, p_max_size, "%s",
cur->audacious.items[AUDACIOUS_PLAYLIST_POSITION]);
}
+ OBJ(audacious_main_volume) {
+ snprintf(p, p_max_size, "%s",
+ cur->audacious.items[AUDACIOUS_MAIN_VOLUME]);
+ }
OBJ(audacious_bar) {
double progress;
} /* bsize > 0 */
} /* fp == NULL */
} /* if cur_upd_time >= */
- // parse_conky_vars(obj->data.tail.buffer, p, cur);
}
head:
OBJ(head) {
} /* nl > 0 */
} /* if fp == null */
} /* cur_upd_time >= */
- // parse_conky_vars(obj->data.tail.buffer, p, cur);
}
-#ifdef TCP_PORT_MONITOR
- OBJ(tcp_portmon) {
- /* grab a pointer to this port monitor */
- tcp_port_monitor_t *p_monitor =
- find_tcp_port_monitor(info.p_tcp_port_monitor_collection,
- obj->data.tcp_port_monitor.port_range_begin,
- obj->data.tcp_port_monitor.port_range_end);
-
- if (!p_monitor) {
- snprintf(p, p_max_size, "monitor not found");
- break;
+ OBJ(lines) {
+ FILE *fp = fopen(obj->data.s,"r");
+
+ if(fp != NULL) {
+ char buf[BUFSZ];
+ int j, lines;
+
+ lines = 0;
+ while(fgets(buf, BUFSZ, fp) != NULL){
+ for(j = 0; buf[j] != 0; j++) {
+ if(buf[j] == '\n') {
+ lines++;
+ }
+ }
+ }
+ sprintf(p, "%d", lines);
+ fclose(fp);
+ } else {
+ sprintf(p, "File Unreadable");
}
+ }
- /* now grab the text of interest */
- if (peek_tcp_port_monitor(p_monitor,
- obj->data.tcp_port_monitor.item,
- obj->data.tcp_port_monitor.connection_index, p,
- p_max_size) != 0) {
- snprintf(p, p_max_size, "monitor peek error");
- break;
+ OBJ(words) {
+ FILE *fp = fopen(obj->data.s,"r");
+
+ if(fp != NULL) {
+ char buf[BUFSZ];
+ int j, words;
+ char inword = FALSE;
+
+ words = 0;
+ while(fgets(buf, BUFSZ, fp) != NULL){
+ for(j = 0; buf[j] != 0; j++) {
+ if(!isspace(buf[j])) {
+ if(inword == FALSE) {
+ words++;
+ inword = TRUE;
+ }
+ } else {
+ inword = FALSE;
+ }
+ }
+ }
+ sprintf(p, "%d", words);
+ fclose(fp);
+ } else {
+ sprintf(p, "File Unreadable");
}
}
+#ifdef TCP_PORT_MONITOR
+ OBJ(tcp_portmon) {
+ tcp_portmon_action(p, p_max_size,
+ &obj->data.tcp_port_monitor);
+ }
#endif
#ifdef HAVE_ICONV
int idx;
if(obj->data.ifblock.s && sscanf(obj->data.ifblock.s, "%i", &idx) == 1) {
if(!smapi_bat_installed(idx)) {
- i = obj->data.ifblock.pos;
- if_jumped = 1;
- } else
- if_jumped = 0;
+ DO_JUMP;
+ }
} else
ERR("argument to if_smapi_bat_installed must be an integer");
}
} else
ERR("argument to smapi_bat_perc must be an integer");
}
+ OBJ(smapi_bat_temp) {
+ int idx, val;
+ if(obj->data.s && sscanf(obj->data.s, "%i", &idx) == 1) {
+ val = smapi_bat_installed(idx) ?
+ smapi_get_bat_int(idx, "temperature") : 0;
+ /* temperature is in milli degree celsius */
+ temp_print(p, p_max_size, val / 1000, TEMP_CELSIUS);
+ } else
+ ERR("argument to smapi_bat_temp must be an integer");
+ }
+ OBJ(smapi_bat_power) {
+ int idx, val;
+ if(obj->data.s && sscanf(obj->data.s, "%i", &idx) == 1) {
+ val = smapi_bat_installed(idx) ?
+ smapi_get_bat_int(idx, "power_now") : 0;
+ /* power_now is in mW, set to W with one digit precision */
+ snprintf(p, p_max_size, "%.1f", ((double)val / 1000));
+ } else
+ ERR("argument to smapi_bat_power must be an integer");
+ }
OBJ(smapi_bat_bar) {
if(obj->data.i >= 0 && smapi_bat_installed(obj->data.i))
new_bar(p, obj->a, obj->b, (int)
new_bar(p, obj->a, obj->b, 0);
}
#endif /* SMAPI */
+ OBJ(scroll) {
+ unsigned int j;
+ char *tmp;
+ struct text_object subroot;
+ parse_conky_vars(&subroot, obj->data.scroll.text, p, cur);
+
+ if (strlen(p) <= obj->data.scroll.show) {
+ break;
+ }
+#define LINESEPARATOR '|'
+ //place all the lines behind each other with LINESEPARATOR between them
+ for(j = 0; p[j] != 0; j++) {
+ if(p[j]=='\n') {
+ p[j]=LINESEPARATOR;
+ }
+ }
+ //scroll the output obj->data.scroll.start places by copying that many chars from
+ //the front of the string to tmp, scrolling the rest to the front and placing tmp
+ //at the back of the string
+ tmp = calloc(obj->data.scroll.start + 1, sizeof(char));
+ strncpy(tmp, p, obj->data.scroll.start); tmp[obj->data.scroll.start] = 0;
+ for(j = obj->data.scroll.start; p[j] != 0; j++){
+ p[j - obj->data.scroll.start] = p[j];
+ }
+ strcpy(&p[j - obj->data.scroll.start], tmp);
+ free(tmp);
+ //only show the requested number of chars
+ if(obj->data.scroll.show < j) {
+ p[obj->data.scroll.show] = 0;
+ }
+ //next time, scroll a place more or reset scrolling if we are at the end
+ obj->data.scroll.start += obj->data.scroll.step;
+ if(obj->data.scroll.start >= j){
+ obj->data.scroll.start = 0;
+ }
+ }
+#ifdef NVIDIA
+ OBJ(nvidia) {
+ int value = get_nvidia_value(obj->data.nvidia.type, display);
+ if(value == -1)
+ snprintf(p, p_max_size, "N/A");
+ else if (obj->data.nvidia.type == NV_TEMP)
+ temp_print(p, p_max_size, (double)value, TEMP_CELSIUS);
+ else if (obj->data.nvidia.print_as_float &&
+ value > 0 && value < 100)
+ snprintf(p, p_max_size, "%.1f", (float)value);
+ else
+ snprintf(p, p_max_size, "%d", value);
+ }
+#endif /* NVIDIA */
break;
}
+#undef DO_JUMP
+
{
unsigned int a = strlen(p);
}
}
-double current_update_time, last_update_time;
+double current_update_time, next_update_time, last_update_time;
static void generate_text(void)
{
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, global_text_objects,
- global_text_object_count, cur);
+ generate_text_internal(p, max_user_text, global_root_object, cur);
if (stuff_in_upper_case) {
char *tmp_p;
}
}
+ next_update_time += update_interval;
+ if (next_update_time < get_time()) {
+ next_update_time = get_time() + update_interval;
+ } else if (next_update_time > get_time() + update_interval) {
+ next_update_time = get_time() + update_interval;
+ }
last_update_time = current_update_time;
total_updates++;
// free(p);
/* 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
int i, i2, pos, width_of_s;
int max = 0;
int added;
- char space[2];
if (s[0] == '\0') {
return;
}
width_of_s = get_string_width(s);
- if (out_to_console) {
+ if ((output_methods & TO_STDOUT) && draw_mode == FG) {
printf("%s\n", s);
fflush(stdout); /* output immediately, don't buffer */
}
pos = 0;
added = 0;
- 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
}
/* this function returns the next colour between two colours for a gradient */
-inline unsigned long do_gradient(unsigned long first_colour,
+unsigned long do_gradient(unsigned long first_colour,
unsigned long last_colour)
{
int tmp_color = 0;
}
/* this function returns the max diff for a gradient */
-inline unsigned long gradient_max(unsigned long first_colour,
+unsigned long gradient_max(unsigned long first_colour,
unsigned long last_colour)
{
int red1, green1, blue1; // first colour
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;
} else {
set_foreground_color(default_fg_color);
} */
+ if (show_graph_range) {
+ int tmp_x = cur_x;
+ int tmp_y = cur_y;
+ unsigned short int seconds = update_interval * w;
+ char *tmp_day_str;
+ char *tmp_hour_str;
+ char *tmp_min_str;
+ char *tmp_sec_str;
+ unsigned short int timeunits;
+ if(seconds!=0){
+ timeunits = seconds / 86400; seconds %= 86400;
+ if( timeunits > 0 ) {
+ asprintf(&tmp_day_str, "%dd", timeunits);
+ }else{
+ tmp_day_str = strdup("");
+ }
+ timeunits = seconds / 3600; seconds %= 3600;
+ if( timeunits > 0 ) {
+ asprintf(&tmp_hour_str, "%dh", timeunits);
+ }else{
+ tmp_hour_str = strdup("");
+ }
+ timeunits = seconds / 60; seconds %= 60;
+ if(timeunits > 0) {
+ asprintf(&tmp_min_str, "%dm", timeunits);
+ }else{
+ tmp_min_str = strdup("");
+ }
+ if(seconds > 0) {
+ asprintf(&tmp_sec_str, "%ds", seconds);
+ }else{
+ tmp_sec_str = strdup("");
+ }
+ asprintf(&tmp_str, "%s%s%s%s", tmp_day_str, tmp_hour_str, tmp_min_str, tmp_sec_str);
+ free(tmp_day_str); free(tmp_hour_str); free(tmp_min_str); free(tmp_sec_str);
+ }else{
+ asprintf(&tmp_str, "Range not possible"); //should never happen, but better safe then sorry
+ }
+ cur_x += (w / 2) - (font_ascent() * (strlen(tmp_str) / 2));
+ cur_y += font_height() / 2;
+ draw_string(tmp_str);
+ free(tmp_str);
+ cur_x = tmp_x;
+ cur_y = tmp_y;
+ }
+#ifdef MATH
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;
+ cur_x += font_ascent() / 2;
+ cur_y += font_height() / 2;
tmp_str = (char *)
calloc(log10(floor(specials[special_index].graph_scale)) + 4,
sizeof(char));
cur_x = tmp_x;
cur_y = tmp_y;
}
+#endif
set_foreground_color(last_colour);
break;
}
}
set_foreground_color(default_fg_color);
- draw_mode = FG;
#endif /* X11 */
+ draw_mode = FG;
draw_text();
#ifdef X11
#ifdef HAVE_XDBE
#ifdef SIGNAL_BLOCKING
sigset_t newmask, oldmask;
#endif
+ double t;
#ifdef X11
Region region = XCreateRegion();
sigaddset(&newmask, SIGUSR1);
#endif
+ next_update_time = last_update_time = get_time();
info.looped = 0;
while (total_run_times == 0 || info.looped < total_run_times) {
info.looped++;
fd_set fdsr;
struct timeval tv;
int s;
- double t = update_interval - (get_time() - last_update_time);
+ t = next_update_time - get_time();
if (t < 0) {
t = 0;
+ } else if (t > update_interval) {
+ t = update_interval;
}
tv.tv_sec = (long) t;
/* timeout */
if (s == 0) {
#else
- /* FIXME just sleep for the interval time if no X11 */
- usleep(update_interval * 1000000);
+ t = (next_update_time - get_time()) * 1000000;
+ usleep((useconds_t)t);
#endif /* X11 */
update_text();
#ifdef X11
static void load_config_file(const char *);
/* reload the config file */
-void reload_config(void)
+static void reload_config(void)
{
timed_thread_destroy_registered_threads();
}
#endif
+#ifdef MOC
+ free_moc(&info.moc);
+#endif
+
#ifdef X11
free_fonts();
#endif /* X11 */
#ifdef TCP_PORT_MONITOR
- destroy_tcp_port_monitor_collection(info.p_tcp_port_monitor_collection);
+ tcp_portmon_clear();
#endif
if (current_config) {
XClearWindow(display, RootWindow(display, screen));
#endif /* X11 */
-#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);
}
}
}
-void clean_up(void)
+static void clean_up(void)
{
timed_thread_destroy_registered_threads();
free_fonts();
#endif /* X11 */
- free_text_objects(global_text_object_count, global_text_objects);
+ free_text_objects(&global_root_object, 1);
if (tmpstring1) {
free(tmpstring1);
tmpstring1 = 0;
free(text_buffer);
text_buffer = 0;
}
- global_text_object_count = 0;
- global_text_objects = NULL;
- if (text) {
- free(text);
- text = 0;
+ if (global_text) {
+ free(global_text);
+ global_text = 0;
}
free(current_config);
#ifdef TCP_PORT_MONITOR
- destroy_tcp_port_monitor_collection(info.p_tcp_port_monitor_collection);
- info.p_tcp_port_monitor_collection = NULL;
+ tcp_portmon_clear();
#endif
#ifdef RSS
free_rss_info();
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) {
+ } else if (strcasecmp(s, "yes") == EQUAL) {
return 1;
- } else if (strcasecmp(s, "true") == 0) {
+ } else if (strcasecmp(s, "true") == EQUAL) {
return 1;
- } else if (strcasecmp(s, "1") == 0) {
+ } else if (strcasecmp(s, "1") == EQUAL) {
return 1;
}
return 0;
#ifdef X11
static enum alignment string_to_alignment(const char *s)
{
- if (strcasecmp(s, "top_left") == 0) {
+ if (strcasecmp(s, "top_left") == EQUAL) {
return TOP_LEFT;
- } else if (strcasecmp(s, "top_right") == 0) {
+ } else if (strcasecmp(s, "top_right") == EQUAL) {
return TOP_RIGHT;
- } else if (strcasecmp(s, "top_middle") == 0) {
+ } else if (strcasecmp(s, "top_middle") == EQUAL) {
return TOP_MIDDLE;
- } else if (strcasecmp(s, "bottom_left") == 0) {
+ } else if (strcasecmp(s, "bottom_left") == EQUAL) {
return BOTTOM_LEFT;
- } else if (strcasecmp(s, "bottom_right") == 0) {
+ } else if (strcasecmp(s, "bottom_right") == EQUAL) {
return BOTTOM_RIGHT;
- } else if (strcasecmp(s, "bottom_middle") == 0) {
+ } else if (strcasecmp(s, "bottom_middle") == EQUAL) {
return BOTTOM_MIDDLE;
- } else if (strcasecmp(s, "middle_left") == 0) {
+ } else if (strcasecmp(s, "middle_left") == EQUAL) {
return MIDDLE_LEFT;
- } else if (strcasecmp(s, "middle_right") == 0) {
+ } else if (strcasecmp(s, "middle_right") == EQUAL) {
return MIDDLE_RIGHT;
- } else if (strcasecmp(s, "tl") == 0) {
+ } else if (strcasecmp(s, "tl") == EQUAL) {
return TOP_LEFT;
- } else if (strcasecmp(s, "tr") == 0) {
+ } else if (strcasecmp(s, "tr") == EQUAL) {
return TOP_RIGHT;
- } else if (strcasecmp(s, "tm") == 0) {
+ } else if (strcasecmp(s, "tm") == EQUAL) {
return TOP_MIDDLE;
- } else if (strcasecmp(s, "bl") == 0) {
+ } else if (strcasecmp(s, "bl") == EQUAL) {
return BOTTOM_LEFT;
- } else if (strcasecmp(s, "br") == 0) {
+ } else if (strcasecmp(s, "br") == EQUAL) {
return BOTTOM_RIGHT;
- } else if (strcasecmp(s, "bm") == 0) {
+ } else if (strcasecmp(s, "bm") == EQUAL) {
return BOTTOM_MIDDLE;
- } else if (strcasecmp(s, "ml") == 0) {
+ } else if (strcasecmp(s, "ml") == EQUAL) {
return MIDDLE_LEFT;
- } else if (strcasecmp(s, "mr") == 0) {
+ } else if (strcasecmp(s, "mr") == EQUAL) {
return MIDDLE_RIGHT;
- } else if (strcasecmp(s, "none") == 0) {
+ } else if (strcasecmp(s, "none") == EQUAL) {
return NONE;
}
return TOP_LEFT;
info.mpd.name = NULL;
info.mpd.file = NULL;
#endif
+#ifdef MOC
+ init_moc(&info.moc);
+#endif
#ifdef XMMS2
info.xmms2.artist = NULL;
info.xmms2.album = NULL;
#endif
use_spacer = NO_SPACER;
#ifdef X11
- out_to_console = 0;
+ output_methods = TO_X;
#else
- out_to_console = 1;
+ output_methods = TO_STDOUT;
#endif
#ifdef X11
show_graph_scale = 0;
+ show_graph_range = 0;
default_fg_color = WhitePixel(display, screen);
default_bg_color = BlackPixel(display, screen);
default_out_color = BlackPixel(display, screen);
color7 = default_fg_color;
color8 = default_fg_color;
color9 = default_fg_color;
+ template[0] = strdup("");
+ template[1] = strdup("");
+ template[2] = strdup("");
+ template[3] = strdup("");
+ template[4] = strdup("");
+ template[5] = strdup("");
+ template[6] = strdup("");
+ template[7] = strdup("");
+ template[8] = strdup("");
+ template[9] = strdup("");
draw_shades = 1;
draw_borders = 0;
draw_graph_borders = 1;
own_window = 0;
window.type = TYPE_NORMAL;
window.hints = 0;
- strcpy(window.class_name, "Conky");
+ strcpy(window.class_name, PACKAGE_NAME);
update_uname();
- sprintf(window.title, "Conky (%s)", info.uname_s.nodename);
+ sprintf(window.title, PACKAGE_NAME" (%s)", info.uname_s.nodename);
#endif
stippled_borders = 0;
border_margin = 3;
border_width = 1;
text_alignment = BOTTOM_LEFT;
+ info.x11.monitor.number = 1;
+ info.x11.monitor.current = 0;
#endif /* X11 */
free(current_mail_spool);
info.users.number = 1;
#ifdef TCP_PORT_MONITOR
- tcp_port_monitor_args.max_port_monitor_connections =
- MAX_PORT_MONITOR_CONNECTIONS_DEFAULT;
+ /* set default connection limit */
+ tcp_portmon_set_max_connections(0);
#endif
}
FILE *fp;
set_default_configurations();
- fp = fopen(f, "r");
+#ifdef CONFIG_OUTPUT
+ if (!strcmp(f, "==builtin==")) {
+#ifdef HAVE_FOPENCOOKIE
+ fp = fopencookie(NULL, "r", conf_cookie);
+#endif
+ } else
+#endif /* CONFIG_OUTPUT */
+ fp = fopen(f, "r");
+
if (!fp) {
return;
}
+ DBGP("reading contents from config file '%s'", f);
while (!feof(fp)) {
char buf[256], *p, *p2, *name, *value;
#ifdef X11
CONF2("alignment") {
- if (value) {
+ if (window.type == TYPE_DOCK)
+ ;
+ else if (value) {
int a = string_to_alignment(value);
if (a <= 0) {
CONF("show_graph_scale") {
show_graph_scale = string_to_bool(value);
}
+ CONF("show_graph_range") {
+ show_graph_range = string_to_bool(value);
+ }
CONF("border_margin") {
if (value) {
border_margin = strtol(value, 0, 0);
CONF_ERR;
}
}
+#define TEMPLATE_CONF(n) \
+ CONF("template"#n) { \
+ if (value) { \
+ free(template[n]); \
+ template[n] = strdup(value); \
+ } else { \
+ CONF_ERR; \
+ } \
+ }
+ TEMPLATE_CONF(0)
+ TEMPLATE_CONF(1)
+ TEMPLATE_CONF(2)
+ TEMPLATE_CONF(3)
+ TEMPLATE_CONF(4)
+ TEMPLATE_CONF(5)
+ TEMPLATE_CONF(6)
+ TEMPLATE_CONF(7)
+ TEMPLATE_CONF(8)
+ TEMPLATE_CONF(9)
CONF("default_color") {
if (value) {
default_fg_color = get_x11_color(value);
#endif /* X11 */
CONF("imap") {
if (value) {
- info.mail = parse_mail_args(IMAP, value);
+ info.mail = parse_mail_args(IMAP_TYPE, value);
} else {
CONF_ERR;
}
}
CONF("pop3") {
if (value) {
- info.mail = parse_mail_args(POP3, value);
+ info.mail = parse_mail_args(POP3_TYPE, value);
} else {
CONF_ERR;
}
}
#endif /* X11 */
CONF("out_to_console") {
- out_to_console = string_to_bool(value);
+ if(string_to_bool(value)) output_methods |= TO_STDOUT;
}
CONF("use_spacer") {
if (value) {
- if (strcasecmp(value, "left") == 0) {
+ if (strcasecmp(value, "left") == EQUAL) {
use_spacer = LEFT_SPACER;
- } else if (strcasecmp(value, "right") == 0) {
+ } else if (strcasecmp(value, "right") == EQUAL) {
use_spacer = RIGHT_SPACER;
- } else if (strcasecmp(value, "none") == 0) {
+ } else if (strcasecmp(value, "none") == EQUAL) {
use_spacer = NO_SPACER;
} else {
use_spacer = string_to_bool(value);
if ((p_hint = strtok_r(value, delim, &p_save)) != NULL) {
do {
/* fprintf(stderr, "hint [%s] parsed\n", p_hint); */
- if (strncmp(p_hint, "undecorate", 10) == 0) {
+ if (strncmp(p_hint, "undecorate", 10) == EQUAL) {
SET_HINT(window.hints, HINT_UNDECORATED);
- } else if (strncmp(p_hint, "below", 5) == 0) {
+ } else if (strncmp(p_hint, "below", 5) == EQUAL) {
SET_HINT(window.hints, HINT_BELOW);
- } else if (strncmp(p_hint, "above", 5) == 0) {
+ } else if (strncmp(p_hint, "above", 5) == EQUAL) {
SET_HINT(window.hints, HINT_ABOVE);
- } else if (strncmp(p_hint, "sticky", 6) == 0) {
+ } else if (strncmp(p_hint, "sticky", 6) == EQUAL) {
SET_HINT(window.hints, HINT_STICKY);
- } else if (strncmp(p_hint, "skip_taskbar", 12) == 0) {
+ } else if (strncmp(p_hint, "skip_taskbar", 12) == EQUAL) {
SET_HINT(window.hints, HINT_SKIP_TASKBAR);
- } else if (strncmp(p_hint, "skip_pager", 10) == 0) {
+ } else if (strncmp(p_hint, "skip_pager", 10) == EQUAL) {
SET_HINT(window.hints, HINT_SKIP_PAGER);
} else {
CONF_ERR;
}
CONF("own_window_type") {
if (value) {
- if (strncmp(value, "normal", 6) == 0) {
+ if (strncmp(value, "normal", 6) == EQUAL) {
window.type = TYPE_NORMAL;
- } else if (strncmp(value, "desktop", 7) == 0) {
+ } else if (strncmp(value, "desktop", 7) == EQUAL) {
window.type = TYPE_DESKTOP;
- } else if (strncmp(value, "override", 8) == 0) {
+ } else if (strncmp(value, "dock", 7) == EQUAL) {
+ window.type = TYPE_DOCK;
+ text_alignment = TOP_LEFT;
+ } else if (strncmp(value, "override", 8) == EQUAL) {
window.type = TYPE_OVERRIDE;
} else {
CONF_ERR;
}
}
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);
- if (strlen(text) < 1) {
+ if (strlen(global_text) < 1) {
CRIT_ERR("no text supplied in configuration; exiting");
}
- text_lines = line + 1;
+ global_text_lines = line + 1;
return;
}
#ifdef TCP_PORT_MONITOR
CONF("max_port_monitor_connections") {
- if (!value || (sscanf(value, "%d",
- &tcp_port_monitor_args.max_port_monitor_connections) != 1)
- || tcp_port_monitor_args.max_port_monitor_connections < 0) {
+ int max;
+ if (!value || (sscanf(value, "%d", &max) != 1)) {
/* an error. use default, warn and continue. */
- tcp_port_monitor_args.max_port_monitor_connections =
- MAX_PORT_MONITOR_CONNECTIONS_DEFAULT;
+ tcp_portmon_set_max_connections(0);
+ CONF_ERR;
+ } else if (tcp_portmon_set_max_connections(max)) {
+ /* max is < 0, default has been set*/
CONF_ERR;
- } else if (tcp_port_monitor_args.max_port_monitor_connections
- == 0) {
- /* no error, just use default */
- tcp_port_monitor_args.max_port_monitor_connections =
- MAX_PORT_MONITOR_CONNECTIONS_DEFAULT;
}
- /* else tcp_port_monitor_args.max_port_monitor_connections > 0
- * 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 (strcasecmp(value, "up") == EQUAL) {
+ ifup_strictness = IFUP_UP;
+ } else if (strcasecmp(value, "link") == EQUAL) {
+ ifup_strictness = IFUP_LINK;
+ } else if (strcasecmp(value, "address") == EQUAL) {
+ ifup_strictness = IFUP_ADDR;
+ } else {
+ ERR("incorrect if_up_strictness value, defaulting to 'up'");
+ ifup_strictness = IFUP_UP;
+ }
+ }
+
+ CONF("temperature_unit") {
+ if (!value) {
+ ERR("config option 'temperature_unit' needs an argument");
+ } else if (set_temp_output_unit(value)) {
+ ERR("temperature_unit: incorrect argument");
+ }
+ }
+
else {
ERR("%s: %d: no such configuration: '%s'", f, line, name);
}
// default to update_interval
info.music_player_interval = update_interval;
}
- if (!text) { // didn't supply any text
+ 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"
+ PACKAGE_NAME" 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"
+ " -D, --debug increase debugging output\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 "PACKAGE_NAME" (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 = "vVqdDt:u:i:hc:"
#ifdef X11
"x:y:w:a:f:"
#ifdef OWN_WINDOW
#ifdef HAVE_XDBE
"b"
#endif
+#ifdef CONFIG_OUTPUT
+ "C"
+#endif
#endif /* X11 */
;
static const struct option longopts[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' },
+ { "debug", 0, NULL, 'D' },
{ "config", 1, NULL, 'c' },
+#ifdef CONFIG_OUTPUT
+ { "print-config", 0, NULL, 'C' },
+#endif
{ "daemonize", 0, NULL, 'd' },
#ifdef X11
{ "alignment", 1, NULL, 'a' },
g_signal_pending = 0;
memset(&info, 0, sizeof(info));
+ clear_net_stats();
#ifdef TCP_PORT_MONITOR
- tcp_port_monitor_args.max_port_monitor_connections =
- MAX_PORT_MONITOR_CONNECTIONS_DEFAULT;
+ /* set default connection limit */
+ tcp_portmon_set_max_connections(0);
#endif
/* handle command line parameters that don't change configs */
}
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,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",
- argv[0]
- );
+ print_help(argv[0]);
+ return 0;
+#ifdef CONFIG_OUTPUT
+ case 'C':
+ print_defconfig();
return 0;
+#endif
#ifdef X11
case 'w':
window.window = strtol(optarg, 0, 0);
/* No readable config found */
if (!current_config) {
+#ifdef CONFIG_OUTPUT
+ current_config = strdup("==builtin==");
+ ERR("no readable personal or system-wide config file found,"
+ " using builtin default");
+#else
CRIT_ERR("no readable personal or system-wide config file found");
+#endif /* ! CONF_OUTPUT */
}
}
case 'd':
fork_to_background = 1;
break;
-
+ case 'D':
+ global_debug_level++;
+ break;
#ifdef X11
case 'f':
set_first_font(optarg);
#endif
#endif /* X11 */
case 't':
- if (text) {
- free(text);
- text = 0;
+ if (global_text) {
+ free(global_text);
+ global_text = 0;
}
- text = strndup(optarg, max_user_text);
- 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();
switch (pid) {
case -1:
- ERR("Conky: couldn't fork() to background: %s",
+ ERR(PACKAGE_NAME": couldn't fork() to background: %s",
strerror(errno));
break;
default:
/* parent process */
- fprintf(stderr, "Conky: forked to background, pid is %d\n",
+ fprintf(stderr, PACKAGE_NAME": forked to background, pid is %d\n",
pid);
fflush(stderr);
return 0;
selected_font = 0;
update_text_area(); /* to position text/window on screen */
-#endif /* X11 */
-#ifdef X11
#ifdef OWN_WINDOW
if (own_window && !fixed_pos) {
XMoveWindow(display, window.window, window.x, window.y);
act.sa_flags |= SA_RESTART;
#endif
- if (sigaction(SIGINT, &act, &oact) < 0
- || sigaction(SIGUSR1, &act, &oact) < 0
- || sigaction(SIGHUP,&act,&oact) < 0
- || sigaction(SIGTERM, &act, &oact) < 0) {
+ if ( sigaction(SIGINT, &act, &oact) < 0
+ || sigaction(SIGUSR1, &act, &oact) < 0
+ || sigaction(SIGHUP, &act, &oact) < 0
+ || sigaction(SIGTERM, &act, &oact) < 0) {
ERR("error setting signal handler: %s", strerror(errno));
}
- /* *************** *
- * MAIN CONKY LOOP *
- * *************** */
main_loop();
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
return 0;
}
-void signal_handler(int sig)
+static void signal_handler(int sig)
{
/* signal handler is light as a feather, as it should be.
* we will poll g_signal_pending with each loop of conky