Merge branch 'collectd-4.4' into collectd-4.5
[collectd.git] / src / common.c
index f93cf76..119d284 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/common.c
- * Copyright (C) 2005-2007  Florian octo Forster
+ * Copyright (C) 2005-2008  Florian octo Forster
  *
  * 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
@@ -24,6 +24,7 @@
 # include "config.h"
 #endif
 
+#include "collectd.h"
 #include "common.h"
 #include "plugin.h"
 
@@ -52,11 +53,26 @@ static pthread_mutex_t getpwnam_r_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t strerror_r_lock = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
-void sstrncpy (char *d, const char *s, int len)
+char *sstrncpy (char *dest, const char *src, size_t n)
 {
-       strncpy (d, s, len);
-       d[len - 1] = '\0';
-}
+       strncpy (dest, src, n);
+       dest[n - 1] = '\0';
+
+       return (dest);
+} /* char *sstrncpy */
+
+int ssnprintf (char *dest, size_t n, const char *format, ...)
+{
+       int ret = 0;
+       va_list ap;
+
+       va_start (ap, format);
+       ret = vsnprintf (dest, n, format, ap);
+       dest[n - 1] = '\0';
+       va_end (ap);
+
+       return (ret);
+} /* int ssnprintf */
 
 char *sstrdup (const char *s)
 {
@@ -67,12 +83,12 @@ char *sstrdup (const char *s)
 
        if((r = strdup (s)) == NULL)
        {
-               DEBUG ("Not enough memory.");
-               exit(3);
+               ERROR ("Not enough memory.");
+               exit (3);
        }
 
        return (r);
-}
+} /* char *sstrdup */
 
 /* Even though Posix requires "strerror_r" to return an "int",
  * some systems (e.g. the GNU libc) return a "char *" _and_
@@ -88,7 +104,7 @@ char *sstrerror (int errnum, char *buf, size_t buflen)
                pthread_mutex_lock (&strerror_r_lock);
 
                temp = strerror (errnum);
-               strncpy (buf, temp, buflen);
+               sstrncpy (buf, temp, buflen);
 
                pthread_mutex_unlock (&strerror_r_lock);
        }
@@ -101,9 +117,9 @@ char *sstrerror (int errnum, char *buf, size_t buflen)
                if (buf[0] == '\0')
                {
                        if ((temp != NULL) && (temp != buf) && (temp[0] != '\0'))
-                               strncpy (buf, temp, buflen);
+                               sstrncpy (buf, temp, buflen);
                        else
-                               strncpy (buf, "strerror_r did not return "
+                               sstrncpy (buf, "strerror_r did not return "
                                                "an error message", buflen);
                }
        }
@@ -112,13 +128,12 @@ char *sstrerror (int errnum, char *buf, size_t buflen)
 #else
        if (strerror_r (errnum, buf, buflen) != 0)
        {
-               snprintf (buf, buflen, "Error #%i; "
+               ssnprintf (buf, buflen, "Error #%i; "
                                "Additionally, strerror_r failed.",
                                errnum);
        }
 #endif /* STRERROR_R_CHAR_P */
 
-       buf[buflen - 1] = '\0';
        return (buf);
 } /* char *sstrerror */
 
@@ -128,12 +143,12 @@ void *smalloc (size_t size)
 
        if ((r = malloc (size)) == NULL)
        {
-               DEBUG("Not enough memory.");
-               exit(3);
+               ERROR ("Not enough memory.");
+               exit (3);
        }
 
-       return r;
-}
+       return (r);
+} /* void *smalloc */
 
 #if 0
 void sfree (void **ptr)
@@ -176,7 +191,7 @@ ssize_t sread (int fd, void *buf, size_t count)
                        return (-1);
                }
 
-               assert (nleft >= status);
+               assert ((0 > status) || (nleft >= (size_t)status));
 
                nleft = nleft - status;
                ptr   = ptr   + status;
@@ -221,7 +236,7 @@ int strsplit (char *string, char **fields, size_t size)
        i = 0;
        ptr = string;
        saveptr = NULL;
-       while ((fields[i] = strtok_r (ptr, " \t", &saveptr)) != NULL)
+       while ((fields[i] = strtok_r (ptr, " \t\r\n", &saveptr)) != NULL)
        {
                ptr = NULL;
                i++;
@@ -237,8 +252,8 @@ int strjoin (char *dst, size_t dst_len,
                char **fields, size_t fields_num,
                const char *sep)
 {
-       int field_len;
-       int sep_len;
+       size_t field_len;
+       size_t sep_len;
        int i;
 
        memset (dst, '\0', dst_len);
@@ -250,7 +265,7 @@ int strjoin (char *dst, size_t dst_len,
        if (sep != NULL)
                sep_len = strlen (sep);
 
-       for (i = 0; i < fields_num; i++)
+       for (i = 0; i < (int)fields_num; i++)
        {
                if ((i > 0) && (sep_len > 0))
                {
@@ -373,7 +388,7 @@ int check_create_dir (const char *file_orig)
 
        if ((len = strlen (file_orig)) < 1)
                return (-1);
-       else if (len >= 512)
+       else if (len >= sizeof (file_copy))
                return (-1);
 
        /*
@@ -388,8 +403,7 @@ int check_create_dir (const char *file_orig)
        /*
         * Create a copy for `strtok_r' to destroy
         */
-       strncpy (file_copy, file_orig, 512);
-       file_copy[511] = '\0';
+       sstrncpy (file_copy, file_orig, sizeof (file_copy));
 
        /*
         * Break into components. This will eat up several slashes in a row and
@@ -474,8 +488,7 @@ int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name)
        if (kc == NULL)
                return (-1);
 
-       snprintf (ident, 128, "%s,%i,%s", module, instance, name);
-       ident[127] = '\0';
+       ssnprintf (ident, sizeof (ident), "%s,%i,%s", module, instance, name);
 
        if (*ksp_ptr == NULL)
        {
@@ -524,12 +537,12 @@ long long get_kstat_value (kstat_t *ksp, char *name)
 #else
        if (ksp == NULL)
        {
-               fprintf (stderr, "ERROR: %s:%i: ksp == NULL\n", __FILE__, __LINE__);
+               ERROR ("ERROR: %s:%i: ksp == NULL\n", __FILE__, __LINE__);
                return (-1LL);
        }
        else if (ksp->ks_type != KSTAT_TYPE_NAMED)
        {
-               fprintf (stderr, "ERROR: %s:%i: ksp->ks_type != KSTAT_TYPE_NAMED\n", __FILE__, __LINE__);
+               ERROR ("ERROR: %s:%i: ksp->ks_type != KSTAT_TYPE_NAMED\n", __FILE__, __LINE__);
                return (-1LL);
        }
 #endif
@@ -554,7 +567,7 @@ long long get_kstat_value (kstat_t *ksp, char *name)
 
 unsigned long long ntohll (unsigned long long n)
 {
-#if __BYTE_ORDER == __BIG_ENDIAN
+#if BYTE_ORDER == BIG_ENDIAN
        return (n);
 #else
        return (((unsigned long long) ntohl (n)) << 32) + ntohl (n >> 32);
@@ -563,7 +576,7 @@ unsigned long long ntohll (unsigned long long n)
 
 unsigned long long htonll (unsigned long long n)
 {
-#if __BYTE_ORDER == __BIG_ENDIAN
+#if BYTE_ORDER == BIG_ENDIAN
        return (n);
 #else
        return (((unsigned long long) htonl (n)) << 32) + htonl (n >> 32);
@@ -660,21 +673,21 @@ int format_name (char *ret, int ret_len,
        if ((plugin_instance == NULL) || (strlen (plugin_instance) == 0))
        {
                if ((type_instance == NULL) || (strlen (type_instance) == 0))
-                       status = snprintf (ret, ret_len, "%s/%s/%s",
+                       status = ssnprintf (ret, ret_len, "%s/%s/%s",
                                        hostname, plugin, type);
                else
-                       status = snprintf (ret, ret_len, "%s/%s/%s-%s",
+                       status = ssnprintf (ret, ret_len, "%s/%s/%s-%s",
                                        hostname, plugin, type,
                                        type_instance);
        }
        else
        {
                if ((type_instance == NULL) || (strlen (type_instance) == 0))
-                       status = snprintf (ret, ret_len, "%s/%s-%s/%s",
+                       status = ssnprintf (ret, ret_len, "%s/%s-%s/%s",
                                        hostname, plugin, plugin_instance,
                                        type);
                else
-                       status = snprintf (ret, ret_len, "%s/%s-%s/%s-%s",
+                       status = ssnprintf (ret, ret_len, "%s/%s-%s/%s-%s",
                                        hostname, plugin, plugin_instance,
                                        type, type_instance);
        }
@@ -823,4 +836,87 @@ int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf,
 
        return (status);
 } /* int getpwnam_r */
-#endif
+#endif /* !HAVE_GETPWNAM_R */
+
+int notification_init (notification_t *n, int severity, const char *message,
+               const char *host,
+               const char *plugin, const char *plugin_instance,
+               const char *type, const char *type_instance)
+{
+       memset (n, '\0', sizeof (notification_t));
+
+       n->severity = severity;
+
+       if (message != NULL)
+               sstrncpy (n->message, message, sizeof (n->message));
+       if (host != NULL)
+               sstrncpy (n->host, host, sizeof (n->host));
+       if (plugin != NULL)
+               sstrncpy (n->plugin, plugin, sizeof (n->plugin));
+       if (plugin_instance != NULL)
+               sstrncpy (n->plugin_instance, plugin_instance,
+                               sizeof (n->plugin_instance));
+       if (type != NULL)
+               sstrncpy (n->type, type, sizeof (n->type));
+       if (type_instance != NULL)
+               sstrncpy (n->type_instance, type_instance,
+                               sizeof (n->type_instance));
+
+       return (0);
+} /* int notification_init */
+
+int walk_directory (const char *dir, dirwalk_callback_f callback,
+               void *user_data)
+{
+       struct dirent *ent;
+       DIR *dh;
+       int success;
+       int failure;
+
+       success = 0;
+       failure = 0;
+
+       if ((dh = opendir (dir)) == NULL)
+       {
+               char errbuf[1024];
+               ERROR ("walk_directory: Cannot open '%s': %s", dir,
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               return -1;
+       }
+
+       while ((ent = readdir (dh)) != NULL)
+       {
+               int status;
+
+               if (ent->d_name[0] == '.')
+                       continue;
+
+               status = (*callback) (dir, ent->d_name, user_data);
+               if (status != 0)
+                       failure++;
+               else
+                       success++;
+       }
+
+       closedir (dh);
+
+       if ((success == 0) && (failure > 0))
+               return (-1);
+       return (0);
+}
+
+int read_file_contents (const char *filename, char *buf, int bufsize)
+{
+       FILE *fh;
+       int n;
+
+       if ((fh = fopen (filename, "r")) == NULL)
+               return -1;
+
+       n = fread(buf, 1, bufsize, fh);
+       fclose(fh);
+
+       return n;
+}
+
+