mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-14 03:30:17 +01:00
622 lines
16 KiB
C
622 lines
16 KiB
C
|
/* ***** BEGIN LICENSE BLOCK *****
|
||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||
|
*
|
||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||
|
* the License. You may obtain a copy of the License at
|
||
|
* http://www.mozilla.org/MPL/
|
||
|
*
|
||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||
|
* for the specific language governing rights and limitations under the
|
||
|
* License.
|
||
|
*
|
||
|
* The Original Code is Mozilla Communicator client code, released
|
||
|
* March 31, 1998.
|
||
|
*
|
||
|
* The Initial Developer of the Original Code is
|
||
|
* Netscape Communications Corporation.
|
||
|
* Portions created by the Initial Developer are Copyright (C) 1998-1999
|
||
|
* the Initial Developer. All Rights Reserved.
|
||
|
*
|
||
|
* Contributor(s):
|
||
|
*
|
||
|
* Alternatively, the contents of this file may be used under the terms of
|
||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||
|
* of those above. If you wish to allow use of your version of this file only
|
||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||
|
* use your version of this file under the terms of the MPL, indicate your
|
||
|
* decision by deleting the provisions above and replace them with the notice
|
||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||
|
* the provisions above, a recipient may use your version of this file under
|
||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||
|
*
|
||
|
* ***** END LICENSE BLOCK ***** */
|
||
|
#include <nspr.h>
|
||
|
#include <stdio.h>
|
||
|
#include <ldap.h>
|
||
|
|
||
|
#define NAME "cn=Directory Manager"
|
||
|
#define PASSWORD "secret99"
|
||
|
#define BASE "dc=example,dc=com"
|
||
|
|
||
|
static int simplebind( LDAP *ld, char *msg, int tries );
|
||
|
static void search_thread( void * );
|
||
|
static void modify_thread( void * );
|
||
|
static void add_thread( void * );
|
||
|
static void delete_thread( void * );
|
||
|
static void set_ld_error();
|
||
|
static int get_ld_error();
|
||
|
static void set_errno();
|
||
|
static int get_errno();
|
||
|
static void tsd_setup();
|
||
|
static void *my_mutex_alloc( void );
|
||
|
static void my_mutex_free( void * );
|
||
|
static int my_mutex_lock( void * );
|
||
|
static int my_mutex_unlock( void * );
|
||
|
static LDAPHostEnt *my_gethostbyname( const char *name, LDAPHostEnt *result,
|
||
|
char *buffer, int buflen, int *statusp, void *extradata );
|
||
|
static LDAPHostEnt *my_gethostbyaddr( const char *addr, int length,
|
||
|
int type, LDAPHostEnt *result, char *buffer, int buflen,
|
||
|
int *statusp, void *extradata );
|
||
|
static LDAPHostEnt *copyPRHostEnt2LDAPHostEnt( LDAPHostEnt *ldhp,
|
||
|
PRHostEnt *prhp );
|
||
|
|
||
|
typedef struct ldapmsgwrapper {
|
||
|
LDAPMessage *lmw_messagep;
|
||
|
struct ldapmsgwrapper *lmw_next;
|
||
|
} ldapmsgwrapper;
|
||
|
|
||
|
|
||
|
#define CONNECTION_ERROR( lderr ) ( (lderr) == LDAP_SERVER_DOWN || \
|
||
|
(lderr) == LDAP_CONNECT_ERROR )
|
||
|
|
||
|
|
||
|
LDAP *ld;
|
||
|
PRUintn tsdindex;
|
||
|
#ifdef LDAP_MEMCACHE
|
||
|
LDAPMemCache *memcache = NULL;
|
||
|
#define MEMCACHE_SIZE (256*1024) /* 256K bytes */
|
||
|
#define MEMCACHE_TTL (15*60) /* 15 minutes */
|
||
|
#endif
|
||
|
|
||
|
|
||
|
main( int argc, char **argv )
|
||
|
{
|
||
|
PRThread *search_tid, *search_tid2, *search_tid3;
|
||
|
PRThread *search_tid4, *modify_tid, *add_tid;
|
||
|
PRThread *delete_tid;
|
||
|
struct ldap_thread_fns tfns;
|
||
|
struct ldap_dns_fns dnsfns;
|
||
|
int rc;
|
||
|
|
||
|
if ( argc != 3 ) {
|
||
|
fprintf( stderr, "usage: %s host port\n", argv[0] );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 0 );
|
||
|
if ( PR_NewThreadPrivateIndex( &tsdindex, NULL ) != PR_SUCCESS ) {
|
||
|
perror( "PR_NewThreadPrivateIndex" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
tsd_setup(); /* for main thread */
|
||
|
|
||
|
if ( (ld = ldap_init( argv[1], atoi( argv[2] ) )) == NULL ) {
|
||
|
perror( "ldap_open" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
/* set thread function pointers */
|
||
|
memset( &tfns, '\0', sizeof(struct ldap_thread_fns) );
|
||
|
tfns.ltf_mutex_alloc = my_mutex_alloc;
|
||
|
tfns.ltf_mutex_free = my_mutex_free;
|
||
|
tfns.ltf_mutex_lock = my_mutex_lock;
|
||
|
tfns.ltf_mutex_unlock = my_mutex_unlock;
|
||
|
tfns.ltf_get_errno = get_errno;
|
||
|
tfns.ltf_set_errno = set_errno;
|
||
|
tfns.ltf_get_lderrno = get_ld_error;
|
||
|
tfns.ltf_set_lderrno = set_ld_error;
|
||
|
tfns.ltf_lderrno_arg = NULL;
|
||
|
if ( ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS, (void *) &tfns )
|
||
|
!= 0 ) {
|
||
|
ldap_perror( ld, "ldap_set_option: thread functions" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
/* set DNS function pointers */
|
||
|
memset( &dnsfns, '\0', sizeof(struct ldap_dns_fns) );
|
||
|
dnsfns.lddnsfn_bufsize = PR_NETDB_BUF_SIZE;
|
||
|
dnsfns.lddnsfn_gethostbyname = my_gethostbyname;
|
||
|
dnsfns.lddnsfn_gethostbyaddr = my_gethostbyaddr;
|
||
|
if ( ldap_set_option( ld, LDAP_OPT_DNS_FN_PTRS, (void *)&dnsfns )
|
||
|
!= 0 ) {
|
||
|
ldap_perror( ld, "ldap_set_option: DNS functions" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
#ifdef LDAP_MEMCACHE
|
||
|
/* create the in-memory cache */
|
||
|
if (( rc = ldap_memcache_init( MEMCACHE_TTL, MEMCACHE_SIZE, NULL,
|
||
|
&tfns, &memcache )) != LDAP_SUCCESS ) {
|
||
|
fprintf( stderr, "ldap_memcache_init failed - %s\n",
|
||
|
ldap_err2string( rc ));
|
||
|
exit( 1 );
|
||
|
}
|
||
|
if (( rc = ldap_memcache_set( ld, memcache )) != LDAP_SUCCESS ) {
|
||
|
fprintf( stderr, "ldap_memcache_set failed - %s\n",
|
||
|
ldap_err2string( rc ));
|
||
|
exit( 1 );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* set option so that the next call to ldap_simple_bind_s() after
|
||
|
* the server connection is lost will attempt to reconnect.
|
||
|
*/
|
||
|
if ( ldap_set_option( ld, LDAP_OPT_RECONNECT, LDAP_OPT_ON ) != 0 ) {
|
||
|
ldap_perror( ld, "ldap_set_option: reconnect" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
/* initial bind */
|
||
|
if ( simplebind( ld, "ldap_simple_bind_s/main", 1 ) != LDAP_SUCCESS ) {
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
/* create the operation threads */
|
||
|
if ( (search_tid = PR_CreateThread( PR_USER_THREAD, search_thread,
|
||
|
"1", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
|
||
|
0 )) == NULL ) {
|
||
|
perror( "PR_CreateThread search_thread" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
if ( (modify_tid = PR_CreateThread( PR_USER_THREAD, modify_thread,
|
||
|
"2", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
|
||
|
0 )) == NULL ) {
|
||
|
perror( "PR_CreateThread modify_thread" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
if ( (search_tid2 = PR_CreateThread( PR_USER_THREAD, search_thread,
|
||
|
"3", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
|
||
|
0 )) == NULL ) {
|
||
|
perror( "PR_CreateThread search_thread 2" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
if ( (add_tid = PR_CreateThread( PR_USER_THREAD, add_thread,
|
||
|
"4", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
|
||
|
0 )) == NULL ) {
|
||
|
perror( "PR_CreateThread add_thread" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
if ( (search_tid3 = PR_CreateThread( PR_USER_THREAD, search_thread,
|
||
|
"5", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
|
||
|
0 )) == NULL ) {
|
||
|
perror( "PR_CreateThread search_thread 3" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
if ( (delete_tid = PR_CreateThread( PR_USER_THREAD, delete_thread,
|
||
|
"6", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
|
||
|
0 )) == NULL ) {
|
||
|
perror( "PR_CreateThread delete_thread" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
if ( (search_tid4 = PR_CreateThread( PR_USER_THREAD, search_thread,
|
||
|
"7", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
|
||
|
0 )) == NULL ) {
|
||
|
perror( "PR_CreateThread search_thread 4" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
PR_Cleanup();
|
||
|
return( 0 );
|
||
|
}
|
||
|
|
||
|
|
||
|
static int
|
||
|
simplebind( LDAP *ld, char *msg, int tries )
|
||
|
{
|
||
|
int rc;
|
||
|
|
||
|
while ( tries-- > 0 ) {
|
||
|
rc = ldap_simple_bind_s( ld, NAME, PASSWORD );
|
||
|
if ( rc != LDAP_SUCCESS ) {
|
||
|
ldap_perror( ld, msg );
|
||
|
}
|
||
|
if ( tries == 0 || !CONNECTION_ERROR( rc )) {
|
||
|
return( rc );
|
||
|
}
|
||
|
fprintf( stderr,
|
||
|
"%s: sleeping for 5 secs - will try %d more time(s)...\n",
|
||
|
msg, tries );
|
||
|
sleep( 5 );
|
||
|
}
|
||
|
|
||
|
return( rc );
|
||
|
}
|
||
|
|
||
|
|
||
|
static void
|
||
|
search_thread( void *arg1 )
|
||
|
{
|
||
|
LDAPMessage *res;
|
||
|
LDAPMessage *e;
|
||
|
char *a;
|
||
|
char **v;
|
||
|
char *dn;
|
||
|
BerElement *ber;
|
||
|
int i, rc, msgid;
|
||
|
void *tsd;
|
||
|
char *id = arg1;
|
||
|
|
||
|
printf( "search_thread\n" );
|
||
|
tsd_setup();
|
||
|
for ( ;; ) {
|
||
|
printf( "%sSearching...\n", id );
|
||
|
if ( (msgid = ldap_search( ld, BASE, LDAP_SCOPE_SUBTREE,
|
||
|
"(objectclass=*)", NULL, 0 )) == -1 ) {
|
||
|
ldap_perror( ld, "ldap_search_s" );
|
||
|
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||
|
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
|
||
|
"bind-search_thread", 5 ) != LDAP_SUCCESS ) {
|
||
|
return;
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
while ( (rc = ldap_result( ld, msgid, 0, NULL, &res ))
|
||
|
== LDAP_RES_SEARCH_ENTRY ) {
|
||
|
for ( e = ldap_first_entry( ld, res ); e != NULL;
|
||
|
e = ldap_next_entry( ld, e ) ) {
|
||
|
dn = ldap_get_dn( ld, e );
|
||
|
/* printf( "%sdn: %s\n", id, dn ); */
|
||
|
free( dn );
|
||
|
for ( a = ldap_first_attribute( ld, e, &ber );
|
||
|
a != NULL; a = ldap_next_attribute( ld, e,
|
||
|
ber ) ) {
|
||
|
v = ldap_get_values( ld, e, a );
|
||
|
for ( i = 0; v && v[i] != 0; i++ ) {
|
||
|
/*
|
||
|
printf( "%s%s: %s\n", id, a,
|
||
|
v[i] );
|
||
|
*/
|
||
|
}
|
||
|
ldap_value_free( v );
|
||
|
ldap_memfree( a );
|
||
|
}
|
||
|
if ( ber != NULL ) {
|
||
|
ber_free( ber, 0 );
|
||
|
}
|
||
|
}
|
||
|
ldap_msgfree( res );
|
||
|
/* printf( "%s\n", id ); */
|
||
|
}
|
||
|
|
||
|
if ( rc == -1 || ldap_result2error( ld, res, 0 ) !=
|
||
|
LDAP_SUCCESS ) {
|
||
|
ldap_perror( ld, "ldap_search" );
|
||
|
} else {
|
||
|
printf( "%sDone with one round\n", id );
|
||
|
}
|
||
|
|
||
|
if ( rc == -1 ) {
|
||
|
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||
|
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
|
||
|
"bind-search_thread", 5 ) != LDAP_SUCCESS ) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
modify_thread( void *arg1 )
|
||
|
{
|
||
|
LDAPMessage *res;
|
||
|
LDAPMessage *e;
|
||
|
int i, modentry, entries, msgid, rc;
|
||
|
LDAPMod mod;
|
||
|
LDAPMod *mods[2];
|
||
|
char *vals[2];
|
||
|
char *dn;
|
||
|
char *id = arg1;
|
||
|
ldapmsgwrapper *list, *lmwp, *lastlmwp;
|
||
|
|
||
|
printf( "modify_thread\n" );
|
||
|
tsd_setup();
|
||
|
if ( (msgid = ldap_search( ld, BASE, LDAP_SCOPE_SUBTREE,
|
||
|
"(objectclass=*)", NULL, 0 )) == -1 ) {
|
||
|
ldap_perror( ld, "ldap_search_s" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
entries = 0;
|
||
|
list = lastlmwp = NULL;
|
||
|
while ( (rc = ldap_result( ld, msgid, 0, NULL, &res ))
|
||
|
== LDAP_RES_SEARCH_ENTRY ) {
|
||
|
entries++;
|
||
|
if (( lmwp = (ldapmsgwrapper *)
|
||
|
malloc( sizeof( ldapmsgwrapper ))) == NULL ) {
|
||
|
perror( "modify_thread: malloc" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
lmwp->lmw_messagep = res;
|
||
|
lmwp->lmw_next = NULL;
|
||
|
if ( lastlmwp == NULL ) {
|
||
|
list = lastlmwp = lmwp;
|
||
|
} else {
|
||
|
lastlmwp->lmw_next = lmwp;
|
||
|
}
|
||
|
lastlmwp = lmwp;
|
||
|
}
|
||
|
if ( rc == -1 || ldap_result2error( ld, res, 0 ) != LDAP_SUCCESS ) {
|
||
|
ldap_perror( ld, "modify_thread: ldap_search" );
|
||
|
exit( 1 );
|
||
|
} else {
|
||
|
entries++;
|
||
|
printf( "%sModify got %d entries\n", id, entries );
|
||
|
}
|
||
|
|
||
|
mods[0] = &mod;
|
||
|
mods[1] = NULL;
|
||
|
vals[0] = "bar";
|
||
|
vals[1] = NULL;
|
||
|
for ( ;; ) {
|
||
|
modentry = rand() % entries;
|
||
|
for ( i = 0, lmwp = list; lmwp != NULL && i < modentry;
|
||
|
i++, lmwp = lmwp->lmw_next ) {
|
||
|
/* NULL */
|
||
|
}
|
||
|
|
||
|
if ( lmwp == NULL ) {
|
||
|
fprintf( stderr,
|
||
|
"%sModify could not find entry %d of %d\n",
|
||
|
id, modentry, entries );
|
||
|
continue;
|
||
|
}
|
||
|
e = lmwp->lmw_messagep;
|
||
|
printf( "%sPicked entry %d of %d\n", id, i, entries );
|
||
|
dn = ldap_get_dn( ld, e );
|
||
|
mod.mod_op = LDAP_MOD_REPLACE;
|
||
|
mod.mod_type = "description";
|
||
|
mod.mod_values = vals;
|
||
|
printf( "%sModifying (%s)\n", id, dn );
|
||
|
if (( rc = ldap_modify_s( ld, dn, mods )) != LDAP_SUCCESS ) {
|
||
|
ldap_perror( ld, "ldap_modify_s" );
|
||
|
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
|
||
|
"bind-modify_thread", 5 ) != LDAP_SUCCESS ) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
free( dn );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
add_thread( void *arg1 )
|
||
|
{
|
||
|
LDAPMod mod[5];
|
||
|
LDAPMod *mods[6];
|
||
|
char dn[BUFSIZ], name[40];
|
||
|
char *cnvals[2], *snvals[2], *ocvals[2];
|
||
|
int i, rc;
|
||
|
char *id = arg1;
|
||
|
|
||
|
printf( "add_thread\n" );
|
||
|
tsd_setup();
|
||
|
for ( i = 0; i < 5; i++ ) {
|
||
|
mods[i] = &mod[i];
|
||
|
}
|
||
|
mods[5] = NULL;
|
||
|
mod[0].mod_op = 0;
|
||
|
mod[0].mod_type = "cn";
|
||
|
mod[0].mod_values = cnvals;
|
||
|
cnvals[1] = NULL;
|
||
|
mod[1].mod_op = 0;
|
||
|
mod[1].mod_type = "sn";
|
||
|
mod[1].mod_values = snvals;
|
||
|
snvals[1] = NULL;
|
||
|
mod[2].mod_op = 0;
|
||
|
mod[2].mod_type = "objectclass";
|
||
|
mod[2].mod_values = ocvals;
|
||
|
ocvals[0] = "person";
|
||
|
ocvals[1] = NULL;
|
||
|
mods[3] = NULL;
|
||
|
|
||
|
for ( ;; ) {
|
||
|
sprintf( name, "%d", rand() );
|
||
|
sprintf( dn, "cn=%s, " BASE, name );
|
||
|
cnvals[0] = name;
|
||
|
snvals[0] = name;
|
||
|
|
||
|
printf( "%sAdding entry (%s)\n", id, dn );
|
||
|
if (( rc = ldap_add_s( ld, dn, mods )) != LDAP_SUCCESS ) {
|
||
|
ldap_perror( ld, "ldap_add_s" );
|
||
|
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
|
||
|
"bind-add_thread", 5 ) != LDAP_SUCCESS ) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
delete_thread( void *arg1 )
|
||
|
{
|
||
|
LDAPMessage *res;
|
||
|
char dn[BUFSIZ], name[40];
|
||
|
int entries, msgid, rc;
|
||
|
char *id = arg1;
|
||
|
|
||
|
printf( "delete_thread\n" );
|
||
|
tsd_setup();
|
||
|
if ( (msgid = ldap_search( ld, BASE, LDAP_SCOPE_SUBTREE,
|
||
|
"(objectclass=*)", NULL, 0 )) == -1 ) {
|
||
|
ldap_perror( ld, "delete_thread: ldap_search_s" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
entries = 0;
|
||
|
while ( (rc = ldap_result( ld, msgid, 0, NULL, &res ))
|
||
|
== LDAP_RES_SEARCH_ENTRY ) {
|
||
|
entries++;
|
||
|
ldap_msgfree( res );
|
||
|
}
|
||
|
entries++;
|
||
|
if ( rc == -1 || ldap_result2error( ld, res, 1 ) != LDAP_SUCCESS ) {
|
||
|
ldap_perror( ld, "delete_thread: ldap_search" );
|
||
|
} else {
|
||
|
printf( "%sDelete got %d entries\n", id, entries );
|
||
|
}
|
||
|
|
||
|
for ( ;; ) {
|
||
|
sprintf( name, "%d", rand() );
|
||
|
sprintf( dn, "cn=%s, " BASE, name );
|
||
|
|
||
|
printf( "%sDeleting entry (%s)\n", id, dn );
|
||
|
if (( rc = ldap_delete_s( ld, dn )) != LDAP_SUCCESS ) {
|
||
|
ldap_perror( ld, "ldap_delete_s" );
|
||
|
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
|
||
|
"bind-delete_thread", 5 ) != LDAP_SUCCESS ) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct ldap_error {
|
||
|
int le_errno;
|
||
|
char *le_matched;
|
||
|
char *le_errmsg;
|
||
|
};
|
||
|
|
||
|
static void
|
||
|
tsd_setup()
|
||
|
{
|
||
|
void *tsd;
|
||
|
|
||
|
tsd = (void *) PR_GetThreadPrivate( tsdindex );
|
||
|
if ( tsd != NULL ) {
|
||
|
fprintf( stderr, "tsd non-null!\n" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
tsd = (void *) calloc( 1, sizeof(struct ldap_error) );
|
||
|
if ( PR_SetThreadPrivate( tsdindex, tsd ) != 0 ) {
|
||
|
perror( "PR_SetThreadPrivate" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
set_ld_error( int err, char *matched, char *errmsg, void *dummy )
|
||
|
{
|
||
|
struct ldap_error *le;
|
||
|
|
||
|
le = (void *) PR_GetThreadPrivate( tsdindex );
|
||
|
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
|
||
|
get_ld_error( char **matchedp, char **errmsgp, void *dummy )
|
||
|
{
|
||
|
struct ldap_error *le;
|
||
|
|
||
|
le = PR_GetThreadPrivate( tsdindex );
|
||
|
if ( matchedp != NULL ) {
|
||
|
*matchedp = le->le_matched;
|
||
|
}
|
||
|
if ( errmsgp != NULL ) {
|
||
|
*errmsgp = le->le_errmsg;
|
||
|
}
|
||
|
return( le->le_errno );
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
set_errno( int oserrno )
|
||
|
{
|
||
|
/* XXXmcs: should this be PR_SetError( oserrno, 0 )? */
|
||
|
PR_SetError( PR_UNKNOWN_ERROR, oserrno );
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
get_errno( void )
|
||
|
{
|
||
|
/* XXXmcs: should this be PR_GetError()? */
|
||
|
return( PR_GetOSError());
|
||
|
}
|
||
|
|
||
|
static void *
|
||
|
my_mutex_alloc( void )
|
||
|
{
|
||
|
return( (void *)PR_NewLock());
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
my_mutex_free( void *mutex )
|
||
|
{
|
||
|
PR_DestroyLock( (PRLock *)mutex );
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
my_mutex_lock( void *mutex )
|
||
|
{
|
||
|
PR_Lock( (PRLock *)mutex );
|
||
|
return( 0 );
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
my_mutex_unlock( void *mutex )
|
||
|
{
|
||
|
if ( PR_Unlock( (PRLock *)mutex ) == PR_FAILURE ) {
|
||
|
return( -1 );
|
||
|
}
|
||
|
|
||
|
return( 0 );
|
||
|
}
|
||
|
|
||
|
static LDAPHostEnt *
|
||
|
my_gethostbyname( const char *name, LDAPHostEnt *result,
|
||
|
char *buffer, int buflen, int *statusp, void *extradata )
|
||
|
{
|
||
|
PRHostEnt prhent;
|
||
|
|
||
|
if ( PR_GetHostByName( name, buffer, buflen,
|
||
|
&prhent ) != PR_SUCCESS ) {
|
||
|
return( NULL );
|
||
|
}
|
||
|
|
||
|
return( copyPRHostEnt2LDAPHostEnt( result, &prhent ));
|
||
|
}
|
||
|
|
||
|
static LDAPHostEnt *
|
||
|
my_gethostbyaddr( const char *addr, int length, int type, LDAPHostEnt *result,
|
||
|
char *buffer, int buflen, int *statusp, void *extradata )
|
||
|
{
|
||
|
PRHostEnt prhent;
|
||
|
|
||
|
if ( PR_GetHostByAddr( (PRNetAddr *)addr, buffer, buflen,
|
||
|
&prhent ) != PR_SUCCESS ) {
|
||
|
return( NULL );
|
||
|
}
|
||
|
|
||
|
return( copyPRHostEnt2LDAPHostEnt( result, &prhent ));
|
||
|
}
|
||
|
|
||
|
static LDAPHostEnt *
|
||
|
copyPRHostEnt2LDAPHostEnt( LDAPHostEnt *ldhp, PRHostEnt *prhp )
|
||
|
{
|
||
|
ldhp->ldaphe_name = prhp->h_name;
|
||
|
ldhp->ldaphe_aliases = prhp->h_aliases;
|
||
|
ldhp->ldaphe_addrtype = prhp->h_addrtype;
|
||
|
ldhp->ldaphe_length = prhp->h_length;
|
||
|
ldhp->ldaphe_addr_list = prhp->h_addr_list;
|
||
|
return( ldhp );
|
||
|
}
|