Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/ltf.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltf.c')
-rw-r--r--ltf.c355
1 files changed, 355 insertions, 0 deletions
diff --git a/ltf.c b/ltf.c
new file mode 100644
index 0000000..b185495
--- /dev/null
+++ b/ltf.c
@@ -0,0 +1,355 @@
+/* Copyright (C) 1997-2005 Luke Howard.
+ This file is part of the nss_ldap library.
+ Contributed by Luke Howard, <lukeh@padl.com>, 1997.
+
+ The nss_ldap library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The nss_ldap library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the nss_ldap library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+static char rcsId[] = "$Id: ltf.c,v 2.29 2005/05/20 05:30:42 lukeh Exp $";
+
+#include "config.h"
+
+#ifdef HAVE_PORT_BEFORE_H
+#include <port_before.h>
+#endif
+
+#if defined(HAVE_THREAD_H) && !defined(_AIX)
+#include <thread.h>
+#elif defined(HAVE_PTHREAD_H)
+#include <pthread.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef HAVE_LBER_H
+#include <lber.h>
+#endif
+#ifdef HAVE_LDAP_H
+#include <ldap.h>
+#endif
+
+#include "ldap-nss.h"
+
+#if defined(LDAP_OPT_THREAD_FN_PTRS) && (defined(HAVE_THREAD_H) || defined(HAVE_PTHREAD_H))
+
+static void *ltf_mutex_alloc (void);
+static void ltf_mutex_free (void *m);
+static NSS_STATUS ltf_tsd_setup (void);
+static void ltf_set_ld_error (int err, char *matched, char *errmsg,
+ void *dummy);
+static int ltf_get_ld_error (char **matched, char **errmsg, void *dummy);
+static void ltf_set_errno (int err);
+static int ltf_get_errno (void);
+
+#ifndef HAVE_THREAD_H /* thus, pthreads */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL. You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ *
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All Rights
+ * Reserved.
+ */
+
+static int ltf_mutex_lock (void *);
+static int ltf_mutex_unlock (void *);
+
+static pthread_key_t key;
+
+NSS_STATUS _nss_ldap_ltf_thread_init (LDAP * ld)
+{
+ struct ldap_thread_fns tfns;
+
+ /* set mutex pointers */
+ memset (&tfns, '\0', sizeof (struct ldap_thread_fns));
+ tfns.ltf_mutex_alloc = ltf_mutex_alloc;
+ tfns.ltf_mutex_free = ltf_mutex_free;
+ tfns.ltf_mutex_lock = ltf_mutex_lock;
+ tfns.ltf_mutex_unlock = ltf_mutex_unlock;
+ tfns.ltf_get_errno = ltf_get_errno;
+ tfns.ltf_set_errno = ltf_set_errno;
+ tfns.ltf_get_lderrno = ltf_get_ld_error;
+ tfns.ltf_set_lderrno = ltf_set_ld_error;
+ tfns.ltf_lderrno_arg = NULL;
+ /* set ld_errno pointers */
+ if (ldap_set_option (ld, LDAP_OPT_THREAD_FN_PTRS, (void *) &tfns) != 0)
+ {
+ return NSS_UNAVAIL;
+ }
+
+ return ltf_tsd_setup ();
+}
+
+static void *
+ltf_mutex_alloc (void)
+{
+ pthread_mutex_t *mutexp;
+
+ if ((mutexp = malloc (sizeof (pthread_mutex_t))) != NULL)
+ {
+ pthread_mutex_init (mutexp, NULL);
+ }
+
+ return (mutexp);
+}
+
+static void
+ltf_mutex_free (void *mutexp)
+{
+ pthread_mutex_destroy ((pthread_mutex_t *) mutexp);
+}
+
+static int
+ltf_mutex_lock (void *mutexp)
+{
+#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H)
+ return __libc_lock_lock (*(pthread_mutex_t *) mutexp);
+#elif defined(HPUX)
+ return __thread_mutex_lock ((pthread_mutex_t *) mutexp);
+#else
+# ifdef _AIX
+ if (__multi_threaded == 0)
+ return 0;
+# endif
+ return pthread_mutex_lock ((pthread_mutex_t *) mutexp);
+#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */
+}
+
+static int
+ltf_mutex_unlock (void *mutexp)
+{
+#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H)
+ return __libc_lock_unlock (*(pthread_mutex_t *) mutexp);
+#elif defined(HPUX)
+ return __thread_mutex_unlock ((pthread_mutex_t *) mutexp);
+#else
+# ifdef _AIX
+ if (__multi_threaded == 0)
+ return 0;
+# endif
+ return pthread_mutex_unlock ((pthread_mutex_t *) mutexp);
+#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */
+}
+
+static NSS_STATUS
+ltf_tsd_setup (void)
+{
+ void *tsd;
+
+#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H)
+ if (__libc_key_create (&key, free) != 0)
+ {
+ return NSS_UNAVAIL;
+ }
+ tsd = (void *) calloc (1, sizeof (struct ldap_error));
+ __libc_setspecific (key, tsd);
+#else
+ if (pthread_key_create (&key, free) != 0)
+ {
+ return NSS_UNAVAIL;
+ }
+ tsd = pthread_getspecific (key);
+ if (tsd != NULL)
+ {
+ pthread_exit (NULL);
+ }
+ tsd = (void *) calloc (1, sizeof (struct ldap_error));
+ pthread_setspecific (key, tsd);
+#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */
+
+ return NSS_SUCCESS;
+}
+
+static void
+ltf_set_ld_error (int err, char *matched, char *errmsg, void *dummy)
+{
+ struct ldap_error *le;
+
+#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H)
+ le = __libc_getspecific (key);
+#else
+ le = pthread_getspecific (key);
+#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */
+
+ le->le_errno = err;
+
+ if (le->le_matched != NULL)
+ ldap_memfree (le->le_matched);
+ le->le_matched = matched;
+
+ if (le->le_errmsg != NULL)
+ ldap_memfree (le->le_errmsg);
+ le->le_errmsg = errmsg;
+}
+
+static int
+ltf_get_ld_error (char **matched, char **errmsg, void *dummy)
+{
+ struct ldap_error *le;
+
+#if defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H)
+ le = __libc_getspecific (key);
+#else
+ le = pthread_getspecific (key);
+#endif /* HAVE_LIBC_LOCK_H || HAVE_BITS_LIBC_LOCK_H */
+ if (le == NULL)
+ return LDAP_LOCAL_ERROR;
+
+ if (matched != NULL)
+ *matched = le->le_matched;
+
+ if (errmsg != NULL)
+ *errmsg = le->le_errmsg;
+
+ return (le->le_errno);
+}
+
+static void
+ltf_set_errno (int err)
+{
+ errno = err;
+}
+
+static int
+ltf_get_errno (void)
+{
+ return (errno);
+}
+#else
+static thread_key_t ltf_key = 0;
+
+static void *
+ltf_mutex_alloc (void)
+{
+ mutex_t *m;
+
+ m = (mutex_t *) malloc (sizeof (*m));
+ if (m == NULL)
+ return NULL;
+
+ if (mutex_init (m, USYNC_THREAD, NULL) < 0)
+ return NULL;
+
+ return m;
+}
+
+static void
+ltf_mutex_free (void *m)
+{
+ mutex_destroy ((mutex_t *) m);
+/* free(m); */
+}
+
+void
+ltf_destr (void *tsd)
+{
+ free (tsd);
+}
+
+static NSS_STATUS
+ltf_tsd_setup (void)
+{
+ void *tsd;
+
+ (void) thr_keycreate (&ltf_key, ltf_destr);
+ tsd = (void *) calloc (1, sizeof (ldap_error_t));
+ thr_setspecific (ltf_key, tsd);
+ return NSS_SUCCESS;
+}
+
+static void
+ltf_set_ld_error (int err, char *matched, char *errmsg, void *dummy)
+{
+ ldap_error_t *le;
+
+ (void) thr_getspecific (ltf_key, (void **) &le);
+ if (le == NULL)
+ return;
+
+ le->le_errno = err;
+
+ if (le->le_matched != NULL)
+ ldap_memfree (le->le_matched);
+ le->le_matched = matched;
+
+ if (le->le_errmsg != NULL)
+ ldap_memfree (le->le_errmsg);
+ le->le_errmsg = errmsg;
+}
+
+static int
+ltf_get_ld_error (char **matched, char **errmsg, void *dummy)
+{
+ ldap_error_t *le = NULL;
+
+ (void) thr_getspecific (ltf_key, (void **) &le);
+ if (le == NULL)
+ return LDAP_LOCAL_ERROR;
+
+ if (matched != NULL)
+ *matched = le->le_matched;
+
+ if (errmsg != NULL)
+ *errmsg = le->le_errmsg;
+
+ return le->le_errno;
+}
+
+static void
+ltf_set_errno (int err)
+{
+ errno = err;
+}
+
+static int
+ltf_get_errno (void)
+{
+ return errno;
+}
+
+NSS_STATUS _nss_ldap_ltf_thread_init (LDAP * ld)
+{
+ struct ldap_thread_fns tfns;
+
+ memset (&tfns, '\0', sizeof (tfns));
+ tfns.ltf_mutex_alloc = ltf_mutex_alloc;
+ tfns.ltf_mutex_free = ltf_mutex_free;
+ tfns.ltf_mutex_lock = (int (*)(void *)) mutex_lock;
+ tfns.ltf_mutex_unlock = (int (*)(void *)) mutex_unlock;
+ tfns.ltf_get_errno = ltf_get_errno;
+ tfns.ltf_set_errno = ltf_set_errno;
+ tfns.ltf_get_lderrno = ltf_get_ld_error;
+ tfns.ltf_set_lderrno = ltf_set_ld_error;
+ tfns.ltf_lderrno_arg = NULL;
+
+ if (ldap_set_option (ld, LDAP_OPT_THREAD_FN_PTRS, (void *) &tfns) != 0)
+ return NSS_UNAVAIL;
+
+ return ltf_tsd_setup ();
+}
+#endif /* !HAVE_THREAD_H */
+#endif /* LDAP_OPT_THREAD_FN_PTRS */