--- libraries/libldap/result.c 2003/02/28 12:41:53 1.84 +++ libraries/libldap/result.c 2004/08/31 00:08:28 1.84.2.6 @@ -1,14 +1,22 @@ -/* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.83 2003/02/28 11:57:28 hyc Exp $ */ -/* - * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* result.c - wait for an ldap result */ +/* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.94 2004/07/24 01:13:29 hyc Exp $ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2004 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ -/* Portions - * Copyright (c) 1990 Regents of the University of Michigan. - * All rights reserved. +/* Portions Copyright (c) 1990 Regents of the University of Michigan. + * All rights reserved. */ -/*--- - * This notice applies to changes, created by or for Novell, Inc., +/* This notice applies to changes, created by or for Novell, Inc., * to preexisting works for which notices appear elsewhere in this file. * * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved. @@ -24,13 +32,14 @@ *--- * Modification to OpenLDAP source by Novell, Inc. * April 2000 sfs Add code to process V3 referrals and search results - * - * result.c - wait for an ldap result - */ -/* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License + *--- + * Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License * can be found in the file "build/LICENSE-2.0.1" in this distribution * of OpenLDAP Software. */ +/* Portions Copyright (C) The Internet Society (1997) + * ASN.1 fragments are from RFC 2251; see RFC for full legal notices. + */ /* * LDAPv3 (RFC2251) @@ -64,7 +73,7 @@ static int ldap_mark_abandoned LDAP_P(( static int wait4msg LDAP_P(( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout, LDAPMessage **result )); static ber_tag_t try_read1msg LDAP_P(( LDAP *ld, ber_int_t msgid, - int all, Sockbuf *sb, LDAPConn *lc, LDAPMessage **result )); + int all, Sockbuf *sb, LDAPConn **lc, LDAPMessage **result )); static ber_tag_t build_result_ber LDAP_P(( LDAP *ld, BerElement **bp, LDAPRequest *lr )); static void merge_error_info LDAP_P(( LDAP *ld, LDAPRequest *parentr, LDAPRequest *lr )); static LDAPMessage * chkResponseList LDAP_P(( LDAP *ld, int msgid, int all)); @@ -185,7 +194,7 @@ chkResponseList( for ( tmp = lm; tmp != NULL; tmp = tmp->lm_chain ) { if ( tmp->lm_msgtype != LDAP_RES_SEARCH_ENTRY && tmp->lm_msgtype != LDAP_RES_SEARCH_REFERENCE - && tmp->lm_msgtype != LDAP_RES_EXTENDED_PARTIAL ) + && tmp->lm_msgtype != LDAP_RES_INTERMEDIATE ) { break; } @@ -305,17 +314,20 @@ wait4msg( if( (*result = chkResponseList(ld, msgid, all)) != NULL ) { rc = (*result)->lm_msgtype; } else { + int lc_ready = 0; - for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) { + for ( lc = ld->ld_conns; lc != NULL; lc = nextlc ) { + nextlc = lc->lconn_next; if ( ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_DATA_READY, NULL ) ) { - rc = try_read1msg( ld, msgid, all, lc->lconn_sb, - lc, result ); + rc = try_read1msg( ld, msgid, all, lc->lconn_sb, + &lc, result ); + lc_ready = 1; break; } } - if ( lc == NULL ) { + if ( !lc_ready ) { rc = ldap_int_select( ld, tvp ); #ifdef LDAP_DEBUG if ( rc == -1 ) { @@ -364,7 +376,8 @@ wait4msg( ldap_is_read_ready( ld, lc->lconn_sb )) { rc = try_read1msg( ld, msgid, all, - lc->lconn_sb, lc, result ); + lc->lconn_sb, &lc, result ); + if ( lc == NULL ) lc = nextlc; } } } @@ -400,7 +413,7 @@ try_read1msg( ber_int_t msgid, int all, Sockbuf *sb, - LDAPConn *lc, + LDAPConn **lcp, LDAPMessage **result ) { BerElement *ber; @@ -410,6 +423,7 @@ try_read1msg( ber_len_t len; int foundit = 0; LDAPRequest *lr, *tmplr; + LDAPConn *lc; BerElement tmpber; int rc, refer_cnt, hadref, simple_request; ber_int_t lderr; @@ -423,7 +437,8 @@ try_read1msg( int v3ref; assert( ld != NULL ); - assert( lc != NULL ); + assert( lcp != NULL ); + assert( *lcp != NULL ); #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ARGS, "read1msg: msgid %d, all %d\n", msgid, all, 0 ); @@ -431,6 +446,8 @@ try_read1msg( Debug( LDAP_DEBUG_TRACE, "read1msg: msgid %d, all %d\n", msgid, all, 0 ); #endif + lc = *lcp; + retry: if ( lc->lconn_ber == NULL ) { lc->lconn_ber = ldap_alloc_ber_with_options(ld); @@ -660,11 +677,9 @@ nextresp2: * go through the following code. This code also chases V2 referrals * and checks if all referrals have been chased. */ - if ( (tag != LDAP_RES_SEARCH_ENTRY) && (v3ref > -1) -#ifdef LDAP_RES_INTERMEDIATE_RESP - && (tag != LDAP_RES_INTERMEDIATE_RESP ) -#endif - ) { + if ( (tag != LDAP_RES_SEARCH_ENTRY) && (v3ref > -1) && + (tag != LDAP_RES_INTERMEDIATE )) + { /* For a v3 search referral/reference, only come here if already chased it */ if ( ld->ld_version >= LDAP_VERSION2 && ( lr->lr_parent != NULL || @@ -808,6 +823,7 @@ lr->lr_res_matched ? lr->lr_res_matched if ( lc != NULL ) { ldap_free_connection( ld, lc, 0, 1 ); + *lcp = NULL; } } } @@ -957,7 +973,7 @@ lr->lr_res_matched ? lr->lr_res_matched for ( tmp = l; (tmp->lm_chain != NULL) && ((tmp->lm_chain->lm_msgtype == LDAP_RES_SEARCH_ENTRY) || (tmp->lm_chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE) || - (tmp->lm_chain->lm_msgtype == LDAP_RES_EXTENDED_PARTIAL )); + (tmp->lm_chain->lm_msgtype == LDAP_RES_INTERMEDIATE )); tmp = tmp->lm_chain ) ; /* NULL */ tmp->lm_chain = new; @@ -1109,7 +1125,7 @@ char * ldap_int_msgtype2str( ber_tag_t t case LDAP_RES_COMPARE: return "compare"; case LDAP_RES_DELETE: return "delete"; case LDAP_RES_EXTENDED: return "extended-result"; - case LDAP_RES_EXTENDED_PARTIAL: return "extended-partial"; + case LDAP_RES_INTERMEDIATE: return "intermediate"; case LDAP_RES_MODIFY: return "modify"; case LDAP_RES_RENAME: return "rename"; case LDAP_RES_SEARCH_ENTRY: return "search-entry";