Impelemt an own version of `getpwnam_r'.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sat, 30 Jun 2007 21:22:41 +0000 (23:22 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sat, 30 Jun 2007 21:22:41 +0000 (23:22 +0200)
Since OpenBSD doesn't provide a threadsafe version itself, we need to provide
it in this case.. :/

configure.in
src/common.c
src/common.h

index 692dc5b..9596cec 100644 (file)
@@ -418,6 +418,9 @@ AC_CHECK_FUNCS(strchr memcpy strstr strcmp strncmp strncpy strlen)
 AC_CHECK_FUNCS(strncasecmp strcasecmp)
 AC_CHECK_FUNCS(openlog syslog closelog)
 
+AC_CHECK_FUNCS(getpwnam_r)
+AC_CHECK_FUNCS(getgrnam_r)
+
 socket_needs_socket="no"
 AC_CHECK_FUNCS(socket, [], AC_CHECK_LIB(socket, socket, [socket_needs_socket="yes"], AC_MSG_ERROR(cannot find socket)))
 AM_CONDITIONAL(BUILD_WITH_LIBSOCKET, test "x$socket_needs_socket" = "xyes")
@@ -444,10 +447,6 @@ AC_CHECK_FUNCS(thread_info)
 # For users module
 AC_CHECK_FUNCS(getutent getutxent)
 
-# For quota module
-AC_CHECK_FUNCS(quotactl)
-AC_CHECK_FUNCS(getgrgid getpwuid)
-
 # For interface module
 AC_CHECK_FUNCS(getifaddrs)
 
index 1addb32..6333ab7 100644 (file)
 #include "common.h"
 #include "plugin.h"
 
+#if HAVE_PTHREAD_H
+# include <pthread.h>
+#endif
+
 #ifdef HAVE_MATH_H
-#  include <math.h>
+# include <math.h>
 #endif
 
 /* for ntohl and htonl */
 extern kstat_ctl_t *kc;
 #endif
 
+#if !HAVE_GETPWNAM_R
+static pthread_mutex_t getpwnam_r_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
 void sstrncpy (char *d, const char *s, int len)
 {
        strncpy (d, s, len);
@@ -643,3 +651,55 @@ 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;
+
+               *pwbufp = pwbuf;
+       } while (0);
+
+       pthread_mutex_unlock (&getpwnam_r_lock);
+
+       return (status);
+} /* int getpwnam_r */
+#endif
index b07db9d..f12b5e4 100644 (file)
 #include "collectd.h"
 #include "plugin.h"
 
+#if HAVE_PWD_H
+# include <pwd.h>
+#endif
+
 #define sfree(ptr) \
        if((ptr) != NULL) { \
                free(ptr); \
@@ -172,4 +176,9 @@ int parse_identifier (char *str, char **ret_host,
                char **ret_type, char **ret_type_instance);
 int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds);
 
+#if !HAVE_GETPWNAM_R
+int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf,
+               size_t buflen, struct passwd **pwbufp);
+#endif
+
 #endif /* COMMON_H */