X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fcommon.c;h=e8050412b022e7c59dd7b9fef37d85991ea012bf;hb=d35dd47646956b011a75084a979fd7850cea9a6b;hp=1addb323673814a5d8375f3114efaa654fa652f5;hpb=6c9f69a4507e2ec9490e2baf76146f4036aa2b8e;p=collectd.git diff --git a/src/common.c b/src/common.c index 1addb323..e8050412 100644 --- a/src/common.c +++ b/src/common.c @@ -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 @@ -27,8 +27,12 @@ #include "common.h" #include "plugin.h" +#if HAVE_PTHREAD_H +# include +#endif + #ifdef HAVE_MATH_H -# include +# include #endif /* for ntohl and htonl */ @@ -40,6 +44,14 @@ extern kstat_ctl_t *kc; #endif +#if !HAVE_GETPWNAM_R +static pthread_mutex_t getpwnam_r_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + +#if !HAVE_STRERROR_R +static pthread_mutex_t strerror_r_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + void sstrncpy (char *d, const char *s, int len) { strncpy (d, s, len); @@ -62,12 +74,51 @@ char *sstrdup (const char *s) return (r); } -/* Don't use the return value of `strerror_r', because the GNU-people got - * inventive there.. -octo */ +/* Even though Posix requires "strerror_r" to return an "int", + * some systems (e.g. the GNU libc) return a "char *" _and_ + * ignore the second argument ... -tokkee */ char *sstrerror (int errnum, char *buf, size_t buflen) { buf[0] = '\0'; - strerror_r (errnum, buf, buflen); + +#if !HAVE_STRERROR_R + { + char *temp; + + pthread_mutex_lock (&strerror_r_lock); + + temp = strerror (errnum); + strncpy (buf, temp, buflen); + + pthread_mutex_unlock (&strerror_r_lock); + } +/* #endif !HAVE_STRERROR_R */ + +#elif STRERROR_R_CHAR_P + { + char *temp; + temp = strerror_r (errnum, buf, buflen); + if (buf[0] == '\0') + { + if ((temp != NULL) && (temp != buf) && (temp[0] != '\0')) + strncpy (buf, temp, buflen); + else + strncpy (buf, "strerror_r did not return " + "an error message", buflen); + } + } +/* #endif STRERROR_R_CHAR_P */ + +#else + if (strerror_r (errnum, buf, buflen) != 0) + { + snprintf (buf, buflen, "Error #%i; " + "Additionally, strerror_r failed.", + errnum); + } +#endif /* STRERROR_R_CHAR_P */ + + buf[buflen - 1] = '\0'; return (buf); } /* char *sstrerror */ @@ -125,7 +176,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; @@ -186,8 +237,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); @@ -199,7 +250,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)) { @@ -390,7 +441,7 @@ int check_create_dir (const char *file_orig) if (mkdir (dir, 0755) == -1) { char errbuf[1024]; - ERROR ("mkdir (%s): %s", dir, + ERROR ("check_create_dir: mkdir (%s): %s", dir, sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); @@ -413,7 +464,7 @@ int check_create_dir (const char *file_orig) } return (0); -} +} /* check_create_dir */ #ifdef HAVE_LIBKSTAT int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name) @@ -643,3 +694,90 @@ int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds) return (-1); return (0); } /* int parse_values */ + +#if !HAVE_GETPWNAM_R +int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf, + size_t buflen, struct passwd **pwbufp) +{ + int status = 0; + struct passwd *pw; + + memset (pwbuf, '\0', sizeof (struct passwd)); + + pthread_mutex_lock (&getpwnam_r_lock); + + do + { + pw = getpwnam (name); + if (pw == NULL) + { + status = (errno != 0) ? errno : ENOENT; + break; + } + +#define GETPWNAM_COPY_MEMBER(member) \ + if (pw->member != NULL) \ + { \ + int len = strlen (pw->member); \ + if (len >= buflen) \ + { \ + status = ENOMEM; \ + break; \ + } \ + sstrncpy (buf, pw->member, buflen); \ + pwbuf->member = buf; \ + buf += (len + 1); \ + buflen -= (len + 1); \ + } + GETPWNAM_COPY_MEMBER(pw_name); + GETPWNAM_COPY_MEMBER(pw_passwd); + GETPWNAM_COPY_MEMBER(pw_gecos); + GETPWNAM_COPY_MEMBER(pw_dir); + GETPWNAM_COPY_MEMBER(pw_shell); + + pwbuf->pw_uid = pw->pw_uid; + pwbuf->pw_gid = pw->pw_gid; + + if (pwbufp != NULL) + *pwbufp = pwbuf; + } while (0); + + pthread_mutex_unlock (&getpwnam_r_lock); + + return (status); +} /* int getpwnam_r */ +#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) + strncpy (n->message, message, sizeof (n->message)); + if (host != NULL) + strncpy (n->host, host, sizeof (n->host)); + if (plugin != NULL) + strncpy (n->plugin, plugin, sizeof (n->plugin)); + if (plugin_instance != NULL) + strncpy (n->plugin_instance, plugin_instance, + sizeof (n->plugin_instance)); + if (type != NULL) + strncpy (n->type, type, sizeof (n->type)); + if (type_instance != NULL) + strncpy (n->type_instance, type_instance, + sizeof (n->type_instance)); + + n->message[sizeof (n->message) - 1] = '\0'; + n->host[sizeof (n->host) - 1] = '\0'; + n->plugin[sizeof (n->plugin) - 1] = '\0'; + n->plugin_instance[sizeof (n->plugin_instance) - 1] = '\0'; + n->type[sizeof (n->type) - 1] = '\0'; + n->type_instance[sizeof (n->type_instance) - 1] = '\0'; + + return (0); +} /* int notification_init */