X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fcommon.c;h=cf2a63989f357600d3dc7aa011b551c90abf59f4;hb=fd909f8965b2b6714dc1da328c77f3681c04af5e;hp=0a4cba3f80002b766717724c9651ec2afa4116e8;hpb=a000c91dc3de0977c2a57cf45dc8bd9f3045a14a;p=collectd.git diff --git a/src/common.c b/src/common.c index 0a4cba3f..cf2a6398 100644 --- a/src/common.c +++ b/src/common.c @@ -1,6 +1,6 @@ /** * collectd - src/common.c - * Copyright (C) 2005 Florian octo Forster + * Copyright (C) 2005,2006 Florian octo Forster * * This program is free software; you can redistribute it and/ * or modify it under the terms of the GNU General Public Li- @@ -25,30 +25,21 @@ #include "common.h" #include "utils_debug.h" +#ifdef HAVE_MATH_H +# include +#endif + +/* for ntohl and htonl */ +#if HAVE_ARPA_INET_H +# include +#endif + +extern int operating_mode; + #ifdef HAVE_LIBKSTAT extern kstat_ctl_t *kc; #endif -#ifdef HAVE_LIBRRD -static char *rra_def[] = -{ - "RRA:AVERAGE:0.0:1:1500", - "RRA:AVERAGE:0.2:6:1500", - "RRA:AVERAGE:0.1:180:1680", - "RRA:AVERAGE:0.1:2160:1520", - "RRA:MIN:0.0:1:1500", - "RRA:MIN:0.2:6:1500", - "RRA:MIN:0.1:180:1680", - "RRA:MIN:0.1:2160:1520", - "RRA:MAX:0.0:1:1500", - "RRA:MAX:0.2:6:1500", - "RRA:MAX:0.1:180:1680", - "RRA:MAX:0.1:2160:1520", - NULL -}; -static int rra_num = 12; -#endif /* HAVE_LIBRRD */ - void sstrncpy (char *d, const char *s, int len) { strncpy (d, s, len); @@ -97,6 +88,70 @@ void sfree (void **ptr) } #endif +ssize_t sread (int fd, void *buf, size_t count) +{ + char *ptr; + size_t nleft; + ssize_t status; + + ptr = (char *) buf; + nleft = count; + + while (nleft > 0) + { + status = read (fd, (void *) ptr, nleft); + + if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) + continue; + + if (status < 0) + return (status); + + if (status == 0) + { + DBG ("Received EOF from fd %i. " + "Closing fd and returning error.", + fd); + close (fd); + return (-1); + } + + assert (nleft >= status); + + nleft = nleft - status; + ptr = ptr + status; + } + + return (0); +} + + +ssize_t swrite (int fd, const void *buf, size_t count) +{ + const char *ptr; + size_t nleft; + ssize_t status; + + ptr = (const char *) buf; + nleft = count; + + while (nleft > 0) + { + status = write (fd, (const void *) ptr, nleft); + + if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) + continue; + + if (status < 0) + return (status); + + nleft = nleft - status; + ptr = ptr + status; + } + + return (0); +} + int strsplit (char *string, char **fields, size_t size) { size_t i; @@ -156,6 +211,27 @@ int strjoin (char *dst, size_t dst_len, return (strlen (dst)); } +int strsubstitute (char *str, char c_from, char c_to) +{ + int ret; + + if (str == NULL) + return (-1); + + ret = 0; + while (*str != '\0') + { + if (*str == c_from) + { + *str = c_to; + ret++; + } + str++; + } + + return (ret); +} + int escape_slashes (char *buf, int buf_len) { int i; @@ -184,7 +260,29 @@ int escape_slashes (char *buf, int buf_len) return (0); } -#ifdef HAVE_LIBRRD +int timeval_sub_timespec (struct timeval *tv0, struct timeval *tv1, struct timespec *ret) +{ + if ((tv0 == NULL) || (tv1 == NULL) || (ret == NULL)) + return (-2); + + if ((tv0->tv_sec < tv1->tv_sec) + || ((tv0->tv_sec == tv1->tv_sec) && (tv0->tv_usec < tv1->tv_usec))) + return (-1); + + ret->tv_sec = tv0->tv_sec - tv1->tv_sec; + ret->tv_nsec = 1000 * ((long) (tv0->tv_usec - tv1->tv_usec)); + + if (ret->tv_nsec < 0) + { + assert (ret->tv_sec > 0); + + ret->tv_nsec += 1000000000; + ret->tv_sec -= 1; + } + + return (0); +} + int check_create_dir (const char *file_orig) { struct stat statbuf; @@ -289,57 +387,69 @@ int check_create_dir (const char *file_orig) 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) { - char **argv; - int argc; - int i, j; - int status = 0; + FILE *log; + int i; if (check_create_dir (filename)) return (-1); - argc = ds_num + rra_num + 4; - - if ((argv = (char **) malloc (sizeof (char *) * (argc + 1))) == NULL) + log = fopen (filename, "w"); + if (log == NULL) { - syslog (LOG_ERR, "rrd_create failed: %s", strerror (errno)); + syslog (LOG_WARNING, "Failed to create %s: %s", filename, + strerror(errno)); return (-1); } - argv[0] = "create"; - argv[1] = filename; - argv[2] = "-s"; - argv[3] = COLLECTD_STEP; - - j = 4; + fprintf (log, "epoch"); for (i = 0; i < ds_num; i++) - argv[j++] = ds_def[i]; - for (i = 0; i < rra_num; i++) - argv[j++] = rra_def[i]; - argv[j] = NULL; - - optind = 0; /* bug in librrd? */ - rrd_clear_error (); - if (rrd_create (argc, argv) == -1) { - syslog (LOG_ERR, "rrd_create failed: %s: %s", filename, rrd_get_error ()); - status = -1; + char *name; + char *tmp; + + name = strchr (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 = strchr (name, ':'); + if (tmp == NULL) + { + syslog (LOG_WARNING, "Invalid DS definition '%s' for %s", + ds_def[i], filename); + fclose(log); + remove(filename); + return (-1); + } + + /* The `%.*s' is needed because there is no null-byte behind + * the name. */ + fprintf(log, ",%.*s", (int) (tmp - name), name); } + fprintf(log, "\n"); + fclose(log); - free (argv); - - return (status); + return 0; } -#endif /* HAVE_LIBRRD */ -int rrd_update_file (char *host, char *file, char *values, +int log_update_file (char *host, char *file, char *values, char **ds_def, int ds_num) { -#ifdef HAVE_LIBRRD + char *tmp; + FILE *fp; struct stat statbuf; char full_file[1024]; - char *argv[4] = { "update", full_file, values, NULL }; + + /* Cook the values a bit: Substitute colons with commas */ + strsubstitute (values, ':', ','); /* host == NULL => local mode */ if (host != NULL) @@ -353,11 +463,35 @@ int rrd_update_file (char *host, char *file, char *values, return (-1); } + strncpy (full_file, file, 1024); + + tmp = full_file + strlen (full_file) - 4; + assert ((tmp != NULL) && (tmp > full_file)); + + /* Change the filename for logfiles. */ + if (strncmp (tmp, ".rrd", 4) == 0) + { + time_t now; + struct tm *tm; + + /* TODO: Find a way to minimize the calls to `localtime', since + * they are pretty expensive.. */ + 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 (rrd_create_file (full_file, ds_def, ds_num)) + if (log_create_file (full_file, ds_def, ds_num)) return (-1); } else @@ -372,17 +506,20 @@ int rrd_update_file (char *host, char *file, char *values, return (-1); } - optind = 0; /* bug in librrd? */ - rrd_clear_error (); - if (rrd_update (3, argv) == -1) + + fp = fopen (full_file, "a"); + if (fp == NULL) { - syslog (LOG_WARNING, "rrd_update failed: %s: %s", full_file, rrd_get_error ()); + syslog (LOG_WARNING, "Failed to append to %s: %s", full_file, + strerror(errno)); return (-1); } -#endif /* HAVE_LIBRRD */ + fprintf(fp, "%s\n", values); + fclose(fp); return (0); -} +} /* int log_update_file */ + #ifdef HAVE_LIBKSTAT int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name) @@ -469,3 +606,21 @@ long long get_kstat_value (kstat_t *ksp, char *name) return (retval); } #endif /* HAVE_LIBKSTAT */ + +unsigned long long ntohll (unsigned long long n) +{ +#if __BYTE_ORDER == __BIG_ENDIAN + return (n); +#else + return (((unsigned long long) ntohl (n)) << 32) + ntohl (n >> 32); +#endif +} + +unsigned long long htonll (unsigned long long n) +{ +#if __BYTE_ORDER == __BIG_ENDIAN + return (n); +#else + return (((unsigned long long) htonl (n)) << 32) + htonl (n >> 32); +#endif +}