diff --git a/src/Makefile.am b/src/Makefile.am
index 973f5d11..568b621e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -121,8 +121,6 @@ conky_SOURCES = \
conky.h \
$(freebsd) \
fs.c \
- head.c \
- head.h \
$(hddtemp) \
$(linux) \
logging.h \
@@ -144,8 +142,8 @@ conky_SOURCES = \
$(x11) \
$(xmms2) \
$(ibm) \
- tail.c \
- tail.h \
+ tailhead.c \
+ tailhead.h \
temphelper.c \
temphelper.h \
text_object.h \
@@ -167,8 +165,6 @@ EXTRA_DIST = \
freebsd.c \
freebsd.h \
fs.h \
- head.c \
- head.h \
hddtemp.c \
hddtemp.h \
linux.c \
@@ -190,8 +186,8 @@ EXTRA_DIST = \
openbsd.c \
openbsd.h \
solaris.c \
- tail.c \
- tail.h \
+ tailhead.c \
+ tailhead.h \
top.h \
diskio.h \
x11.c \
diff --git a/src/conky.c b/src/conky.c
index 32376bb2..413f0564 100644
--- a/src/conky.c
+++ b/src/conky.c
@@ -64,13 +64,12 @@
#include "build.h"
#include "diskio.h"
#include "fs.h"
-#include "head.h"
#include "logging.h"
#include "mixer.h"
#include "mail.h"
#include "mboxscan.h"
#include "temphelper.h"
-#include "tail.h"
+#include "tailhead.h"
#include "top.h"
/* check for OS and include appropriate headers */
diff --git a/src/head.c b/src/head.c
deleted file mode 100644
index 04c0823f..00000000
--- a/src/head.c
+++ /dev/null
@@ -1,144 +0,0 @@
-#include "config.h"
-#include "conky.h"
-#include "logging.h"
-#include "tail.h" /* MAX_TAIL_LINES */
-
-int init_head_object(struct text_object *obj, const char *arg)
-{
- char buf[64];
- int n1, n2;
- FILE *fp;
- int numargs;
-
- if (!arg) {
- ERR("head needs arguments");
- return 1;
- }
-
- numargs = sscanf(arg, "%63s %i %i", buf, &n1, &n2);
-
- if (numargs < 2 || numargs > 3) {
- ERR("incorrect number of arguments given to tail object");
- return 1;
- }
-
- if (n1 < 1 || n1 > MAX_TAIL_LINES) {
- ERR("invalid arg for tail, number of lines must be "
- "between 1 and %i", MAX_TAIL_LINES);
- return 1;
- }
-
- if ((fp = fopen(buf, "r")) == NULL) {
- ERR("head logfile does not exist, or you do not have "
- "correct permissions");
- return 1;
- }
-
- obj->data.tail.logfile = malloc(text_buffer_size);
- strcpy(obj->data.tail.logfile, buf);
- obj->data.tail.wantedlines = n1;
- obj->data.tail.interval = update_interval * 2;
- fclose(fp);
-
- /* XXX: the following implies update_interval >= 1 ?! */
- if (numargs == 3 && (n2 < 1 || n2 < update_interval)) {
- ERR("tail interval must be greater than "
- "0 and "PACKAGE_NAME"'s interval, ignoring");
- } else if (numargs == 3) {
- obj->data.tail.interval = n2;
- }
- /* asumming all else worked */
- obj->data.tail.buffer = malloc(text_buffer_size * 20);
- return 0;
-}
-
-static long fwd_fcharfind(FILE *fp, char val, unsigned int step)
-{
-#define BUFSZ 0x1000
- long ret = -1;
- unsigned int count = 0;
- static char buf[BUFSZ];
- long orig_pos = ftell(fp);
- long buf_pos = -1;
- long buf_size = BUFSZ;
- char *cur_found = NULL;
-
- while (count < step) {
- if (cur_found == NULL) {
- buf_size = fread(buf, 1, buf_size, fp);
- buf_pos = 0;
- }
- cur_found = memchr(buf + buf_pos, val, buf_size - buf_pos);
- if (cur_found != NULL) {
- buf_pos = cur_found - buf + 1;
- count++;
- } else {
- if (feof(fp)) {
- break;
- }
- }
- }
- if (count == step) {
- ret = ftell(fp) - buf_size + buf_pos - 1;
- }
- fseek(fp, orig_pos, SEEK_SET);
- return ret;
-}
-
-int print_head_object(struct text_object *obj, char *p, size_t p_max_size)
-{
- FILE *fp;
- long nl = 0;
- int iter;
-
- if (current_update_time - obj->data.tail.last_update < obj->data.tail.interval) {
- snprintf(p, p_max_size, "%s", obj->data.tail.buffer);
- return 0;
- }
-
- obj->data.tail.last_update = current_update_time;
-
- fp = fopen(obj->data.tail.logfile, "rt");
- if (fp == NULL) {
- /* Send one message, but do not consistently spam
- * on missing logfiles. */
- if (obj->data.tail.readlines != 0) {
- ERR("head logfile failed to open");
- strcpy(obj->data.tail.buffer, "Logfile Missing");
- }
- obj->data.tail.readlines = 0;
- snprintf(p, p_max_size, "Logfile Missing");
- } else {
- obj->data.tail.readlines = 0;
- for (iter = obj->data.tail.wantedlines; iter > 0;
- iter--) {
- nl = fwd_fcharfind(fp, '\n', iter);
- if (nl >= 0) {
- break;
- }
- }
- obj->data.tail.readlines = iter;
- /* Make sure nl is at least 1 byte smaller than the
- * buffer max size. */
- if (nl > (long) ((text_buffer_size * 20) - 1)) {
- nl = text_buffer_size * 20 - 1;
- }
- nl = fread(obj->data.tail.buffer, 1, nl, fp);
- fclose(fp);
- if (nl > 0) {
- /* Clean up trailing newline, make sure the buffer
- * is null terminated. */
- if (obj->data.tail.buffer[nl - 1] == '\n') {
- obj->data.tail.buffer[nl - 1] = '\0';
- } else {
- obj->data.tail.buffer[nl] = '\0';
- }
- snprintf(p, p_max_size, "%s",
- obj->data.tail.buffer);
- } else {
- strcpy(obj->data.tail.buffer, "Logfile Empty");
- snprintf(p, p_max_size, "Logfile Empty");
- } /* nl > 0 */
- } /* if fp == null */
- return 0;
-}
diff --git a/src/head.h b/src/head.h
deleted file mode 100644
index aadcd773..00000000
--- a/src/head.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _HEAD_H
-#define _HEAD_H
-
-#include "text_object.h"
-
-int init_head_object(struct text_object *, const char *);
-int print_head_object(struct text_object *, char *, size_t);
-
-#endif /* _HEAD_H */
diff --git a/src/tail.h b/src/tail.h
deleted file mode 100644
index a2690234..00000000
--- a/src/tail.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _TAIL_H
-#define _TAIL_H
-
-#include "text_object.h"
-
-#define MAX_TAIL_LINES 100
-
-int init_tail_object(struct text_object *, const char *);
-int print_tail_object(struct text_object *, char *, size_t);
-
-#endif /* _TAIL_H */
diff --git a/src/tail.c b/src/tailhead.c
similarity index 58%
rename from src/tail.c
rename to src/tailhead.c
index 91df3158..ab89d48e 100644
--- a/src/tail.c
+++ b/src/tailhead.c
@@ -1,17 +1,43 @@
+/* Conky, a system monitor, based on torsmo
+ *
+ * Any original torsmo code is licensed under the BSD license
+ *
+ * All code written since the fork of torsmo is licensed under the GPL
+ *
+ * Please see COPYING for details
+ *
+ * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
+ * Copyright (c) 2005-2008 Brenden Matthews, Philip Kovacs, et. al.
+ * (see AUTHORS)
+ * All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
#include "config.h"
#include "conky.h"
#include "logging.h"
-#include "tail.h"
+#include "tailhead.h"
#include "text_object.h"
#include
#include
-//#include
#include
#include
#include
-int init_tail_object(struct text_object *obj, const char *arg)
+int init_tailhead_object(enum tailhead_type type,
+ struct text_object *obj, const char *arg)
{
char buf[64];
int n1, n2;
@@ -19,39 +45,47 @@ int init_tail_object(struct text_object *obj, const char *arg)
FILE *fp = NULL;
int fd;
int numargs;
+ const char *me;
+
+ /* FIXME: use #define for that */
+ me = (type == TAIL) ? "tail" : "head";
if (!arg) {
- ERR("tail needs arguments");
+ ERR("%s needs arguments", me);
return 1;
}
numargs = sscanf(arg, "%63s %i %i", buf, &n1, &n2);
if (numargs < 2 || numargs > 3) {
- ERR("incorrect number of arguments given to tail object");
+ ERR("incorrect number of arguments given to %s object", me);
return 1;
}
if (n1 < 1 || n1 > MAX_TAIL_LINES) {
- ERR("invalid arg for tail, number of lines must be "
- "between 1 and %i", MAX_TAIL_LINES);
+ ERR("invalid arg for %s, number of lines must be "
+ "between 1 and %i", me, MAX_TAIL_LINES);
return 1;
}
obj->data.tail.fd = -1;
+ if (type == HEAD) {
+ goto NO_FIFO;
+ }
if (stat(buf, &st) == 0) {
if (S_ISFIFO(st.st_mode)) {
fd = open(buf, O_RDONLY | O_NONBLOCK);
if (fd == -1) {
- ERR("tail logfile does not exist, or you do "
- "not have correct permissions");
+ ERR("%s logfile does not exist, or you do "
+ "not have correct permissions", me);
return 1;
}
obj->data.tail.fd = fd;
} else {
+NO_FIFO:
fp = fopen(buf, "r");
}
}
@@ -67,14 +101,14 @@ int init_tail_object(struct text_object *obj, const char *arg)
}
} else {
// fclose(fp);
- ERR("tail logfile does not exist, or you do not have "
- "correct permissions");
+ ERR("%s logfile does not exist, or you do not have "
+ "correct permissions", me);
return 1;
}
/* XXX: the following implies update_interval >= 1 ?! */
if (numargs == 3 && (n2 < 1 || n2 < update_interval)) {
- ERR("tail interval must be greater than "
- "0 and "PACKAGE_NAME"'s interval, ignoring");
+ ERR("%s interval must be greater than "
+ "0 and "PACKAGE_NAME"'s interval, ignoring", me);
} else if (numargs == 3) {
obj->data.tail.interval = n2;
}
@@ -280,3 +314,94 @@ int print_tail_object(struct text_object *obj, char *p, size_t p_max_size)
} /* fp == NULL */
return 0;
}
+
+long fwd_fcharfind(FILE *fp, char val, unsigned int step)
+{
+#define BUFSZ 0x1000
+ long ret = -1;
+ unsigned int count = 0;
+ static char buf[BUFSZ];
+ long orig_pos = ftell(fp);
+ long buf_pos = -1;
+ long buf_size = BUFSZ;
+ char *cur_found = NULL;
+
+ while (count < step) {
+ if (cur_found == NULL) {
+ buf_size = fread(buf, 1, buf_size, fp);
+ buf_pos = 0;
+ }
+ cur_found = memchr(buf + buf_pos, val, buf_size - buf_pos);
+ if (cur_found != NULL) {
+ buf_pos = cur_found - buf + 1;
+ count++;
+ } else {
+ if (feof(fp)) {
+ break;
+ }
+ }
+ }
+ if (count == step) {
+ ret = ftell(fp) - buf_size + buf_pos - 1;
+ }
+ fseek(fp, orig_pos, SEEK_SET);
+ return ret;
+}
+
+int print_head_object(struct text_object *obj, char *p, size_t p_max_size)
+{
+ FILE *fp;
+ long nl = 0;
+ int iter;
+
+ if (current_update_time - obj->data.tail.last_update < obj->data.tail.interval) {
+ snprintf(p, p_max_size, "%s", obj->data.tail.buffer);
+ return 0;
+ }
+
+ obj->data.tail.last_update = current_update_time;
+
+ fp = fopen(obj->data.tail.logfile, "rt");
+ if (fp == NULL) {
+ /* Send one message, but do not consistently spam
+ * on missing logfiles. */
+ if (obj->data.tail.readlines != 0) {
+ ERR("head logfile failed to open");
+ strcpy(obj->data.tail.buffer, "Logfile Missing");
+ }
+ obj->data.tail.readlines = 0;
+ snprintf(p, p_max_size, "Logfile Missing");
+ } else {
+ obj->data.tail.readlines = 0;
+ for (iter = obj->data.tail.wantedlines; iter > 0;
+ iter--) {
+ nl = fwd_fcharfind(fp, '\n', iter);
+ if (nl >= 0) {
+ break;
+ }
+ }
+ obj->data.tail.readlines = iter;
+ /* Make sure nl is at least 1 byte smaller than the
+ * buffer max size. */
+ if (nl > (long) ((text_buffer_size * 20) - 1)) {
+ nl = text_buffer_size * 20 - 1;
+ }
+ nl = fread(obj->data.tail.buffer, 1, nl, fp);
+ fclose(fp);
+ if (nl > 0) {
+ /* Clean up trailing newline, make sure the buffer
+ * is null terminated. */
+ if (obj->data.tail.buffer[nl - 1] == '\n') {
+ obj->data.tail.buffer[nl - 1] = '\0';
+ } else {
+ obj->data.tail.buffer[nl] = '\0';
+ }
+ snprintf(p, p_max_size, "%s",
+ obj->data.tail.buffer);
+ } else {
+ strcpy(obj->data.tail.buffer, "Logfile Empty");
+ snprintf(p, p_max_size, "Logfile Empty");
+ } /* nl > 0 */
+ } /* if fp == null */
+ return 0;
+}
diff --git a/src/tailhead.h b/src/tailhead.h
new file mode 100644
index 00000000..f3485f18
--- /dev/null
+++ b/src/tailhead.h
@@ -0,0 +1,47 @@
+/* Conky, a system monitor, based on torsmo
+ *
+ * Any original torsmo code is licensed under the BSD license
+ *
+ * All code written since the fork of torsmo is licensed under the GPL
+ *
+ * Please see COPYING for details
+ *
+ * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
+ * Copyright (c) 2005-2008 Brenden Matthews, Philip Kovacs, et. al.
+ * (see AUTHORS)
+ * All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#ifndef _TAILHEAD_H
+#define _TAILHEAD_H
+
+#include "text_object.h"
+
+#define MAX_TAIL_LINES 100
+
+enum tailhead_type {
+ TAIL,
+ HEAD,
+};
+
+#define init_tail_object(o, a) init_tailhead_object(TAIL, o, a)
+#define init_head_object(o, a) init_tailhead_object(HEAD, o, a)
+
+int init_tailhead_object(enum tailhead_type,
+ struct text_object *, const char *);
+int print_head_object(struct text_object *, char *, size_t);
+int print_tail_object(struct text_object *, char *, size_t);
+
+#endif /* _TAILHEAD_H */