Exemplo n.º 1
0
/*
 * returns -1 if a fatal error occurs.  If async is non-zero and the flush
 * would block, -2 is returned.
 */
int
nsldapi_ber_flush( LDAP *ld, Sockbuf *sb, BerElement *ber, int freeit,
	int async )
{
	int	terrno;

	for ( ;; ) {
		 /*
		  * ber_flush() doesn't set errno on EOF, so we pre-set it to
		  * zero to avoid getting tricked by leftover "EAGAIN" errors
		  */
		LDAP_SET_ERRNO( ld, 0 );

		if ( ber_flush( sb, ber, freeit ) == 0 ) {
			return( 0 );	/* success */
		}

		terrno = LDAP_GET_ERRNO( ld );

        if (ld->ld_options & LDAP_BITOPT_ASYNC) {
            if ( terrno != 0 && !NSLDAPI_ERRNO_IO_INPROGRESS( terrno )) {
                nsldapi_connection_lost_nolock( ld, sb );
                return( -1 );	/* fatal error */
            }
        }
        else if ( !NSLDAPI_ERRNO_IO_INPROGRESS( terrno )) {

			nsldapi_connection_lost_nolock( ld, sb );
			return( -1 );	/* fatal error */
		}

		if ( async ) {
			return( -2 );	/* would block */
		}
	}
}
Exemplo n.º 2
0
int
nsldapi_connect_to_host( LDAP *ld, Sockbuf *sb, char *host, unsigned long address,
	int port, int async, int secure )
/*
 * 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
 * if -1 is returned, ld_errno is set
 * async is only used ifndef NO_REFERRALS (non-0 means don't wait for connect)
 * XXX async is not used yet!
 */
{
	void			*tcps;
	short 			i;
	int				err;
    InetHostInfo	hi;

	LDAPDebug( LDAP_DEBUG_TRACE, "connect_to_host: %s:%d\n",
	    ( host == NULL ) ? "(by address)" : host, ntohs( port ), 0 );

	/* Initialize OpenTransport, or find out from the host app whether it is installed */
	(void)tcp_init();
	
	if ( host != NULL && gethostinfobyname( host, &hi ) != noErr ) {
		LDAP_SET_LDERRNO( ld, LDAP_CONNECT_ERROR, NULL, NULL );
		return( -1 );
	}

	if ( ld->ld_socket_fn == NULL ) {
		tcps = tcpopen( NULL, TCP_BUFSIZ );
	} else {
		tcps = ld->ld_socket_fn( AF_INET, SOCK_STREAM, 0 );
	}

	if ( tcps == NULL ) {
		LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
		return( -1 );
	}

	if ( secure && ld->ld_ssl_enable_fn( tcps ) < 0 ) {
		if ( ld->ld_close_fn == NULL ) {
			tcpclose( (tcpstream *)tcps );
		} else {
			ld->ld_close_fn( tcps );
		}
		LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
		return( -1 );
	}

    for ( i = 0; host == NULL || hi.addrs[ i ] != 0; ++i ) {
    	if ( host != NULL ) {
			SAFEMEMCPY( (char *)&address, (char *)&hi.addrs[ i ], sizeof( long ));
		}


		if ( ld->ld_connect_fn == NULL ) {
			if ( tcpconnect( tcps, address, port ) == 0 ) {
				err = -1;
			} else {
				err = 0;
			}
		} else {
			struct sockaddr_in	sin;
			(void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in ));
			sin.sin_family = AF_INET;
			sin.sin_port = port;
			sin.sin_addr.s_addr = address;

			err = ld->ld_connect_fn( tcps, (struct sockaddr *)&sin,
				sizeof( struct sockaddr_in ));
		}

		if ( err == 0 ) {
			sb->sb_sd = (void *)tcps;
			return( 0 );
		}

		if ( host == NULL ) {	/* using single address -- not hi.addrs array */
			break;
		}
	}
	
	LDAPDebug( LDAP_DEBUG_TRACE, "tcpconnect failed\n", 0, 0, 0 );
	LDAP_SET_LDERRNO( ld, LDAP_CONNECT_ERROR, NULL, NULL );
	LDAP_SET_ERRNO( ld, EHOSTUNREACH );  /* close enough */

	if ( ld->ld_close_fn == NULL ) {
		tcpclose( (tcpstream *)tcps );
	} else {
		ld->ld_close_fn( tcps );
	}
	return( -1 );
}