Back to index

lightning-sunbird  0.9+nobinonly
nsprthreadtest.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla Communicator client code, released
00015  * March 31, 1998.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #include <nspr.h>
00038 #include <stdio.h>
00039 #include <ldap.h>
00040 
00041 #define NAME         "cn=Directory Manager"
00042 #define PASSWORD     "secret99"
00043 #define BASE         "dc=example,dc=com"
00044 
00045 static int simplebind( LDAP *ld, char *msg, int tries );
00046 static void search_thread( void * );
00047 static void modify_thread( void * );
00048 static void add_thread( void * );
00049 static void delete_thread( void * );
00050 static void set_ld_error();
00051 static int  get_ld_error();
00052 static void set_errno();
00053 static int  get_errno();
00054 static void tsd_setup();
00055 static void *my_mutex_alloc( void );
00056 static void my_mutex_free( void * );
00057 static int my_mutex_lock( void * );
00058 static int my_mutex_unlock( void * );
00059 static LDAPHostEnt *my_gethostbyname( const char *name, LDAPHostEnt *result,
00060        char *buffer, int buflen, int *statusp, void *extradata );
00061 static LDAPHostEnt *my_gethostbyaddr( const char *addr, int length,
00062        int type, LDAPHostEnt *result, char *buffer, int buflen,
00063        int *statusp, void *extradata );
00064 static LDAPHostEnt *copyPRHostEnt2LDAPHostEnt( LDAPHostEnt *ldhp,
00065        PRHostEnt *prhp );
00066 
00067 typedef struct ldapmsgwrapper {
00068     LDAPMessage                    *lmw_messagep;
00069     struct ldapmsgwrapper   *lmw_next;
00070 } ldapmsgwrapper;
00071 
00072 
00073 #define CONNECTION_ERROR( lderr )  ( (lderr) == LDAP_SERVER_DOWN || \
00074                                    (lderr) == LDAP_CONNECT_ERROR )
00075 
00076 
00077 LDAP          *ld;
00078 PRUintn              tsdindex;
00079 #ifdef LDAP_MEMCACHE
00080 LDAPMemCache  *memcache = NULL;
00081 #define MEMCACHE_SIZE              (256*1024)    /* 256K bytes */
00082 #define MEMCACHE_TTL        (15*60)              /* 15 minutes */
00083 #endif
00084 
00085 
00086 main( int argc, char **argv )
00087 {
00088        PRThread             *search_tid, *search_tid2, *search_tid3;
00089        PRThread             *search_tid4, *modify_tid, *add_tid;
00090        PRThread             *delete_tid;
00091        struct ldap_thread_fns      tfns;
00092        struct ldap_dns_fns  dnsfns;
00093        int                  rc;
00094 
00095        if ( argc != 3 ) {
00096               fprintf( stderr, "usage: %s host port\n", argv[0] );
00097               exit( 1 );
00098        }
00099 
00100        PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 0 );
00101        if ( PR_NewThreadPrivateIndex( &tsdindex, NULL ) != PR_SUCCESS ) {
00102               perror( "PR_NewThreadPrivateIndex" );
00103               exit( 1 );
00104        }
00105        tsd_setup();  /* for main thread */
00106 
00107        if ( (ld = ldap_init( argv[1], atoi( argv[2] ) )) == NULL ) {
00108               perror( "ldap_open" );
00109               exit( 1 );
00110        }
00111 
00112        /* set thread function pointers */
00113        memset( &tfns, '\0', sizeof(struct ldap_thread_fns) );
00114        tfns.ltf_mutex_alloc = my_mutex_alloc;
00115        tfns.ltf_mutex_free = my_mutex_free;
00116        tfns.ltf_mutex_lock = my_mutex_lock;
00117        tfns.ltf_mutex_unlock = my_mutex_unlock;
00118        tfns.ltf_get_errno = get_errno;
00119        tfns.ltf_set_errno = set_errno;
00120        tfns.ltf_get_lderrno = get_ld_error;
00121        tfns.ltf_set_lderrno = set_ld_error;
00122        tfns.ltf_lderrno_arg = NULL;
00123        if ( ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS, (void *) &tfns )
00124            != 0 ) {
00125               ldap_perror( ld, "ldap_set_option: thread functions" );
00126               exit( 1 );
00127        }
00128 
00129        /* set DNS function pointers */
00130        memset( &dnsfns, '\0', sizeof(struct ldap_dns_fns) );
00131        dnsfns.lddnsfn_bufsize = PR_NETDB_BUF_SIZE;
00132        dnsfns.lddnsfn_gethostbyname = my_gethostbyname;
00133        dnsfns.lddnsfn_gethostbyaddr = my_gethostbyaddr;
00134        if ( ldap_set_option( ld, LDAP_OPT_DNS_FN_PTRS, (void *)&dnsfns )
00135            != 0 ) {
00136               ldap_perror( ld, "ldap_set_option: DNS functions" );
00137               exit( 1 );
00138        }
00139 
00140 #ifdef LDAP_MEMCACHE
00141        /* create the in-memory cache */
00142        if (( rc = ldap_memcache_init( MEMCACHE_TTL, MEMCACHE_SIZE, NULL,
00143            &tfns, &memcache )) != LDAP_SUCCESS ) {
00144               fprintf( stderr, "ldap_memcache_init failed - %s\n",
00145                   ldap_err2string( rc ));
00146               exit( 1 );
00147        }
00148        if (( rc = ldap_memcache_set( ld, memcache )) != LDAP_SUCCESS ) {
00149               fprintf( stderr, "ldap_memcache_set failed - %s\n",
00150                   ldap_err2string( rc ));
00151               exit( 1 );
00152        }
00153 #endif
00154 
00155        /*
00156         * set option so that the next call to ldap_simple_bind_s() after
00157         * the server connection is lost will attempt to reconnect.
00158         */
00159        if ( ldap_set_option( ld, LDAP_OPT_RECONNECT, LDAP_OPT_ON ) != 0 ) {
00160               ldap_perror( ld, "ldap_set_option: reconnect" );
00161               exit( 1 );
00162        }
00163 
00164        /* initial bind */
00165        if ( simplebind( ld, "ldap_simple_bind_s/main", 1 ) != LDAP_SUCCESS ) {
00166               exit( 1 );
00167        }
00168 
00169        /* create the operation threads */
00170        if ( (search_tid = PR_CreateThread( PR_USER_THREAD, search_thread,
00171            "1", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
00172            0 )) == NULL ) {
00173               perror( "PR_CreateThread search_thread" );
00174               exit( 1 );
00175        }
00176        if ( (modify_tid = PR_CreateThread( PR_USER_THREAD, modify_thread,
00177            "2", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
00178            0 )) == NULL ) {
00179               perror( "PR_CreateThread modify_thread" );
00180               exit( 1 );
00181        }
00182        if ( (search_tid2 = PR_CreateThread( PR_USER_THREAD, search_thread,
00183            "3", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
00184            0 )) == NULL ) {
00185               perror( "PR_CreateThread search_thread 2" );
00186               exit( 1 );
00187        }
00188        if ( (add_tid = PR_CreateThread( PR_USER_THREAD, add_thread,
00189            "4", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
00190            0 )) == NULL ) {
00191               perror( "PR_CreateThread add_thread" );
00192               exit( 1 );
00193        }
00194        if ( (search_tid3 = PR_CreateThread( PR_USER_THREAD, search_thread,
00195            "5", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
00196            0 )) == NULL ) {
00197               perror( "PR_CreateThread search_thread 3" );
00198               exit( 1 );
00199        }
00200        if ( (delete_tid = PR_CreateThread( PR_USER_THREAD, delete_thread,
00201            "6", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
00202            0 )) == NULL ) {
00203               perror( "PR_CreateThread delete_thread" );
00204               exit( 1 );
00205        }
00206        if ( (search_tid4 = PR_CreateThread( PR_USER_THREAD, search_thread,
00207            "7", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
00208            0 )) == NULL ) {
00209               perror( "PR_CreateThread search_thread 4" );
00210               exit( 1 );
00211        }
00212 
00213        PR_Cleanup();
00214        return( 0 );
00215 }
00216 
00217 
00218 static int
00219 simplebind( LDAP *ld, char *msg, int tries )
00220 {
00221        int    rc;
00222 
00223        while ( tries-- > 0 ) {
00224               rc = ldap_simple_bind_s( ld, NAME, PASSWORD );
00225               if ( rc != LDAP_SUCCESS ) {
00226                      ldap_perror( ld, msg );
00227               }
00228               if ( tries == 0 || !CONNECTION_ERROR( rc )) {
00229                      return( rc );
00230               }
00231               fprintf( stderr,
00232                   "%s: sleeping for 5 secs - will try %d more time(s)...\n",
00233                   msg, tries );
00234               sleep( 5 );
00235        }
00236 
00237        return( rc );
00238 }
00239 
00240 
00241 static void
00242 search_thread( void *arg1 )
00243 {
00244        LDAPMessage   *res;
00245        LDAPMessage   *e;
00246        char          *a;
00247        char          **v;
00248        char          *dn;
00249        BerElement    *ber;
00250        int           i, rc, msgid;
00251        void          *tsd;
00252        char          *id = arg1;
00253 
00254        printf( "search_thread\n" );
00255        tsd_setup();
00256        for ( ;; ) {
00257               printf( "%sSearching...\n", id );
00258               if ( (msgid = ldap_search( ld, BASE, LDAP_SCOPE_SUBTREE,
00259                   "(objectclass=*)", NULL, 0 )) == -1 ) {
00260                      ldap_perror( ld, "ldap_search_s" );
00261                      rc =  ldap_get_lderrno( ld, NULL, NULL );
00262                      if ( CONNECTION_ERROR( rc ) && simplebind( ld,
00263                          "bind-search_thread", 5 ) != LDAP_SUCCESS ) {
00264                             return;
00265                      }
00266                      continue;
00267               }
00268               while ( (rc = ldap_result( ld, msgid, 0, NULL, &res ))
00269                   == LDAP_RES_SEARCH_ENTRY ) {
00270                      for ( e = ldap_first_entry( ld, res ); e != NULL;
00271                          e = ldap_next_entry( ld, e ) ) {
00272                             dn = ldap_get_dn( ld, e );
00273                             /* printf( "%sdn: %s\n", id, dn ); */
00274                             free( dn );
00275                             for ( a = ldap_first_attribute( ld, e, &ber );
00276                                 a != NULL; a = ldap_next_attribute( ld, e,
00277                                 ber ) ) {
00278                                    v = ldap_get_values( ld, e, a );
00279                                    for ( i = 0; v && v[i] != 0; i++ ) {
00280                                           /*
00281                                           printf( "%s%s: %s\n", id, a,
00282                                               v[i] );
00283                                           */
00284                                    }
00285                                    ldap_value_free( v );
00286                                    ldap_memfree( a );
00287                             }
00288                             if ( ber != NULL ) {
00289                                    ber_free( ber, 0 );
00290                             }
00291                      }
00292                      ldap_msgfree( res );
00293                      /* printf( "%s\n", id ); */
00294               }
00295 
00296               if ( rc == -1 || ldap_result2error( ld, res, 0 ) !=
00297                   LDAP_SUCCESS ) {
00298                      ldap_perror( ld, "ldap_search" );
00299               } else {
00300                      printf( "%sDone with one round\n", id );
00301               }
00302 
00303               if ( rc == -1 ) {
00304                      rc = ldap_get_lderrno( ld, NULL, NULL );
00305                      if ( CONNECTION_ERROR( rc ) && simplebind( ld,
00306                          "bind-search_thread", 5 ) != LDAP_SUCCESS ) {
00307                             return;
00308                      }
00309               }
00310        }
00311 }
00312 
00313 static void
00314 modify_thread( void *arg1 )
00315 {
00316        LDAPMessage   *res;
00317        LDAPMessage   *e;
00318        int           i, modentry, entries, msgid, rc;
00319        LDAPMod              mod;
00320        LDAPMod              *mods[2];
00321        char          *vals[2];
00322        char          *dn;
00323        char          *id = arg1;
00324        ldapmsgwrapper       *list, *lmwp, *lastlmwp;
00325 
00326        printf( "modify_thread\n" );
00327        tsd_setup();
00328        if ( (msgid = ldap_search( ld, BASE, LDAP_SCOPE_SUBTREE,
00329            "(objectclass=*)", NULL, 0 )) == -1 ) {
00330               ldap_perror( ld, "ldap_search_s" );
00331               exit( 1 );
00332        }
00333        entries = 0;
00334        list = lastlmwp = NULL;
00335        while ( (rc = ldap_result( ld, msgid, 0, NULL, &res ))
00336            == LDAP_RES_SEARCH_ENTRY ) {
00337               entries++;
00338               if (( lmwp = (ldapmsgwrapper *)
00339                      malloc( sizeof( ldapmsgwrapper ))) == NULL ) {
00340                      perror( "modify_thread: malloc" );
00341                      exit( 1 );
00342               }
00343               lmwp->lmw_messagep = res;
00344               lmwp->lmw_next = NULL;
00345               if ( lastlmwp == NULL ) {
00346                      list = lastlmwp = lmwp;
00347               } else {
00348                      lastlmwp->lmw_next = lmwp;
00349               }
00350               lastlmwp = lmwp;
00351        }
00352        if ( rc == -1 || ldap_result2error( ld, res, 0 ) != LDAP_SUCCESS ) {
00353               ldap_perror( ld, "modify_thread: ldap_search" );
00354               exit( 1 );
00355        } else {
00356               entries++;
00357               printf( "%sModify got %d entries\n", id, entries );
00358        }
00359 
00360        mods[0] = &mod;
00361        mods[1] = NULL;
00362        vals[0] = "bar";
00363        vals[1] = NULL;
00364        for ( ;; ) {
00365               modentry = rand() % entries;
00366               for ( i = 0, lmwp = list; lmwp != NULL && i < modentry;
00367                   i++, lmwp = lmwp->lmw_next ) {
00368                      /* NULL */
00369               }
00370 
00371               if ( lmwp == NULL ) {
00372                      fprintf( stderr,
00373                          "%sModify could not find entry %d of %d\n",
00374                          id, modentry, entries );
00375                      continue;
00376               }
00377               e = lmwp->lmw_messagep;
00378               printf( "%sPicked entry %d of %d\n", id, i, entries );
00379               dn = ldap_get_dn( ld, e );
00380               mod.mod_op = LDAP_MOD_REPLACE;
00381               mod.mod_type = "description";
00382               mod.mod_values = vals;
00383               printf( "%sModifying (%s)\n", id, dn );
00384               if (( rc = ldap_modify_s( ld, dn, mods )) != LDAP_SUCCESS ) {
00385                      ldap_perror( ld, "ldap_modify_s" );
00386                      if ( CONNECTION_ERROR( rc ) && simplebind( ld,
00387                          "bind-modify_thread", 5 ) != LDAP_SUCCESS ) {
00388                             return;
00389                      }
00390               }
00391               free( dn );
00392        }
00393 }
00394 
00395 static void
00396 add_thread( void *arg1 )
00397 {
00398        LDAPMod       mod[5];
00399        LDAPMod       *mods[6];
00400        char   dn[BUFSIZ], name[40];
00401        char   *cnvals[2], *snvals[2], *ocvals[2];
00402        int    i, rc;
00403        char   *id = arg1;
00404 
00405        printf( "add_thread\n" );
00406        tsd_setup();
00407        for ( i = 0; i < 5; i++ ) {
00408               mods[i] = &mod[i];
00409        }
00410        mods[5] = NULL;
00411        mod[0].mod_op = 0;
00412        mod[0].mod_type = "cn";
00413        mod[0].mod_values = cnvals;
00414        cnvals[1] = NULL;
00415        mod[1].mod_op = 0;
00416        mod[1].mod_type = "sn";
00417        mod[1].mod_values = snvals;
00418        snvals[1] = NULL;
00419        mod[2].mod_op = 0;
00420        mod[2].mod_type = "objectclass";
00421        mod[2].mod_values = ocvals;
00422        ocvals[0] = "person";
00423        ocvals[1] = NULL;
00424        mods[3] = NULL;
00425 
00426        for ( ;; ) {
00427               sprintf( name, "%d", rand() );
00428               sprintf( dn, "cn=%s, " BASE, name );
00429               cnvals[0] = name;
00430               snvals[0] = name;
00431 
00432               printf( "%sAdding entry (%s)\n", id, dn );
00433               if (( rc = ldap_add_s( ld, dn, mods )) != LDAP_SUCCESS ) {
00434                      ldap_perror( ld, "ldap_add_s" );
00435                      if ( CONNECTION_ERROR( rc ) && simplebind( ld,
00436                          "bind-add_thread", 5 ) != LDAP_SUCCESS ) {
00437                             return;
00438                      }
00439               }
00440        }
00441 }
00442 
00443 static void
00444 delete_thread( void *arg1 )
00445 {
00446        LDAPMessage   *res;
00447        char          dn[BUFSIZ], name[40];
00448        int           entries, msgid, rc;
00449        char          *id = arg1;
00450 
00451        printf( "delete_thread\n" );
00452        tsd_setup();
00453        if ( (msgid = ldap_search( ld, BASE, LDAP_SCOPE_SUBTREE,
00454            "(objectclass=*)", NULL, 0 )) == -1 ) {
00455               ldap_perror( ld, "delete_thread: ldap_search_s" );
00456               exit( 1 );
00457        }
00458        entries = 0;
00459        while ( (rc = ldap_result( ld, msgid, 0, NULL, &res ))
00460            == LDAP_RES_SEARCH_ENTRY ) {
00461               entries++;
00462               ldap_msgfree( res );
00463        }
00464        entries++;
00465        if ( rc == -1 || ldap_result2error( ld, res, 1 ) != LDAP_SUCCESS ) {
00466               ldap_perror( ld, "delete_thread: ldap_search" );
00467        } else {
00468               printf( "%sDelete got %d entries\n", id, entries );
00469        }
00470 
00471        for ( ;; ) {
00472               sprintf( name, "%d", rand() );
00473               sprintf( dn, "cn=%s, " BASE, name );
00474 
00475               printf( "%sDeleting entry (%s)\n", id, dn );
00476               if (( rc = ldap_delete_s( ld, dn )) != LDAP_SUCCESS ) {
00477                      ldap_perror( ld, "ldap_delete_s" );
00478                      if ( CONNECTION_ERROR( rc ) && simplebind( ld,
00479                          "bind-delete_thread", 5 ) != LDAP_SUCCESS ) {
00480                             return;
00481                      }
00482               }
00483        }
00484 }
00485 
00486 struct ldap_error {
00487        int    le_errno;
00488        char   *le_matched;
00489        char   *le_errmsg;
00490 };
00491 
00492 static void
00493 tsd_setup()
00494 {
00495        void   *tsd;
00496 
00497        tsd = (void *) PR_GetThreadPrivate( tsdindex );
00498        if ( tsd != NULL ) {
00499               fprintf( stderr, "tsd non-null!\n" );
00500               exit( 1 );
00501        }
00502        tsd = (void *) calloc( 1, sizeof(struct ldap_error) );
00503        if ( PR_SetThreadPrivate( tsdindex, tsd ) != 0 ) {
00504               perror( "PR_SetThreadPrivate" );
00505               exit( 1 );
00506        }
00507 }
00508 
00509 static void
00510 set_ld_error( int err, char *matched, char *errmsg, void *dummy )
00511 {
00512        struct ldap_error *le;
00513 
00514        le = (void *) PR_GetThreadPrivate( tsdindex );
00515        le->le_errno = err;
00516        if ( le->le_matched != NULL ) {
00517               ldap_memfree( le->le_matched );
00518        }
00519        le->le_matched = matched;
00520        if ( le->le_errmsg != NULL ) {
00521               ldap_memfree( le->le_errmsg );
00522        }
00523        le->le_errmsg = errmsg;
00524 }
00525 
00526 static int
00527 get_ld_error( char **matchedp, char **errmsgp, void *dummy )
00528 {
00529        struct ldap_error *le;
00530 
00531        le = PR_GetThreadPrivate( tsdindex );
00532        if ( matchedp != NULL ) {
00533               *matchedp = le->le_matched;
00534        }
00535        if ( errmsgp != NULL ) {
00536               *errmsgp = le->le_errmsg;
00537        }
00538        return( le->le_errno );
00539 }
00540 
00541 static void
00542 set_errno( int oserrno )
00543 {
00544        /* XXXmcs: should this be PR_SetError( oserrno, 0 )? */
00545        PR_SetError( PR_UNKNOWN_ERROR, oserrno );
00546 }
00547 
00548 static int
00549 get_errno( void )
00550 {
00551        /* XXXmcs: should this be PR_GetError()? */
00552        return( PR_GetOSError());
00553 }
00554 
00555 static void *
00556 my_mutex_alloc( void )
00557 {
00558        return( (void *)PR_NewLock());
00559 }
00560 
00561 static void
00562 my_mutex_free( void *mutex )
00563 {
00564        PR_DestroyLock( (PRLock *)mutex );
00565 }
00566 
00567 static int
00568 my_mutex_lock( void *mutex )
00569 {
00570        PR_Lock( (PRLock *)mutex );
00571        return( 0 );
00572 }
00573 
00574 static int
00575 my_mutex_unlock( void *mutex )
00576 {
00577        if ( PR_Unlock( (PRLock *)mutex ) == PR_FAILURE ) {
00578               return( -1 );
00579        }
00580 
00581        return( 0 );
00582 }
00583 
00584 static LDAPHostEnt *
00585 my_gethostbyname( const char *name, LDAPHostEnt *result,
00586        char *buffer, int buflen, int *statusp, void *extradata )
00587 {
00588        PRHostEnt     prhent;
00589 
00590        if ( PR_GetHostByName( name, buffer, buflen,
00591            &prhent ) != PR_SUCCESS ) {
00592               return( NULL );
00593        }
00594 
00595        return( copyPRHostEnt2LDAPHostEnt( result, &prhent ));
00596 }
00597 
00598 static LDAPHostEnt *
00599 my_gethostbyaddr( const char *addr, int length, int type, LDAPHostEnt *result,
00600        char *buffer, int buflen, int *statusp, void *extradata )
00601 {
00602        PRHostEnt     prhent;
00603 
00604        if ( PR_GetHostByAddr( (PRNetAddr *)addr, buffer, buflen,
00605            &prhent ) != PR_SUCCESS ) {
00606               return( NULL );
00607        }
00608 
00609        return( copyPRHostEnt2LDAPHostEnt( result, &prhent ));
00610 }
00611 
00612 static LDAPHostEnt *
00613 copyPRHostEnt2LDAPHostEnt( LDAPHostEnt *ldhp, PRHostEnt *prhp )
00614 {
00615        ldhp->ldaphe_name = prhp->h_name;
00616        ldhp->ldaphe_aliases = prhp->h_aliases;
00617        ldhp->ldaphe_addrtype = prhp->h_addrtype;
00618        ldhp->ldaphe_length =  prhp->h_length;
00619        ldhp->ldaphe_addr_list =  prhp->h_addr_list;
00620        return( ldhp );
00621 }