home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / src / os-ip.c next >
C/C++ Source or Header  |  2001-11-13  |  14KB  |  671 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/os-ip.c,v 1.33.2.13 2001/07/21 19:01:39 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6. /*  Portions
  7.  *  Copyright (c) 1995 Regents of the University of Michigan.
  8.  *  All rights reserved.
  9.  *
  10.  *  os-ip.c -- platform-specific TCP & UDP related code
  11.  */
  12.  
  13. #include "portable.h"
  14.  
  15. #include <stdio.h>
  16.  
  17. #include <ac/stdlib.h>
  18.  
  19. #include <ac/errno.h>
  20. #include <ac/socket.h>
  21. #include <ac/string.h>
  22. #include <ac/time.h>
  23. #include <ac/unistd.h>
  24.  
  25. #ifdef HAVE_IO_H
  26. #include <io.h>
  27. #endif /* HAVE_IO_H */
  28.  
  29. #include "ldap-int.h"
  30.  
  31. int ldap_int_tblsize = 0;
  32.  
  33. /*
  34.  * nonblock connect code
  35.  * written by Lars Uffmann, <lars.uffmann@mediaway.net>.
  36.  *
  37.  * Copyright 1999, Lars Uffmann, All rights reserved.
  38.  * This software is not subject to any license of my employer
  39.  * mediaWays GmbH.
  40.  *
  41.  * OpenLDAP COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  42.  *
  43.  * Read about the rationale in ldap_connect_timeout: 
  44.  * ftp://koobera.math.uic.edu/www/docs/connect.html.
  45.  */
  46.  
  47. #define osip_debug(ld,fmt,arg1,arg2,arg3) \
  48. do { \
  49.     ldap_log_printf(NULL, LDAP_DEBUG_TRACE, fmt, arg1, arg2, arg3); \
  50. } while(0)
  51.  
  52. static void
  53. ldap_pvt_set_errno(int err)
  54. {
  55.     errno = err;
  56. }
  57.  
  58. int
  59. ldap_int_timeval_dup( struct timeval **dest, const struct timeval *src )
  60. {
  61.     struct timeval *new;
  62.  
  63.     assert( dest != NULL );
  64.  
  65.     if (src == NULL) {
  66.         *dest = NULL;
  67.         return 0;
  68.     }
  69.  
  70.     new = (struct timeval *) LDAP_MALLOC(sizeof(struct timeval));
  71.  
  72.     if( new == NULL ) {
  73.         *dest = NULL;
  74.         return 1;
  75.     }
  76.  
  77.     AC_MEMCPY( (char *) new, (const char *) src, sizeof(struct timeval));
  78.  
  79.     *dest = new;
  80.     return 0;
  81. }
  82.  
  83. static int
  84. ldap_pvt_ndelay_on(LDAP *ld, int fd)
  85. {
  86.     osip_debug(ld, "ldap_ndelay_on: %d\n",fd,0,0);
  87.     return ber_pvt_socket_set_nonblock( fd, 1 );
  88. }
  89.    
  90. static int
  91. ldap_pvt_ndelay_off(LDAP *ld, int fd)
  92. {
  93.     osip_debug(ld, "ldap_ndelay_off: %d\n",fd,0,0);
  94.     return ber_pvt_socket_set_nonblock( fd, 0 );
  95. }
  96.  
  97. static ber_socket_t
  98. ldap_int_socket(LDAP *ld, int family, int type )
  99. {
  100.     ber_socket_t s = socket(family, type, 0);
  101.     osip_debug(ld, "ldap_new_socket: %d\n",s,0,0);
  102.     return ( s );
  103. }
  104.  
  105. static int
  106. ldap_pvt_close_socket(LDAP *ld, int s)
  107. {
  108.     osip_debug(ld, "ldap_close_socket: %d\n",s,0,0);
  109.     return tcp_close(s);
  110. }
  111.  
  112. static int
  113. ldap_int_prepare_socket(LDAP *ld, int s, int proto )
  114. {
  115.     osip_debug(ld, "ldap_prepare_socket: %d\n", s,0,0);
  116.  
  117. #ifdef TCP_NODELAY
  118.     if( proto == LDAP_PROTO_TCP ) {
  119.         int dummy = 1;
  120.         if ( setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
  121.             (char*) &dummy, sizeof(dummy) ) == AC_SOCKET_ERROR )
  122.         {
  123.             osip_debug(ld, "ldap_prepare_socket: "
  124.                 "setsockopt(%d, TCP_NODELAY) failed (ignored).\n",
  125.                 s, 0, 0);
  126.         }
  127.     }
  128. #endif
  129.  
  130.     return 0;
  131. }
  132.  
  133. #undef TRACE
  134. #define TRACE do { \
  135.     osip_debug(ld, \
  136.         "ldap_is_socket_ready: error on socket %d: errno: %d (%s)\n", \
  137.         s, \
  138.         errno, \
  139.         sock_errstr(errno) ); \
  140. } while( 0 )
  141.  
  142. /*
  143.  * check the socket for errors after select returned.
  144.  */
  145. static int
  146. ldap_pvt_is_socket_ready(LDAP *ld, int s)
  147. {
  148.     osip_debug(ld, "ldap_is_sock_ready: %d\n",s,0,0);
  149.  
  150. #if defined( notyet ) /* && defined( SO_ERROR ) */
  151. {
  152.     int so_errno;
  153.     int dummy = sizeof(so_errno);
  154.     if ( getsockopt( s, SOL_SOCKET, SO_ERROR, &so_errno, &dummy )
  155.         == AC_SOCKET_ERROR )
  156.     {
  157.         return -1;
  158.     }
  159.     if ( so_errno ) {
  160.         ldap_pvt_set_errno(so_errno);
  161.         TRACE;
  162.         return -1;
  163.     }
  164.     return 0;
  165. }
  166. #else
  167. {
  168.     /* error slippery */
  169.     struct sockaddr_in sin;
  170.     char ch;
  171.     int dummy = sizeof(sin);
  172.     if ( getpeername( s, (struct sockaddr *) &sin, &dummy )
  173.         == AC_SOCKET_ERROR )
  174.     {
  175.         /* XXX: needs to be replace with ber_stream_read() */
  176.         tcp_read(s, &ch, 1);
  177. #ifdef HAVE_WINSOCK
  178.         ldap_pvt_set_errno( WSAGetLastError() );
  179. #endif
  180. #ifdef __OS2__
  181.         ldap_pvt_set_errno( sock_errno() );
  182. #endif
  183.         TRACE;
  184.         return -1;
  185.     }
  186.     return 0;
  187. }
  188. #endif
  189.     return -1;
  190. }
  191. #undef TRACE
  192.  
  193. static int
  194. ldap_pvt_connect(LDAP *ld, ber_socket_t s,
  195.     struct sockaddr *sin, socklen_t addrlen,
  196.     int async)
  197. {
  198.     struct timeval    tv, *opt_tv=NULL;
  199.     fd_set        wfds, *z=NULL;
  200. #ifdef HAVE_WINSOCK
  201.     fd_set        efds;
  202. #endif
  203.  
  204.     if ( (opt_tv = ld->ld_options.ldo_tm_net) != NULL ) {
  205.         tv.tv_usec = opt_tv->tv_usec;
  206.         tv.tv_sec = opt_tv->tv_sec;
  207.     }
  208.  
  209.     osip_debug(ld, "ldap_connect_timeout: fd: %d tm: %ld async: %d\n",
  210.             s, opt_tv ? tv.tv_sec : -1L, async);
  211.  
  212.     if ( ldap_pvt_ndelay_on(ld, s) == -1 )
  213.         return ( -1 );
  214.  
  215.     if ( connect(s, sin, addrlen) != AC_SOCKET_ERROR )
  216.     {
  217.         if ( ldap_pvt_ndelay_off(ld, s) == -1 )
  218.             return ( -1 );
  219.         return ( 0 );
  220.     }
  221.  
  222. #ifdef HAVE_WINSOCK
  223.     ldap_pvt_set_errno( WSAGetLastError() );
  224. #endif
  225. #ifdef __OS2__
  226.     ldap_pvt_set_errno( sock_errno() );
  227. #endif
  228. //    if ( errno != EINPROGRESS && errno != EWOULDBLOCK ) {
  229. //        return ( -1 );
  230. //    }
  231.     
  232. #ifdef notyet
  233.     if ( async ) return ( -2 );
  234. #endif
  235.  
  236.     FD_ZERO(&wfds);
  237.     FD_SET(s, &wfds );
  238.  
  239. #ifdef HAVE_WINSOCK
  240.     FD_ZERO(&efds);
  241.     FD_SET(s, &efds );
  242. #endif
  243.  
  244. #if defined(__OS2__) && defined(TCPV40HDRS)
  245.     if ( bsdselect(ldap_int_tblsize, z, &wfds,
  246. #else
  247.     if ( select(ldap_int_tblsize, z, &wfds,
  248. #endif
  249. #ifdef HAVE_WINSOCK
  250.             &efds,
  251. #else
  252.             z,
  253. #endif
  254.             opt_tv ? &tv : NULL) == AC_SOCKET_ERROR )
  255.     {
  256.         return ( -1 );
  257.     }
  258.  
  259. #ifdef HAVE_WINSOCK
  260.     /* This means the connection failed */
  261.     if ( FD_ISSET(s, &efds) ) {
  262.         ldap_pvt_set_errno(WSAECONNREFUSED);
  263.         osip_debug(ld, "ldap_pvt_connect: error on socket %d: "
  264.                "errno: %d (%s)\n", s, errno, sock_errstr(errno));
  265.         return -1;
  266.     }
  267. #endif
  268.     if ( FD_ISSET(s, &wfds) ) {
  269.         if ( ldap_pvt_is_socket_ready(ld, s) == -1 )
  270.             return ( -1 );
  271. #ifndef __OS2__
  272.         if ( ldap_pvt_ndelay_off(ld, s) == -1 )
  273.             return ( -1 );
  274. #endif
  275.         return ( 0 );
  276.     }
  277.     osip_debug(ld, "ldap_connect_timeout: timed out\n",0,0,0);
  278.     ldap_pvt_set_errno( ETIMEDOUT );
  279.     return ( -1 );
  280. }
  281.  
  282. #ifndef HAVE_INET_ATON
  283. int
  284. ldap_pvt_inet_aton( const char *host, struct in_addr *in)
  285. {
  286. #if defined(__OS2__) && defined (TCPV40HDRS)
  287.     unsigned long u = inet_addr( (char *)host );
  288. #else    
  289.     unsigned long u = inet_addr( host );
  290. #endif    
  291.     if ( u != 0xffffffff || u != (unsigned long) -1 ) {
  292.         in->s_addr = u;
  293.         return 1;
  294.     }
  295.     return 0;
  296. }
  297. #endif
  298.  
  299.  
  300. int
  301. ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
  302.     int proto,
  303.     const char *host,
  304.     unsigned long address, int port, int async)
  305. {
  306.     struct sockaddr_in    sin;
  307.     ber_socket_t        s = AC_SOCKET_INVALID;
  308.     int            rc, i, use_hp = 0;
  309.     struct hostent        *hp = NULL;
  310.     char               *ha_buf=NULL, *p, *q;
  311.  
  312.     osip_debug(ld, "ldap_connect_to_host: %s\n",host,0,0);
  313.     
  314.     if (host != NULL) {
  315. #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
  316.         char serv[7];
  317.         int err;
  318.         struct addrinfo hints, *res, *sai;
  319.  
  320.         memset( &hints, '\0', sizeof(hints) );
  321.         hints.ai_family = AF_UNSPEC;
  322.         hints.ai_socktype = SOCK_STREAM;
  323.  
  324.         if ( err = getaddrinfo(host, serv, &hints, &res) ) {
  325.             osip_debug(ld, "ldap_connect_to_host: getaddrinfo failed: %s\n",
  326.                 AC_GAI_STRERROR(err), 0, 0);
  327.             return -1;
  328.         }
  329.         sai = res;
  330.         rc = -1;
  331.         do {
  332.             /* we assume AF_x and PF_x are equal for all x */
  333.             s = ldap_int_socket( ld, sai->ai_family, SOCK_STREAM );
  334.             if ( s == AC_SOCKET_INVALID ) {
  335.                 continue;
  336.             }
  337.  
  338.             if ( ldap_int_prepare_socket(ld, s, proto ) == -1 ) {
  339.                 ldap_pvt_close_socket(ld, s);
  340.                 break;
  341.             }
  342.  
  343.             switch (sai->ai_family) {
  344. #ifdef LDAP_PF_INET6
  345.             case AF_INET6: {
  346.                 char addr[INET6_ADDRSTRLEN];
  347.                 inet_ntop( AF_INET6,
  348.                     &((struct sockaddr_in6 *)sai->ai_addr)->sin6_addr,
  349.                     addr, sizeof addr);
  350.                 osip_debug(ld, "ldap_connect_to_host: Trying %s %s\n", 
  351.                     addr, serv, 0);
  352.             } break;
  353. #endif
  354.             case AF_INET: {
  355.                 char addr[INET_ADDRSTRLEN];
  356.                 inet_ntop( AF_INET,
  357.                     &((struct sockaddr_in *)sai->ai_addr)->sin_addr,
  358.                     addr, sizeof addr);
  359.                 osip_debug(ld, "ldap_connect_to_host: Trying %s:%s\n", 
  360.                     addr, serv, 0);
  361.             } break;
  362.             }
  363.  
  364.             rc = ldap_pvt_connect(ld, s, sai->ai_addr, sai->ai_addrlen, async);
  365.             if ( (rc == 0) || (rc == -2) ) {
  366.                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
  367.                 break;
  368.             }
  369.             ldap_pvt_close_socket(ld, s);
  370.         } while ((sai = sai->ai_next) != NULL);
  371.         freeaddrinfo(res);
  372.         return rc;
  373.  
  374. #else
  375.         struct in_addr in;
  376.         if (! inet_aton( host, &in) ) {
  377.             int local_h_errno;
  378.             struct hostent he_buf;
  379.             rc = ldap_pvt_gethostbyname_a(host, &he_buf, &ha_buf,
  380.                     &hp, &local_h_errno);
  381.  
  382.             if ( (rc < 0) || (hp == NULL) ) {
  383. #ifdef HAVE_WINSOCK
  384.                 ldap_pvt_set_errno( WSAGetLastError() );
  385. #elif defined( __OS2__ )
  386.         ldap_pvt_set_errno( sock_errno() );
  387. #else
  388.                 /* not exactly right, but... */
  389.                 ldap_pvt_set_errno( EHOSTUNREACH );
  390. #endif
  391.                 if (ha_buf) LDAP_FREE(ha_buf);
  392.                 return -1;
  393.             }
  394.             use_hp = 1;
  395.         }
  396.         address = in.s_addr;
  397. #endif
  398.     }
  399.  
  400.     rc = s = -1;
  401.     for ( i = 0; !use_hp || (hp->h_addr_list[i] != 0); ++i, rc = -1 ) {
  402.  
  403.         s = ldap_int_socket( ld, PF_INET, SOCK_STREAM );
  404.         if ( s == AC_SOCKET_INVALID ) {
  405.             /* use_hp ? continue : break; */
  406.             break;
  407.         }
  408.        
  409.         if ( ldap_int_prepare_socket( ld, s, proto ) == -1 ) {
  410.             ldap_pvt_close_socket(ld, s);
  411.             break;
  412.         }
  413.  
  414.         (void)memset((char *)&sin, '\0', sizeof(struct sockaddr_in));
  415.         sin.sin_family = AF_INET;
  416.         sin.sin_port = port;
  417.         p = (char *)&sin.sin_addr;
  418.         q = use_hp ? (char *)hp->h_addr_list[i] : (char *)&address;
  419.         AC_MEMCPY(p, q, sizeof(sin.sin_addr) );
  420.  
  421.         osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n", 
  422.                 inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),0);
  423.  
  424.         rc = ldap_pvt_connect(ld, s,
  425.             (struct sockaddr *)&sin, sizeof(struct sockaddr_in),
  426.             async);
  427.    
  428.         if ( (rc == 0) || (rc == -2) ) {
  429.             ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
  430.             break;
  431.         }
  432.  
  433.         ldap_pvt_close_socket(ld, s);
  434.  
  435.         if (!use_hp)
  436.             break;
  437.     }
  438.     if (ha_buf) LDAP_FREE(ha_buf);
  439.     return rc;
  440. }
  441.  
  442. #if defined( LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND ) || \
  443.     defined( HAVE_CYRUS_SASL )
  444. char *
  445. ldap_host_connected_to( Sockbuf *sb )
  446. {
  447.     struct hostent    *hp;
  448.     socklen_t        len;
  449.     struct sockaddr    sa;
  450.     char            *addr;
  451.     char            *host;
  452.  
  453.        /* buffers for gethostbyaddr_r */
  454.        struct hostent    he_buf;
  455.     int                local_h_errno;
  456.        char            *ha_buf=NULL;
  457.     ber_socket_t    sd;
  458.  
  459.     (void)memset( (char *)&sa, '\0', sizeof( struct sockaddr ));
  460.     len = sizeof( sa );
  461.  
  462.     ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
  463.     if ( getpeername( sd, &sa, &len ) == -1 ) {
  464.         return( NULL );
  465.     }
  466.  
  467.     /*
  468.      * do a reverse lookup on the addr to get the official hostname.
  469.      * this is necessary for kerberos to work right, since the official
  470.      * hostname is used as the kerberos instance.
  471.      */
  472.  
  473.     switch (sa.sa_family) {
  474. #ifdef LDAP_PF_LOCAL
  475.     case AF_LOCAL:
  476.         return LDAP_STRDUP( ldap_int_hostname );
  477. #endif
  478. #ifdef LDAP_PF_INET6
  479.     case AF_INET6:
  480.         addr = (char *) &((struct sockaddr_in6 *)&sa)->sin6_addr;
  481.         len = sizeof( struct in6_addr );
  482.         break;
  483. #endif
  484.     case AF_INET:
  485.         addr = (char *) &((struct sockaddr_in *)&sa)->sin_addr;
  486.         len = sizeof( struct in_addr );
  487.  
  488.         {
  489.             struct sockaddr_in localhost;
  490.             localhost.sin_addr.s_addr = htonl( INADDR_ANY );
  491.  
  492.             if( memcmp ( &localhost.sin_addr,
  493.                 &((struct sockaddr_in *)&sa)->sin_addr,
  494.                 sizeof(localhost.sin_addr) ) == 0 )
  495.             {
  496.                 return LDAP_STRDUP( ldap_int_hostname );
  497.             }
  498.  
  499. #ifdef INADDR_LOOPBACK
  500.             localhost.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
  501.  
  502.             if( memcmp ( &localhost.sin_addr,
  503.                 &((struct sockaddr_in *)&sa)->sin_addr,
  504.                 sizeof(localhost.sin_addr) ) == 0 )
  505.             {
  506.                 return LDAP_STRDUP( ldap_int_hostname );
  507.             }
  508. #endif
  509.         }
  510.         break;
  511.  
  512.     default:
  513.         return( NULL );
  514.         break;
  515.     }
  516.  
  517.     host = NULL;
  518.     if ((ldap_pvt_gethostbyaddr_a( addr, len,
  519.         sa.sa_family, &he_buf, &ha_buf,
  520.         &hp,&local_h_errno ) == 0 ) &&
  521.         (hp != NULL) && ( hp->h_name != NULL ) )
  522.     {
  523.         host = LDAP_STRDUP( hp->h_name );   
  524.     }
  525.  
  526.     LDAP_FREE( ha_buf );
  527.     return host;
  528. }
  529. #endif
  530.  
  531.  
  532. /* for UNIX */
  533. struct selectinfo {
  534.     fd_set    si_readfds;
  535.     fd_set    si_writefds;
  536.     fd_set    si_use_readfds;
  537.     fd_set    si_use_writefds;
  538. };
  539.  
  540.  
  541. void
  542. ldap_mark_select_write( LDAP *ld, Sockbuf *sb )
  543. {
  544.     struct selectinfo    *sip;
  545.     ber_socket_t        sd;
  546.  
  547.     sip = (struct selectinfo *)ld->ld_selectinfo;
  548.     
  549.     ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
  550.     if ( !FD_ISSET( sd, &sip->si_writefds )) {
  551.         FD_SET( sd, &sip->si_writefds );
  552.     }
  553. }
  554.  
  555.  
  556. void
  557. ldap_mark_select_read( LDAP *ld, Sockbuf *sb )
  558. {
  559.     struct selectinfo    *sip;
  560.     ber_socket_t        sd;
  561.  
  562.     sip = (struct selectinfo *)ld->ld_selectinfo;
  563.  
  564.     ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
  565.     if ( !FD_ISSET( sd, &sip->si_readfds )) {
  566.         FD_SET( sd, &sip->si_readfds );
  567.     }
  568. }
  569.  
  570.  
  571. void
  572. ldap_mark_select_clear( LDAP *ld, Sockbuf *sb )
  573. {
  574.     struct selectinfo    *sip;
  575.     ber_socket_t        sd;
  576.  
  577.     sip = (struct selectinfo *)ld->ld_selectinfo;
  578.  
  579.     ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
  580.     FD_CLR( sd, &sip->si_writefds );
  581.     FD_CLR( sd, &sip->si_readfds );
  582. }
  583.  
  584.  
  585. int
  586. ldap_is_write_ready( LDAP *ld, Sockbuf *sb )
  587. {
  588.     struct selectinfo    *sip;
  589.     ber_socket_t        sd;
  590.  
  591.     sip = (struct selectinfo *)ld->ld_selectinfo;
  592.  
  593.     ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
  594.     return( FD_ISSET( sd, &sip->si_use_writefds ));
  595. }
  596.  
  597.  
  598. int
  599. ldap_is_read_ready( LDAP *ld, Sockbuf *sb )
  600. {
  601.     struct selectinfo    *sip;
  602.     ber_socket_t        sd;
  603.  
  604.     sip = (struct selectinfo *)ld->ld_selectinfo;
  605.  
  606.     ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
  607.     return( FD_ISSET( sd, &sip->si_use_readfds ));
  608. }
  609.  
  610.  
  611. void *
  612. ldap_new_select_info( void )
  613. {
  614.     struct selectinfo    *sip;
  615.  
  616.     if (( sip = (struct selectinfo *)LDAP_CALLOC( 1,
  617.         sizeof( struct selectinfo ))) != NULL ) {
  618.         FD_ZERO( &sip->si_readfds );
  619.         FD_ZERO( &sip->si_writefds );
  620.     }
  621.  
  622.     return( (void *)sip );
  623. }
  624.  
  625.  
  626. void
  627. ldap_free_select_info( void *sip )
  628. {
  629.     LDAP_FREE( sip );
  630. }
  631.  
  632.  
  633. void
  634. ldap_int_ip_init( void )
  635. {
  636.     int tblsize;
  637. #if defined( HAVE_SYSCONF )
  638.     tblsize = sysconf( _SC_OPEN_MAX );
  639. #elif defined( HAVE_GETDTABLESIZE )
  640.     tblsize = getdtablesize();
  641. #else
  642.     tblsize = FD_SETSIZE;
  643. #endif /* !USE_SYSCONF */
  644.  
  645. #ifdef FD_SETSIZE
  646.     if( tblsize > FD_SETSIZE )
  647.         tblsize = FD_SETSIZE;
  648. #endif    /* FD_SETSIZE*/
  649.     ldap_int_tblsize = tblsize;
  650. }
  651.  
  652.  
  653. int
  654. do_ldap_select( LDAP *ld, struct timeval *timeout )
  655. {
  656.     struct selectinfo    *sip;
  657.  
  658.     Debug( LDAP_DEBUG_TRACE, "do_ldap_select\n", 0, 0, 0 );
  659.  
  660.     if ( ldap_int_tblsize == 0 )
  661.         ldap_int_ip_init();
  662.  
  663.     sip = (struct selectinfo *)ld->ld_selectinfo;
  664.     sip->si_use_readfds = sip->si_readfds;
  665.     sip->si_use_writefds = sip->si_writefds;
  666.     
  667.     return( select( ldap_int_tblsize,
  668.                     &sip->si_use_readfds, &sip->si_use_writefds,
  669.                     NULL, timeout ));
  670. }
  671.