* os-ip.c -- platform-specific TCP & UDP related code
*/
-#ifndef lint
-static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n";
-#endif
+#include "portable.h"
#include <stdio.h>
-#include <string.h>
-#include <errno.h>
+#include <stdlib.h>
-#ifdef _WIN32
+#include <ac/errno.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+#include <ac/unistd.h>
+
+#ifdef HAVE_IO_H
#include <io.h>
-#include "msdos.h"
-#else /* _WIN32 */
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#endif /* _WIN32 */
-#ifdef _AIX
-#include <sys/select.h>
-#endif /* _AIX */
-#ifdef VMS
-#include "ucx_select.h"
-#endif /* VMS */
-#include "portable.h"
-#include "lber.h"
-#include "ldap.h"
+#endif /* HAVE_IO_H */
-#ifdef LDAP_REFERRALS
-#ifdef USE_SYSCONF
-#include <unistd.h>
-#endif /* USE_SYSCONF */
-#ifdef notyet
-#ifdef NEED_FILIO
+#if defined( HAVE_SYS_FILIO_H )
#include <sys/filio.h>
-#else /* NEED_FILIO */
+#elif defined( HAVE_SYS_IOCTL_H )
#include <sys/ioctl.h>
-#endif /* NEED_FILIO */
-#endif /* notyet */
-#endif /* LDAP_REFERRALS */
-
-#ifdef MACOS
-#define tcp_close( s ) tcpclose( s )
-#else /* MACOS */
-#ifdef DOS
-#ifdef PCNFS
-#define tcp_close( s ) close( s )
-#endif /* PCNFS */
-#ifdef NCSA
-#define tcp_close( s ) netclose( s ); netshut()
-#endif /* NCSA */
-#ifdef WINSOCK
-#define tcp_close( s ) closesocket( s ); WSACleanup();
-#endif /* WINSOCK */
-#else /* DOS */
-#define tcp_close( s ) close( s )
-#endif /* DOS */
-#endif /* MACOS */
+#endif
+#include "ldap-int.h"
int
-connect_to_host( Sockbuf *sb, char *host, unsigned long address,
+ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
int port, int async )
/*
* if host == NULL, connect using address
* "address" and "port" must be in network byte order
* zero is returned upon success, -1 if fatal error, -2 EINPROGRESS
- * async is only used ifdef LDAP_REFERRALS (non-0 means don't wait for connect)
+ * async is only used ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS (non-0 means don't wait for connect)
* XXX async is not used yet!
*/
{
- int rc, i, s, connected, use_hp;
+ int rc, i, s = 0;
+ int connected, use_hp;
struct sockaddr_in sin;
- struct hostent *hp;
+ struct hostent *hp = NULL;
#ifdef notyet
-#ifdef LDAP_REFERRALS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
int status; /* for ioctl call */
-#endif /* LDAP_REFERRALS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
#endif /* notyet */
-
- Debug( LDAP_DEBUG_TRACE, "connect_to_host: %s:%d\n",
- ( host == NULL ) ? "(by address)" : host, ntohs( port ), 0 );
+
+ /* buffers for ldap_int_gethostbyname_a */
+ struct hostent he_buf;
+ int local_h_errno;
+ char *ha_buf=NULL;
+#define DO_RETURN(x) if (ha_buf) free(ha_buf); return (x);
+
+ Debug( LDAP_DEBUG_TRACE, "ldap_connect_to_host: %s:%d\n",
+ ( host == NULL ) ? "(by address)" : host, (int) ntohs( (short) port ), 0 );
connected = use_hp = 0;
- if ( host != NULL && ( address = inet_addr( host )) == -1 ) {
- if ( (hp = gethostbyname( host )) == NULL ) {
+ if ( host != NULL ) {
+ address = inet_addr( host );
+ /* This was just a test for -1 until OSF1 let inet_addr return
+ unsigned int, which is narrower than 'unsigned long address' */
+ if ( address == 0xffffffff || address == (unsigned long) -1 ) {
+ if ( ( ldap_int_gethostbyname_a( host, &he_buf, &ha_buf,
+ &hp, &local_h_errno) < 0) || (hp==NULL))
+ {
+#ifdef HAVE_WINSOCK
+ errno = WSAGetLastError();
+#else
errno = EHOSTUNREACH; /* not exactly right, but... */
- return( -1 );
+#endif
+ DO_RETURN( -1 );
}
use_hp = 1;
+ }
}
rc = -1;
for ( i = 0; !use_hp || ( hp->h_addr_list[ i ] != 0 ); i++ ) {
if (( s = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
- return( -1 );
+ DO_RETURN( -1 );
}
#ifdef notyet
-#ifdef LDAP_REFERRALS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
status = 1;
if ( async && ioctl( s, FIONBIO, (caddr_t)&status ) == -1 ) {
Debug( LDAP_DEBUG_ANY, "FIONBIO ioctl failed on %d\n",
s, 0, 0 );
}
-#endif /* LDAP_REFERRALS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
#endif /* notyet */
(void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in ));
sin.sin_family = AF_INET;
rc = 0;
break;
} else {
+#ifdef HAVE_WINSOCK
+ errno = WSAGetLastError();
+#endif
#ifdef notyet
-#ifdef LDAP_REFERRALS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
#ifdef EAGAIN
if ( errno == EINPROGRESS || errno == EAGAIN ) {
#else /* EAGAIN */
rc = -2;
break;
}
-#endif /* LDAP_REFERRALS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
#endif /* notyet */
#ifdef LDAP_DEBUG
perror( (char *)inet_ntoa( sin.sin_addr ));
}
#endif
- close( s );
+ tcp_close( s );
if ( !use_hp ) {
break;
}
if ( connected ) {
#ifdef notyet
-#ifdef LDAP_REFERRALS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
status = 0;
if ( !async && ioctl( s, FIONBIO, (caddr_t)&on ) == -1 ) {
Debug( LDAP_DEBUG_ANY, "FIONBIO ioctl failed on %d\n",
s, 0, 0 );
}
-#endif /* LDAP_REFERRALS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
#endif /* notyet */
Debug( LDAP_DEBUG_TRACE, "sd %d connected to: %s\n",
- s, inet_ntoa( sin.sin_addr ), 0 );
+ s, (char *) inet_ntoa( sin.sin_addr ), 0 );
}
- return( rc );
+ DO_RETURN( rc );
+
+
}
+
+#undef DO_RETURN
void
-close_connection( Sockbuf *sb )
+ldap_close_connection( Sockbuf *sb )
{
tcp_close( sb->sb_sd );
}
-#ifdef KERBEROS
+#ifdef HAVE_KERBEROS
char *
-host_connected_to( Sockbuf *sb )
+ldap_host_connected_to( Sockbuf *sb )
{
struct hostent *hp;
char *p;
int len;
struct sockaddr_in sin;
+ /* buffers for gethostbyaddr_r */
+ struct hostent he_buf;
+ int local_h_errno;
+ char *ha_buf=NULL;
+#define DO_RETURN(x) if (ha_buf) free(ha_buf); return (x);
+
(void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in ));
len = sizeof( sin );
if ( getpeername( sb->sb_sd, (struct sockaddr *)&sin, &len ) == -1 ) {
* this is necessary for kerberos to work right, since the official
* hostname is used as the kerberos instance.
*/
- if (( hp = gethostbyaddr( (char *) &sin.sin_addr,
- sizeof( sin.sin_addr ), AF_INET )) != NULL ) {
+ if ((ldap_int_gethostbyaddr_a( (char *) &sin.sin_addr,
+ sizeof( sin.sin_addr ),
+ AF_INET, &he_buf, &ha_buf,
+ &hp,&local_h_errno ) ==0 ) && (hp != NULL) )
+ {
if ( hp->h_name != NULL ) {
- return( strdup( hp->h_name ));
+ DO_RETURN( ldap_strdup( hp->h_name ));
}
}
- return( NULL );
+ DO_RETURN( NULL );
}
-#endif /* KERBEROS */
+#undef DO_RETURN
+
+#endif /* HAVE_KERBEROS */
-#ifdef LDAP_REFERRALS
+#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
/* for UNIX */
struct selectinfo {
fd_set si_readfds;
void
-mark_select_write( LDAP *ld, Sockbuf *sb )
+ldap_mark_select_write( LDAP *ld, Sockbuf *sb )
{
struct selectinfo *sip;
sip = (struct selectinfo *)ld->ld_selectinfo;
if ( !FD_ISSET( sb->sb_sd, &sip->si_writefds )) {
- FD_SET( sb->sb_sd, &sip->si_writefds );
+ FD_SET( (u_int) sb->sb_sd, &sip->si_writefds );
}
}
void
-mark_select_read( LDAP *ld, Sockbuf *sb )
+ldap_mark_select_read( LDAP *ld, Sockbuf *sb )
{
struct selectinfo *sip;
sip = (struct selectinfo *)ld->ld_selectinfo;
if ( !FD_ISSET( sb->sb_sd, &sip->si_readfds )) {
- FD_SET( sb->sb_sd, &sip->si_readfds );
+ FD_SET( (u_int) sb->sb_sd, &sip->si_readfds );
}
}
void
-mark_select_clear( LDAP *ld, Sockbuf *sb )
+ldap_mark_select_clear( LDAP *ld, Sockbuf *sb )
{
struct selectinfo *sip;
sip = (struct selectinfo *)ld->ld_selectinfo;
- FD_CLR( sb->sb_sd, &sip->si_writefds );
- FD_CLR( sb->sb_sd, &sip->si_readfds );
+ FD_CLR( (u_int) sb->sb_sd, &sip->si_writefds );
+ FD_CLR( (u_int) sb->sb_sd, &sip->si_readfds );
}
int
-is_write_ready( LDAP *ld, Sockbuf *sb )
+ldap_is_write_ready( LDAP *ld, Sockbuf *sb )
{
struct selectinfo *sip;
int
-is_read_ready( LDAP *ld, Sockbuf *sb )
+ldap_is_read_ready( LDAP *ld, Sockbuf *sb )
{
struct selectinfo *sip;
void *
-new_select_info()
+ldap_new_select_info( void )
{
struct selectinfo *sip;
void
-free_select_info( void *sip )
+ldap_free_select_info( void *sip )
{
free( sip );
}
Debug( LDAP_DEBUG_TRACE, "do_ldap_select\n", 0, 0, 0 );
if ( tblsize == 0 ) {
-#ifdef USE_SYSCONF
+#if defined( HAVE_SYSCONF )
tblsize = sysconf( _SC_OPEN_MAX );
-#else /* USE_SYSCONF */
+#elif defined( HAVE_GETDTABLESIZE )
tblsize = getdtablesize();
-#endif /* USE_SYSCONF */
+#else
+ tblsize = FD_SETSIZE;
+#endif /* !USE_SYSCONF */
+
+#ifdef FD_SETSIZE
+ if( tblsize > FD_SETSIZE ) {
+ tblsize = FD_SETSIZE;
+ }
+#endif /* FD_SETSIZE*/
}
sip = (struct selectinfo *)ld->ld_selectinfo;
return( select( tblsize, &sip->si_use_readfds, &sip->si_use_writefds,
NULL, timeout ));
}
-#endif /* LDAP_REFERRALS */
+#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */