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 */