Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
ldappr-io.c File Reference
#include "ldappr-int.h"

Go to the source code of this file.

Classes

struct  prldap_eventmap_entry

Defines

#define PRLDAP_POLL_ARRAY_GROWTH   5 /* grow arrays 5 elements at a time */
#define PRLDAP_GET_PRFD(socketarg)   (((PRLDAPIOSocketArg *)(socketarg))->prsock_prfd)
#define PRLDAP_EVENTMAP_ENTRIES   sizeof(prldap_eventmap)/sizeof(struct prldap_eventmap_entry )

Functions

static PRIntervalTime prldap_timeout2it (int ms_timeout, int ms_maxtimeout)
static int LDAP_CALLBACK prldap_read (int s, void *buf, int bufsize, struct lextiof_socket_private *socketarg)
static int LDAP_CALLBACK prldap_write (int s, const void *buf, int len, struct lextiof_socket_private *socketarg)
static int LDAP_CALLBACK prldap_poll (LDAP_X_PollFD fds[], int nfds, int timeout, struct lextiof_session_private *sessionarg)
static int LDAP_CALLBACK prldap_connect (const char *hostlist, int defport, int timeout, unsigned long options, struct lextiof_session_private *sessionarg, struct lextiof_socket_private **socketargp)
static int LDAP_CALLBACK prldap_close (int s, struct lextiof_socket_private *socketarg)
static int LDAP_CALLBACK prldap_newhandle (LDAP *ld, struct lextiof_session_private *sessionarg)
static void LDAP_CALLBACK prldap_disposehandle (LDAP *ld, struct lextiof_session_private *sessionarg)
static int LDAP_CALLBACK prldap_shared_newhandle (LDAP *ld, struct lextiof_session_private *sessionarg)
static void LDAP_CALLBACK prldap_shared_disposehandle (LDAP *ld, struct lextiof_session_private *sessionarg)
static PRLDAPIOSessionArgprldap_session_arg_alloc (void)
static void prldap_session_arg_free (PRLDAPIOSessionArg **prsesspp)
static PRLDAPIOSocketArgprldap_socket_arg_alloc (PRLDAPIOSessionArg *sessionarg)
static void prldap_socket_arg_free (PRLDAPIOSocketArg **prsockpp)
static voidprldap_safe_realloc (void *ptr, PRUint32 size)
int prldap_install_io_functions (LDAP *ld, int shared)
static int prldap_try_one_address (struct lextiof_socket_private *prsockp, PRNetAddr *addrp, int timeout, unsigned long options)
int prldap_session_arg_from_ld (LDAP *ld, PRLDAPIOSessionArg **sessargpp)
int prldap_set_io_max_timeout (PRLDAPIOSessionArg *prsessp, int io_max_timeout)
int prldap_get_io_max_timeout (PRLDAPIOSessionArg *prsessp, int *io_max_timeoutp)

Variables

static int prldap_default_io_max_timeout = LDAP_X_IO_TIMEOUT_NO_TIMEOUT
static struct prldap_eventmap_entry []

Class Documentation

struct prldap_eventmap_entry

Definition at line 214 of file ldappr-io.c.

Collaboration diagram for prldap_eventmap_entry:
Class Members
int evm_ldap
PRInt16 evm_nspr

Define Documentation

#define PRLDAP_EVENTMAP_ENTRIES   sizeof(prldap_eventmap)/sizeof(struct prldap_eventmap_entry )

Definition at line 228 of file ldappr-io.c.

#define PRLDAP_GET_PRFD (   socketarg)    (((PRLDAPIOSocketArg *)(socketarg))->prsock_prfd)

Definition at line 88 of file ldappr-io.c.

#define PRLDAP_POLL_ARRAY_GROWTH   5 /* grow arrays 5 elements at a time */

Definition at line 50 of file ldappr-io.c.


Function Documentation

static int LDAP_CALLBACK prldap_close ( int  s,
struct lextiof_socket_private socketarg 
) [static]

Definition at line 443 of file ldappr-io.c.

{
    int              rc;

    rc = 0;
    if ( PR_Close( PRLDAP_GET_PRFD(socketarg)) != PR_SUCCESS ) {
       rc = -1;
       prldap_set_system_errno( prldap_prerr2errno());
    }
    prldap_socket_arg_free( &socketarg );

    return( rc );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int LDAP_CALLBACK prldap_connect ( const char *  hostlist,
int  defport,
int  timeout,
unsigned long  options,
struct lextiof_session_private sessionarg,
struct lextiof_socket_private **  socketargp 
) [static]

Definition at line 375 of file ldappr-io.c.

{
    int                                   rc, parse_err, port;
    char                           *host;
    struct ldap_x_hostlist_status  *status;
    struct lextiof_socket_private  *prsockp;
    PRNetAddr                      addr;
    PRAddrInfo                            *infop = NULL;

    if ( 0 != ( options & LDAP_X_EXTIOF_OPT_SECURE )) {
       prldap_set_system_errno( EINVAL );
       return( -1 );
    }

    if ( NULL == ( prsockp = prldap_socket_arg_alloc( sessionarg ))) {
       prldap_set_system_errno( prldap_prerr2errno());
       return( -1 );
    }

    rc = -1;  /* pessimistic */
    for ( parse_err = ldap_x_hostlist_first( hostlist, defport, &host, &port,
              &status );
              rc < 0 && LDAP_SUCCESS == parse_err && NULL != host;
              parse_err = ldap_x_hostlist_next( &host, &port, status )) {
       /*
        * First, call PR_GetAddrInfoByName; PR_GetAddrInfoByName could 
        * support both IPv4 and IPv6 addresses depending upon the system's
        * configuration.  All available addresses are returned and each of
        * them is examined in prldap_try_one_address till it succeeds.
        * Then, try converting the string address, in case the string
        * address was not successfully handled in PR_GetAddrInfoByName.
        */
       if ( NULL != ( infop =
             PR_GetAddrInfoByName( host, PR_AF_UNSPEC, 
                                (PR_AI_ADDRCONFIG|PR_AI_NOCANONNAME) ))) {
           void *enump = NULL;
           do {
              memset( &addr, 0, sizeof( addr ));
              enump = PR_EnumerateAddrInfo( enump, infop, port, &addr );
              if ( NULL == enump ) {
                  break;
              }
              rc = prldap_try_one_address( prsockp, &addr, timeout, options );
           } while ( rc < 0 );
           PR_FreeAddrInfo( infop );
       } else if ( PR_SUCCESS == PR_StringToNetAddr( host, &addr )) {
           PRLDAP_SET_PORT( &addr, port );
           rc = prldap_try_one_address( prsockp, &addr, timeout, options );
       }
       ldap_memfree( host );
    }

    ldap_x_hostlist_statusfree( status );

    if ( rc < 0 ) {
       prldap_set_system_errno( prldap_prerr2errno());
       prldap_socket_arg_free( &prsockp );
    } else {
       *socketargp = prsockp;
    }

    return( rc );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void LDAP_CALLBACK prldap_disposehandle ( LDAP *  ld,
struct lextiof_session_private sessionarg 
) [static]

Definition at line 506 of file ldappr-io.c.

{
    prldap_session_arg_free( &sessionarg );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int prldap_get_io_max_timeout ( PRLDAPIOSessionArg prsessp,
int io_max_timeoutp 
)

Definition at line 649 of file ldappr-io.c.

{
    int       rc = LDAP_SUCCESS;   /* optimistic */

    if ( NULL == io_max_timeoutp ) {
       rc = LDAP_PARAM_ERROR;
    } else if ( NULL == prsessp ) {
       *io_max_timeoutp = prldap_default_io_max_timeout;
    } else {
       *io_max_timeoutp = prsessp->prsess_io_max_timeout;
    }

    return( rc );
}

Here is the caller graph for this function:

int prldap_install_io_functions ( LDAP *  ld,
int  shared 
)

Definition at line 104 of file ldappr-io.c.

{
    struct ldap_x_ext_io_fns       iofns;

    memset( &iofns, 0, sizeof(iofns));
    iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE;
    iofns.lextiof_read = prldap_read;
    iofns.lextiof_write = prldap_write;
    iofns.lextiof_poll = prldap_poll;
    iofns.lextiof_connect = prldap_connect;
    iofns.lextiof_close = prldap_close;
    if ( shared ) {
       iofns.lextiof_newhandle = prldap_shared_newhandle;
       iofns.lextiof_disposehandle = prldap_shared_disposehandle;
    } else {
       iofns.lextiof_newhandle = prldap_newhandle;
       iofns.lextiof_disposehandle = prldap_disposehandle;
    }
    if ( NULL != ld ) {
       /*
        * If we are dealing with a real ld, we allocate the session specific
        * data structure now.  If not allocated here, it will be allocated
        * inside prldap_newhandle() or prldap_shared_newhandle().
        */
       if ( NULL ==
              ( iofns.lextiof_session_arg = prldap_session_arg_alloc())) {
           ldap_set_lderrno( ld, LDAP_NO_MEMORY, NULL, NULL );
           return( -1 );
       }
    } else {
       iofns.lextiof_session_arg = NULL;
    }

    if ( ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, &iofns ) != 0 ) {
       prldap_session_arg_free(
              (PRLDAPIOSessionArg **) &iofns.lextiof_session_arg );
       return( -1 );
    }

    return( 0 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int LDAP_CALLBACK prldap_newhandle ( LDAP *  ld,
struct lextiof_session_private sessionarg 
) [static]

Definition at line 465 of file ldappr-io.c.

{

    if ( NULL == sessionarg ) {
       struct ldap_x_ext_io_fns    iofns;

       memset( &iofns, 0, sizeof(iofns));
       iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE;
       if ( ldap_get_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS,
              (void *)&iofns ) < 0 ) {
           return( ldap_get_lderrno( ld, NULL, NULL ));
       }
       if ( NULL ==
              ( iofns.lextiof_session_arg = prldap_session_arg_alloc())) {
           return( LDAP_NO_MEMORY );
       }
       if ( ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS,
                  (void *)&iofns ) < 0 ) {
           return( ldap_get_lderrno( ld, NULL, NULL ));
       }
    }

    return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int LDAP_CALLBACK prldap_poll ( LDAP_X_PollFD  fds[],
int  nfds,
int  timeout,
struct lextiof_session_private sessionarg 
) [static]

Definition at line 232 of file ldappr-io.c.

{
    PRLDAPIOSessionArg      *prsessp = sessionarg;
    PRPollDesc              *pds;
    int                     i, j, rc;

    if ( NULL == prsessp ) {
       prldap_set_system_errno( EINVAL );
       return( -1 );
    }

    /* allocate or resize NSPR poll descriptor array */
    if ( prsessp->prsess_pollds_count < nfds ) {
       pds = prldap_safe_realloc( prsessp->prsess_pollds,
              ( nfds + PRLDAP_POLL_ARRAY_GROWTH )
              * sizeof( PRPollDesc ));
       if ( NULL == pds ) {
           prldap_set_system_errno( prldap_prerr2errno());
           return( -1 );
       }
       prsessp->prsess_pollds = pds;
       prsessp->prsess_pollds_count = nfds + PRLDAP_POLL_ARRAY_GROWTH;
    } else {
       pds = prsessp->prsess_pollds;
    }

    /* populate NSPR poll info. based on LDAP info. */
    for ( i = 0; i < nfds; ++i ) {
       if ( NULL == fds[i].lpoll_socketarg ) {
           pds[i].fd = NULL;
       } else {
           pds[i].fd = PRLDAP_GET_PRFD( fds[i].lpoll_socketarg );
       }
       pds[i].in_flags = pds[i].out_flags = 0;
       if ( fds[i].lpoll_fd >= 0 ) {
           for ( j = 0; j < PRLDAP_EVENTMAP_ENTRIES; ++j ) {
              if (( fds[i].lpoll_events & prldap_eventmap[j].evm_ldap )
                  != 0 ) {
                     pds[i].in_flags |= prldap_eventmap[j].evm_nspr;
              }
           }
       }
       fds[i].lpoll_revents = 0;   /* clear revents */
    }

    /* call PR_Poll() to do the real work */
    rc = PR_Poll( pds, nfds,
           prldap_timeout2it( timeout, prsessp->prsess_io_max_timeout ));

    /* populate LDAP info. based on NSPR results */
    for ( i = 0; i < nfds; ++i ) {
       if ( pds[i].fd != NULL ) {
           for ( j = 0; j < PRLDAP_EVENTMAP_ENTRIES; ++j ) {
              if (( pds[i].out_flags & prldap_eventmap[j].evm_nspr )
                     != 0 ) {
                  fds[i].lpoll_revents |= prldap_eventmap[j].evm_ldap;
              }
           }
       }
    }

    return( rc );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int LDAP_CALLBACK prldap_read ( int  s,
void buf,
int  bufsize,
struct lextiof_socket_private socketarg 
) [static]

Definition at line 186 of file ldappr-io.c.

{
    PRIntervalTime   prit;

    prit = prldap_timeout2it( LDAP_X_IO_TIMEOUT_NO_TIMEOUT,
                     socketarg->prsock_io_max_timeout );
    return( PR_Recv( PRLDAP_GET_PRFD(socketarg), buf, bufsize, 0, prit ));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void * prldap_safe_realloc ( void ptr,
PRUint32  size 
) [static]

Definition at line 616 of file ldappr-io.c.

{
    void      *p;

    if ( NULL == ptr ) {
       p = PR_Malloc( size );
    } else {
       p = PR_Realloc( ptr, size );
    }

    return( p );
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 526 of file ldappr-io.c.

{
    PRLDAPIOSessionArg             *prsessp;

    prsessp = PR_Calloc( 1, sizeof( PRLDAPIOSessionArg ));

    if ( NULL != prsessp ) {
       /* copy global defaults to the new session handle */
       prsessp->prsess_io_max_timeout = prldap_default_io_max_timeout;
    }

    return( prsessp );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void prldap_session_arg_free ( PRLDAPIOSessionArg **  prsesspp) [static]

Definition at line 542 of file ldappr-io.c.

{
    if ( NULL != prsesspp && NULL != *prsesspp ) {
       if ( NULL != (*prsesspp)->prsess_pollds ) {
           PR_Free( (*prsesspp)->prsess_pollds );
           (*prsesspp)->prsess_pollds = NULL;
       }
       PR_Free( *prsesspp );
       *prsesspp = NULL;
    }
}

Here is the caller graph for this function:

int prldap_session_arg_from_ld ( LDAP *  ld,
PRLDAPIOSessionArg **  sessargpp 
)

Definition at line 560 of file ldappr-io.c.

{
    struct ldap_x_ext_io_fns       iofns;

    if ( NULL == ld || NULL == sessargpp ) {
       /* XXXmcs: NULL ld's are not supported */
       ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, NULL );
       return( LDAP_PARAM_ERROR );
    }

    memset( &iofns, 0, sizeof(iofns));
    iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE;
    if ( ldap_get_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, (void *)&iofns ) < 0 ) {
       return( ldap_get_lderrno( ld, NULL, NULL ));
    }

    if ( NULL == iofns.lextiof_session_arg ) {
       ldap_set_lderrno( ld, LDAP_LOCAL_ERROR, NULL, NULL );
       return( LDAP_LOCAL_ERROR );
    }

    *sessargpp = iofns.lextiof_session_arg;
    return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int prldap_set_io_max_timeout ( PRLDAPIOSessionArg prsessp,
int  io_max_timeout 
)

Definition at line 633 of file ldappr-io.c.

{
    int       rc = LDAP_SUCCESS;   /* optimistic */

    if ( NULL == prsessp ) {
       prldap_default_io_max_timeout = io_max_timeout;
    } else {
       prsessp->prsess_io_max_timeout = io_max_timeout;
    }

    return( rc );
}

Here is the caller graph for this function:

static void LDAP_CALLBACK prldap_shared_disposehandle ( LDAP *  ld,
struct lextiof_session_private sessionarg 
) [static]

Definition at line 514 of file ldappr-io.c.

{
    prldap_thread_dispose_handle( ld, sessionarg );
    prldap_disposehandle( ld, sessionarg );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int LDAP_CALLBACK prldap_shared_newhandle ( LDAP *  ld,
struct lextiof_session_private sessionarg 
) [static]

Definition at line 493 of file ldappr-io.c.

{
    int              rc;

    if (( rc = prldap_newhandle( ld, sessionarg )) == LDAP_SUCCESS ) {
       rc = prldap_thread_new_handle( ld, sessionarg );
    }

    return( rc );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRLDAPIOSocketArg * prldap_socket_arg_alloc ( PRLDAPIOSessionArg sessionarg) [static]

Definition at line 590 of file ldappr-io.c.

{
    PRLDAPIOSocketArg              *prsockp;

    prsockp = PR_Calloc( 1, sizeof( PRLDAPIOSocketArg ));

    if ( NULL != prsockp && NULL != sessionarg ) {
       /* copy socket defaults from the session */
       prsockp->prsock_io_max_timeout = sessionarg->prsess_io_max_timeout;
    }

    return( prsockp );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void prldap_socket_arg_free ( PRLDAPIOSocketArg **  prsockpp) [static]

Definition at line 606 of file ldappr-io.c.

{
    if ( NULL != prsockpp && NULL != *prsockpp ) {
       PR_Free( *prsockpp );
       *prsockpp = NULL;
    }
}

Here is the caller graph for this function:

static PRIntervalTime prldap_timeout2it ( int  ms_timeout,
int  ms_maxtimeout 
) [static]

Definition at line 148 of file ldappr-io.c.

{
    PRIntervalTime   prit;

    if ( LDAP_X_IO_TIMEOUT_NO_WAIT == ms_timeout ) {
       prit = PR_INTERVAL_NO_WAIT;
    } else if ( LDAP_X_IO_TIMEOUT_NO_TIMEOUT == ms_timeout ) {
       prit = PR_INTERVAL_NO_TIMEOUT;
    } else {
       prit = PR_MillisecondsToInterval( ms_timeout );
    }

    /* cap at maximum I/O timeout */
    if ( LDAP_X_IO_TIMEOUT_NO_WAIT == ms_maxtimeout ) {
       prit = LDAP_X_IO_TIMEOUT_NO_WAIT;
    } else if ( LDAP_X_IO_TIMEOUT_NO_TIMEOUT != ms_maxtimeout ) {
       if ( LDAP_X_IO_TIMEOUT_NO_TIMEOUT == ms_timeout ||
                  ms_timeout > ms_maxtimeout ) {
           prit = PR_MillisecondsToInterval( ms_maxtimeout );
       }
    }

#ifdef PRLDAP_DEBUG
    if ( PR_INTERVAL_NO_WAIT == prit ) {
       fprintf( stderr, "prldap_timeout2it: NO_WAIT\n" );
    } else if ( PR_INTERVAL_NO_TIMEOUT == prit ) {
       fprintf( stderr, "prldap_timeout2it: NO_TIMEOUT\n" );
    } else {
       fprintf( stderr, "prldap_timeout2it: %dms\n",
              PR_IntervalToMilliseconds(prit));
    }
#endif /* PRLDAP_DEBUG */

    return( prit );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int prldap_try_one_address ( struct lextiof_socket_private prsockp,
PRNetAddr addrp,
int  timeout,
unsigned long  options 
) [static]

Definition at line 303 of file ldappr-io.c.

{
    /*
     * Open a TCP socket:
     */
    if (( prsockp->prsock_prfd = PR_OpenTCPSocket(
              PR_NetAddrFamily(addrp) )) == NULL ) {
       return( -1 );
    }

    /*
     * Set nonblocking option if requested:
     */
    if ( 0 != ( options & LDAP_X_EXTIOF_OPT_NONBLOCKING )) {
       PRSocketOptionData   optdata;

       optdata.option = PR_SockOpt_Nonblocking;
       optdata.value.non_blocking = PR_TRUE;
       if ( PR_SetSocketOption( prsockp->prsock_prfd, &optdata )
                  != PR_SUCCESS ) {
           prldap_set_system_errno( prldap_prerr2errno());
           PR_Close( prsockp->prsock_prfd );
           return( -1 );
       }
    }

#ifdef PRLDAP_DEBUG
    {
       char   buf[ 256 ], *p, *fmtstr;

       if ( PR_SUCCESS != PR_NetAddrToString( addrp, buf, sizeof(buf ))) {
              strcpy( buf, "conversion failed!" );
       }
       if ( strncmp( buf, "::ffff:", 7 ) == 0 ) {
              /* IPv4 address mapped into IPv6 address space */
              p = buf + 7;
              fmtstr = "prldap_try_one_address(): Trying %s:%d...\n";
       } else {
              p = buf;
              fmtstr = "prldap_try_one_address(): Trying [%s]:%d...\n";
       }
       fprintf( stderr, fmtstr, p, PR_ntohs( addrp->ipv6.port ));
    }
#endif /* PRLDAP_DEBUG */

    /*
     * Try to open the TCP connection itself:
     */
    if ( PR_SUCCESS != PR_Connect( prsockp->prsock_prfd, addrp,
                prldap_timeout2it( timeout, prsockp->prsock_io_max_timeout ))
                && PR_IN_PROGRESS_ERROR != PR_GetError() ) {
       PR_Close( prsockp->prsock_prfd );
       prsockp->prsock_prfd = NULL;
       return( -1 );
    }

#ifdef PRLDAP_DEBUG
    fputs( "prldap_try_one_address(): Connected.\n", stderr );
#endif /* PRLDAP_DEBUG */

    /*
     * Success.  Return a valid file descriptor (1 is always valid)
     */
    return( 1 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int LDAP_CALLBACK prldap_write ( int  s,
const void buf,
int  len,
struct lextiof_socket_private socketarg 
) [static]

Definition at line 198 of file ldappr-io.c.

{
    PRIntervalTime   prit;

    prit = prldap_timeout2it( LDAP_X_IO_TIMEOUT_NO_TIMEOUT,
                     socketarg->prsock_io_max_timeout );

    /*
     * Note the 4th parameter (flags) to PR_Send() has been obsoleted and
     * must always be 0
     */
    return( PR_Send( PRLDAP_GET_PRFD(socketarg), buf, len, 0, prit ));
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 94 of file ldappr-io.c.

struct prldap_eventmap_entry[] [static]