From b6daf13a37b3f3ec4b4b78bc4e97718efa2eeeeb Mon Sep 17 00:00:00 2001 From: Luke Heberling Date: Fri, 22 Feb 2008 17:18:30 +0100 Subject: [PATCH] src/utils_tail.[ch]: Added a generic interface for `tail'ing files. This will be used to parse logfiles in the near future. --- src/Makefile.am | 1 + src/utils_tail.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++ src/utils_tail.h | 77 ++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 src/utils_tail.c create mode 100644 src/utils_tail.h diff --git a/src/Makefile.am b/src/Makefile.am index 30ea1ee3..50ad0c99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,6 +31,7 @@ collectd_SOURCES = collectd.c collectd.h \ utils_ignorelist.c utils_ignorelist.h \ utils_llist.c utils_llist.h \ utils_mount.c utils_mount.h \ + utils_tail.c utils_tail.h \ utils_threshold.c utils_threshold.h \ types_list.c types_list.h collectd_CPPFLAGS = $(LTDLINCL) diff --git a/src/utils_tail.c b/src/utils_tail.c new file mode 100644 index 00000000..5e5aa03d --- /dev/null +++ b/src/utils_tail.c @@ -0,0 +1,129 @@ +/** + * collectd - src/utils_tail.c + * Copyright (C) 2008 C-Ware, Inc. + * + * 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; only version 2 of the License is applicable. + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: + * Luke Heberling + * + * Description: + * Encapsulates useful code for plugins which must watch for appends to + * the end of a file. + **/ + + +#include "utils_tail.h" +#include +#include +#include +#include + +struct cu_tail_s +{ + char *file; + FILE *fd; + struct stat stat; +}; + +cu_tail_t *cu_tail_create (const char *file) +{ + cu_tail_t *obj; + + obj = (cu_tail_t *) malloc (sizeof (cu_tail_t)); + if (obj == NULL) + return (NULL); + memset (obj, '\0', sizeof (cu_tail_t)); + + obj->file = strdup (file); + if (obj->file == NULL) + { + free (obj); + return (NULL); + } + + obj->fd = NULL; + + return (obj); +} /* cu_tail_t *cu_tail_create */ + +int cu_tail_destroy (cu_tail_t *obj) +{ + if (obj->fd != NULL) + fclose (obj->fd); + free (obj->file); + free (obj); + + return (0); +} /* int cu_tail_destroy */ + +int cu_tail_readline (cu_tail_t *obj, char *buf, int buflen) +{ + struct stat stat_now; + FILE *new_fd; + int len; + + if( buflen < 1 ) + return -1; + + *buf = '\0'; + + if (stat (obj->file, &stat_now) != 0) + return 0; + + if (stat_now.st_dev != obj->stat.st_dev || + stat_now.st_ino != obj->stat.st_ino) + { + new_fd = fopen (obj->file, "r"); + if (new_fd == NULL) + return -1; + + if (obj->stat.st_ino == 0) + fseek (new_fd, 0, SEEK_END); + if (obj->fd != NULL) + fclose (obj->fd); + obj->fd = new_fd; + + } + else if (stat_now.st_size < obj->stat.st_size) + { + rewind (obj->fd); + } + + memcpy (&obj->stat, &stat_now, sizeof (struct stat)); + + if (fgets (buf, buflen, obj->fd) == NULL && feof (obj->fd) == 0) + return -1; + + len = strlen (buf); + if (len > 0 && *(buf + len - 1) != '\n' && feof (obj->fd)) + { + fseek (obj->fd, -len, SEEK_CUR); + *buf = '\0'; + } + + return 0; +} /* int cu_tail_readline */ + +int cu_tail_read (cu_tail_t *obj, char *buf, int buflen, tailfunc *func, void *data) +{ + int ret; + + while ((ret = cu_tail_readline (obj, buf, buflen)) == 0) + if (*buf == '\0' || (ret = func (data, buf, buflen))) + break; + + return ret; +} /* int cu_tail_read */ + diff --git a/src/utils_tail.h b/src/utils_tail.h new file mode 100644 index 00000000..a456870c --- /dev/null +++ b/src/utils_tail.h @@ -0,0 +1,77 @@ +/** + * collectd - src/utils_tail.h + * Copyright (C) 2007 C-Ware, Inc. + * + * 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; only version 2 of the License is applicable. + * + * 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, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: + * Luke Heberling + * + * DESCRIPTION + * Facilitates reading information that is appended to a file, taking into + * account that the file may be rotated and a new file created under the + * same name. + **/ + +#ifndef UTILS_TAIL_H +#define UTILS_TAIL_H 1 + +struct cu_tail_s; +typedef struct cu_tail_s cu_tail_t; + +typedef int tailfunc(void *data, char *buf, int buflen); + +/* + * NAME + * cu_tail_create + * + * DESCRIPTION + * Allocates a new tail object.. + * + * PARAMETERS + * `file' The name of the file to be tailed. + */ +cu_tail_t *cu_tail_create (const char *file); + +/* + * cu_tail_destroy + * + * Takes a tail object returned by `cu_tail_create' and destroys it, freeing + * all internal memory. + * + * Returns 0 when successful and non-zero otherwise. + */ +int cu_tail_destroy (cu_tail_t *obj); + +/* + * cu_tail_readline + * + * Reads from the file until `buflen' characters are read, a newline + * character is read, or an eof condition is encountered. `buf' is + * always null-terminated on successful return. + * + * Returns 0 when successful and non-zero otherwise. + */ +int cu_tail_readline (cu_tail_t *obj, char *buf, int buflen); + +/* + * cu_tail_readline + * + * Reads from the file until eof condition or an error is encountered. + * + * Returns 0 when successful and non-zero otherwise. + */ +int cu_tail_read (cu_tail_t *obj, char *buf, int buflen, tailfunc *func, void *data); + +#endif /* UTILS_TAIL_H */ -- 2.30.2