}
#endif
+int
+ldap_int_connect_cbs(LDAP *ld, Sockbuf *sb, ber_socket_t *s, const char *host, struct sockaddr *addr)
+{
+ struct ldapoptions *lo;
+ ldaplist *ll;
+ ldap_conncb *cb;
+ int rc;
+
+ ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, s );
+
+ /* Invoke all handle-specific callbacks first */
+ lo = &ld->ld_options;
+ for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
+ cb = ll->ll_data;
+ rc = cb->lc_add( ld, sb, host, addr, cb );
+ /* on any failure, call the teardown functions for anything
+ * that previously succeeded
+ */
+ if ( rc ) {
+ ldaplist *l2;
+ for (l2 = lo->ldo_conn_cbs; l2 != ll; l2 = l2->ll_next) {
+ cb = l2->ll_data;
+ cb->lc_del( ld, sb, cb );
+ }
+ /* a failure might have implicitly closed the fd */
+ ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, s );
+ return rc;
+ }
+ }
+ lo = LDAP_INT_GLOBAL_OPT();
+ for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
+ cb = ll->ll_data;
+ rc = cb->lc_add( ld, sb, host, addr, cb );
+ if ( rc ) {
+ ldaplist *l2;
+ for (l2 = lo->ldo_conn_cbs; l2 != ll; l2 = l2->ll_next) {
+ cb = l2->ll_data;
+ cb->lc_del( ld, sb, cb );
+ }
+ lo = &ld->ld_options;
+ for (l2 = lo->ldo_conn_cbs; l2; l2 = l2->ll_next) {
+ cb = l2->ll_data;
+ cb->lc_del( ld, sb, cb );
+ }
+ ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, s );
+ return rc;
+ }
+ }
+ return 0;
+}
int
ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
rc = ldap_pvt_connect( ld, s,
sai->ai_addr, sai->ai_addrlen, async );
if ( rc == 0 || rc == -2 ) {
- ldaplist *ll;
- struct ldapoptions *lo;
- ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
- lo = &ld->ld_options;
- for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
- ldap_conncb *cb = ll->ll_data;
- cb->lc_add( ld, sb, host, sai->ai_addr, cb );
- }
- lo = LDAP_INT_GLOBAL_OPT();
- for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
- ldap_conncb *cb = ll->ll_data;
- cb->lc_add( ld, sb, host, sai->ai_addr, cb );
- }
- break;
+ err = ldap_int_connect_cbs( ld, sb, &s, host, sai->ai_addr );
+ if ( err )
+ rc = err;
+ else
+ break;
}
ldap_pvt_close_socket(ld, s);
}
async);
if ( (rc == 0) || (rc == -2) ) {
- ldaplist *ll;
- struct ldapoptions *lo;
- ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
- lo = &ld->ld_options;
- for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
- ldap_conncb *cb = ll->ll_data;
- cb->lc_add( ld, sb, host, (struct sockaddr *)&sin, cb );
- }
- lo = LDAP_INT_GLOBAL_OPT();
- for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
- ldap_conncb *cb = ll->ll_data;
- cb->lc_add( ld, sb, host, (struct sockaddr *)&sin, cb );
- }
- break;
+ i = ldap_int_connect_cbs( ld, sb, &s, host, (struct sockaddr *)&sin );
+ if ( i )
+ rc = i;
+ else
+ break;
}
ldap_pvt_close_socket(ld, s);
rc = ldap_pvt_connect(ld, s, &server, async);
if (rc == 0) {
- ldaplist *ll;
- struct ldapoptions *lo;
- ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, (void *)&s );
- lo = &ld->ld_options;
- for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
- ldap_conncb *cb = ll->ll_data;
- cb->lc_add( ld, sb, path, (struct sockaddr *)&server, cb );
- }
- lo = LDAP_INT_GLOBAL_OPT();
- for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
- ldap_conncb *cb = ll->ll_data;
- cb->lc_add( ld, sb, path, (struct sockaddr *)&server, cb );
- }
- } else {
+ int err;
+ err = ldap_int_connect_cbs( ld, sb, &s, path, (struct sockaddr *)&server );
+ if ( err )
+ rc = err;
+ }
+ if ( rc ) {
ldap_pvt_close_socket(ld, s);
}
return rc;