#include "common.h"
#include "utils_debug.h"
+extern int operating_mode;
+
#ifdef HAVE_LIBKSTAT
extern kstat_ctl_t *kc;
#endif
static int rra_num = 9;
#endif /* HAVE_LIBRRD */
-void
-sstrncpy(char *d, const char *s, int len)
+void sstrncpy (char *d, const char *s, int len)
{
- strncpy(d, s, len);
- d[len - 1] = 0;
+ strncpy (d, s, len);
+ d[len - 1] = '\0';
}
-char *
-sstrdup(const char *s)
+char *sstrdup (const char *s)
{
- char *r = strdup(s);
- if(r == NULL) {
- DBG("Not enough memory.");
+ char *r;
+
+ if (s == NULL)
+ return (NULL);
+
+ if((r = strdup (s)) == NULL)
+ {
+ DBG ("Not enough memory.");
exit(3);
}
- return r;
+
+ return (r);
}
-void *
-smalloc(size_t size)
+void *smalloc (size_t size)
{
- void *r = malloc(size);
- if(r == NULL) {
+ void *r;
+
+ if ((r = malloc (size)) == NULL)
+ {
DBG("Not enough memory.");
exit(3);
}
+
return r;
}
+#if 0
+void sfree (void **ptr)
+{
+ if (ptr == NULL)
+ return;
+
+ if (*ptr != NULL)
+ free (*ptr);
+
+ *ptr = NULL;
+}
+#endif
+
int strsplit (char *string, char **fields, size_t size)
{
size_t i;
return (0);
}
-#ifdef HAVE_LIBRRD
-int check_create_dir (const char *file_orig)
+static int check_create_dir (const char *file_orig)
{
struct stat statbuf;
for (i = 0; i < (fields_num - last_is_file); i++)
{
/*
- * Join the components together again
- */
- if (strjoin (dir, dir_len, fields, i + 1, "/") < 0)
- return (-1);
-
- /*
* Do not create directories that start with a dot. This
* prevents `../../' attacks and other likely malicious
* behavior.
*/
if (fields[i][0] == '.')
{
- syslog (LOG_ERR, "Cowardly refusing to create a directory that begins with a `.' (dot): `%s'", dir);
+ syslog (LOG_ERR, "Cowardly refusing to create a directory that begins with a `.' (dot): `%s'", file_orig);
return (-2);
}
+ /*
+ * Join the components together again
+ */
+ if (strjoin (dir, dir_len, fields, i + 1, "/") < 0)
+ {
+ syslog (LOG_ERR, "strjoin failed: `%s', component #%i", file_orig, i);
+ return (-1);
+ }
+
if (stat (dir, &statbuf) == -1)
{
if (errno == ENOENT)
return (0);
}
-int rrd_create_file (char *filename, char **ds_def, int ds_num)
+static int log_create_file (char *filename, char **ds_def, int ds_num)
+{
+ FILE *log;
+ int i;
+
+ log = fopen (filename, "w");
+ if (log == NULL)
+ {
+ syslog (LOG_WARNING, "Failed to create %s: %s", filename,
+ strerror(errno));
+ return (-1);
+ }
+
+ for (i = 0; i < ds_num; i++)
+ {
+ char *name;
+ char *tmp;
+
+ name = index (ds_def[i], ':');
+ if (name == NULL)
+ {
+ syslog (LOG_WARNING, "Invalid DS definition '%s' for %s",
+ ds_def[i], filename);
+ fclose(log);
+ remove(filename);
+ return (-1);
+ }
+
+ name += 1;
+ tmp = index(name, ':');
+ if (tmp == NULL)
+ {
+ syslog (LOG_WARNING, "Invalid DS definition '%s' for %s",
+ ds_def[i], filename);
+ fclose(log);
+ remove(filename);
+ return (-1);
+ }
+
+ if (i != 0)
+ fprintf (log, ":");
+ fprintf(log, "%.*s", (tmp - name), name);
+ }
+ fprintf(log, "\n");
+ fclose(log);
+
+ return 0;
+}
+
+static int log_update_file (char *host, char *file, char *values,
+ char **ds_def, int ds_num)
+{
+ char *tmp;
+ FILE *fp;
+ struct stat statbuf;
+ char full_file[1024];
+
+ /* host == NULL => local mode */
+ if (host != NULL)
+ {
+ if (snprintf (full_file, 1024, "%s/%s", host, file) >= 1024)
+ return (-1);
+ }
+ else
+ {
+ if (snprintf (full_file, 1024, "%s", file) >= 1024)
+ return (-1);
+ }
+
+ strncpy (full_file, file, 1024);
+
+ tmp = full_file + strlen (full_file) - 4;
+ assert (tmp > 0);
+
+ /* Change the filename for logfiles. */
+ if (strncmp (tmp, ".rrd", 4) == 0)
+ {
+ time_t now;
+ struct tm *tm;
+
+ now = time (NULL);
+ tm = localtime (&now);
+
+ strftime (tmp, 1024 - (tmp - full_file), "-%Y-%m-%d", tm);
+
+ /* `localtime(3)' returns a pointer to static data,
+ * therefore the pointer may not be free'd. */
+ }
+ else
+ DBG ("The filename ends with `%s' which is unexpected.", tmp);
+
+ if (stat (full_file, &statbuf) == -1)
+ {
+ if (errno == ENOENT)
+ {
+ if (log_create_file (full_file, ds_def, ds_num))
+ return (-1);
+ }
+ else
+ {
+ syslog (LOG_ERR, "stat %s: %s", full_file, strerror (errno));
+ return (-1);
+ }
+ }
+ else if (!S_ISREG (statbuf.st_mode))
+ {
+ syslog (LOG_ERR, "stat %s: Not a regular file!", full_file);
+ return (-1);
+ }
+
+
+ fp = fopen (full_file, "a");
+ if (fp == NULL)
+ {
+ syslog (LOG_WARNING, "Failed to append to %s: %s", full_file,
+ strerror(errno));
+ return (-1);
+ }
+ fprintf(fp, "%s\n", values);
+ fclose(fp);
+
+ return (0);
+} /* int log_update_file */
+
+#if HAVE_LIBRRD
+static int rrd_create_file (char *filename, char **ds_def, int ds_num)
{
char **argv;
int argc;
int i, j;
int status = 0;
+ if (check_create_dir (filename))
+ return (-1);
+
argc = ds_num + rra_num + 4;
if ((argv = (char **) malloc (sizeof (char *) * (argc + 1))) == NULL)
}
free (argv);
-
+
return (status);
}
#endif /* HAVE_LIBRRD */
int rrd_update_file (char *host, char *file, char *values,
char **ds_def, int ds_num)
{
-#ifdef HAVE_LIBRRD
+#if HAVE_LIBRRD
struct stat statbuf;
char full_file[1024];
char *argv[4] = { "update", full_file, values, NULL };
+#endif /* HAVE_LIBRRD */
+
+ /* I'd rather have a function `common_update_file' to make this
+ * decission, but for that we'd need to touch all plugins.. */
+ if (operating_mode == MODE_LOG)
+ return (log_update_file (host, file, values,
+ ds_def, ds_num));
+#if HAVE_LIBRRD
/* host == NULL => local mode */
if (host != NULL)
{
- if (check_create_dir (host))
- return (-1);
-
if (snprintf (full_file, 1024, "%s/%s", host, file) >= 1024)
return (-1);
}
syslog (LOG_WARNING, "rrd_update failed: %s: %s", full_file, rrd_get_error ());
return (-1);
}
-#endif /* HAVE_LIBRRD */
-
return (0);
+/* #endif HAVE_LIBRRD */
+
+#else
+ syslog (LOG_ERR, "`rrd_update_file' was called, but collectd isn't linked against librrd!");
+ return (-1);
+#endif
}
#ifdef HAVE_LIBKSTAT