Diff for /libraries/libldap/result.c between versions 1.138 and 1.139

version 1.138, 2006/11/12 13:22:25 version 1.139, 2006/12/03 19:56:26
Line 1 Line 1
 /* result.c - wait for an ldap result */  /* result.c - wait for an ldap result */
 /* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.137 2006/10/28 14:19:08 ando Exp $ */  /* $OpenLDAP: pkg/ldap/libraries/libldap/result.c,v 1.138 2006/11/12 13:22:25 ando Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
  * Copyright 1998-2006 The OpenLDAP Foundation.   * Copyright 1998-2006 The OpenLDAP Foundation.
Line 64 Line 64
   
 #include "ldap-int.h"  #include "ldap-int.h"
 #include "ldap_log.h"  #include "ldap_log.h"
   #include "lutil.h"
   
 static int ldap_abandoned_idx LDAP_P(( LDAP *ld, ber_int_t msgid ));  static int ldap_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid, int *idx ));
 #define ldap_abandoned(ld, msgid)       ( ldap_abandoned_idx((ld), (msgid)) > -1 )  static int ldap_mark_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid, int idx ));
 static int ldap_mark_abandoned LDAP_P(( LDAP *ld, ber_int_t msgid ));  
 static int wait4msg LDAP_P(( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout,  static int wait4msg LDAP_P(( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout,
         LDAPMessage **result ));          LDAPMessage **result ));
 static ber_tag_t try_read1msg LDAP_P(( LDAP *ld, ber_int_t msgid,  static ber_tag_t try_read1msg LDAP_P(( LDAP *ld, ber_int_t msgid,
Line 164  chkResponseList( Line 164  chkResponseList(
   
         lastlm = &ld->ld_responses;          lastlm = &ld->ld_responses;
         for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) {          for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) {
                   int     idx;
   
                 nextlm = lm->lm_next;                  nextlm = lm->lm_next;
                 ++cnt;                  ++cnt;
   
                 if ( ldap_abandoned( ld, lm->lm_msgid ) ) {                  if ( ldap_abandoned( ld, lm->lm_msgid, &idx ) ) {
                         Debug( LDAP_DEBUG_TRACE,                          Debug( LDAP_DEBUG_ANY,
                                 "ldap_chkResponseList msg abandoned, msgid %d\n",                                  "response list msg abandoned, "
                                 msgid, 0, 0 );                                  "msgid %d message type %s\n",
                         ldap_mark_abandoned( ld, lm->lm_msgid );                                  lm->lm_msgid, ldap_int_msgtype2str( lm->lm_msgtype ), 0 );
   
                           switch ( lm->lm_msgtype ) {
                           case LDAP_RES_SEARCH_ENTRY:
                           case LDAP_RES_SEARCH_REFERENCE:
                           case LDAP_RES_INTERMEDIATE:
                                   break;
   
                           default:
                                   /* there's no need to keep the id
                                    * in the abandoned list any longer */
                                   ldap_mark_abandoned( ld, lm->lm_msgid, idx );
                                   break;
                           }
   
                         /* Remove this entry from list */                          /* Remove this entry from list */
                         *lastlm = nextlm;                          *lastlm = nextlm;
Line 184  chkResponseList( Line 199  chkResponseList(
                 if ( msgid == LDAP_RES_ANY || lm->lm_msgid == msgid ) {                  if ( msgid == LDAP_RES_ANY || lm->lm_msgid == msgid ) {
                         LDAPMessage     *tmp;                          LDAPMessage     *tmp;
   
                         if ( all == LDAP_MSG_ONE || all == LDAP_MSG_RECEIVED ||                          if ( all == LDAP_MSG_ONE ||
                                   all == LDAP_MSG_RECEIVED ||
                                 msgid == LDAP_RES_UNSOLICITED )                                  msgid == LDAP_RES_UNSOLICITED )
                         {                          {
                                 break;                                  break;
                         }                          }
   
                         tmp = lm->lm_chain_tail;                          tmp = lm->lm_chain_tail;
                         if ( (tmp->lm_msgtype == LDAP_RES_SEARCH_ENTRY) ||                          if ( tmp->lm_msgtype == LDAP_RES_SEARCH_ENTRY ||
                                 (tmp->lm_msgtype == LDAP_RES_SEARCH_REFERENCE) ||                                  tmp->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ||
                                 (tmp->lm_msgtype == LDAP_RES_INTERMEDIATE) )                                  tmp->lm_msgtype == LDAP_RES_INTERMEDIATE )
                         {                          {
                                 tmp = NULL;                                  tmp = NULL;
                         }                          }
Line 207  chkResponseList( Line 223  chkResponseList(
                 lastlm = &lm->lm_next;                  lastlm = &lm->lm_next;
         }          }
   
 #if 0  
         {  
                 char    buf[ BUFSIZ ];  
   
                 snprintf( buf, sizeof( buf ), "ld=%p msgid=%d%s cnt=%d",  
                         ld, msgid, all ? " all" : "", cnt );  
                 Debug( LDAP_DEBUG_TRACE, "+++ chkResponseList %s\n", buf, 0, 0 );  
         }  
 #endif  
   
         if ( lm != NULL ) {          if ( lm != NULL ) {
                 /* Found an entry, remove it from the list */                  /* Found an entry, remove it from the list */
                 if ( all == LDAP_MSG_ONE && lm->lm_chain != NULL ) {                  if ( all == LDAP_MSG_ONE && lm->lm_chain != NULL ) {
Line 238  chkResponseList( Line 244  chkResponseList(
         } else {          } else {
                 Debug( LDAP_DEBUG_TRACE,                  Debug( LDAP_DEBUG_TRACE,
                         "ldap_chkResponseList returns ld %p msgid %d, type 0x%02lu\n",                          "ldap_chkResponseList returns ld %p msgid %d, type 0x%02lu\n",
                         (void *)ld, lm->lm_msgid, (unsigned long) lm->lm_msgtype );                          (void *)ld, lm->lm_msgid, (unsigned long)lm->lm_msgtype );
         }          }
 #endif  #endif
     return lm;  
           return lm;
 }  }
   
 static int  static int
Line 318  wait4msg( Line 325  wait4msg(
 #endif  #endif
                         for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {                          for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {
                                 if ( ber_sockbuf_ctrl( lc->lconn_sb,                                  if ( ber_sockbuf_ctrl( lc->lconn_sb,
                                                 LBER_SB_OPT_DATA_READY, NULL ) )                                          LBER_SB_OPT_DATA_READY, NULL ) )
                                 {                                  {
 #ifdef LDAP_R_COMPILE  #ifdef LDAP_R_COMPILE
                                         ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );                                          ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
Line 440  try_read1msg( Line 447  try_read1msg(
         BerElement      *ber;          BerElement      *ber;
         LDAPMessage     *newmsg, *l, *prev;          LDAPMessage     *newmsg, *l, *prev;
         ber_int_t       id;          ber_int_t       id;
           int             idx;
         ber_tag_t       tag;          ber_tag_t       tag;
         ber_len_t       len;          ber_len_t       len;
         int             foundit = 0;          int             foundit = 0;
Line 481  retry: Line 489  retry:
         if ( lc->lconn_ber == NULL ) {          if ( lc->lconn_ber == NULL ) {
                 lc->lconn_ber = ldap_alloc_ber_with_options( ld );                  lc->lconn_ber = ldap_alloc_ber_with_options( ld );
   
                 if( lc->lconn_ber == NULL ) {                  if ( lc->lconn_ber == NULL ) {
                         return -1;                          return -1;
                 }                  }
         }          }
Line 495  retry: Line 503  retry:
         if ( LDAP_IS_UDP(ld) ) {          if ( LDAP_IS_UDP(ld) ) {
                 struct sockaddr from;                  struct sockaddr from;
                 ber_int_sb_read( lc->lconn_sb, &from, sizeof(struct sockaddr) );                  ber_int_sb_read( lc->lconn_sb, &from, sizeof(struct sockaddr) );
                 if (ld->ld_options.ldo_version == LDAP_VERSION2) isv2 = 1;                  if ( ld->ld_options.ldo_version == LDAP_VERSION2 ) isv2 = 1;
         }          }
 nextresp3:  nextresp3:
 #endif  #endif
Line 536  nextresp3: Line 544  nextresp3:
         }          }
   
         /* if it's been abandoned, toss it */          /* if it's been abandoned, toss it */
         if ( ldap_abandoned( ld, id ) ) {          if ( ldap_abandoned( ld, id, &idx ) ) {
                 Debug( LDAP_DEBUG_ANY, "abandoned/discarded ld %p msgid %ld\n",                  /* the message type */
                         (void *)ld, (long) id, 0);                  tag = ber_peek_tag( ber, &len );
                   switch ( tag ) {
                   case LDAP_RES_SEARCH_ENTRY:
                   case LDAP_RES_SEARCH_REFERENCE:
                   case LDAP_RES_INTERMEDIATE:
                   case LBER_ERROR:
                           break;
   
                   default:
                           /* there's no need to keep the id
                            * in the abandoned list any longer */
                           ldap_mark_abandoned( ld, id, idx );
                           break;
                   }
   
                   Debug( LDAP_DEBUG_ANY,
                           "abandoned/discarded ld %p msgid %ld message type %s\n",
                           (void *)ld, (long)id, ldap_int_msgtype2str( tag ) );
   
 retry_ber:  retry_ber:
                 ber_free( ber, 1 );                  ber_free( ber, 1 );
                 if ( ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_DATA_READY, NULL ) ) {                  if ( ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_DATA_READY, NULL ) ) {
Line 549  retry_ber: Line 575  retry_ber:
   
         lr = ldap_find_request_by_msgid( ld, id );          lr = ldap_find_request_by_msgid( ld, id );
         if ( lr == NULL ) {          if ( lr == NULL ) {
                   const char      *msg = "unknown";
   
                   /* the message type */
                   tag = ber_peek_tag( ber, &len );
                   switch ( tag ) {
                   case LBER_ERROR:
                           break;
   
                   default:
                           msg = ldap_int_msgtype2str( tag );
                           break;
                   }
   
                 Debug( LDAP_DEBUG_ANY,                  Debug( LDAP_DEBUG_ANY,
                         "no request for response on ld %p msgid %ld (tossing)\n",                          "no request for response on ld %p msgid %ld message type %s (tossing)\n",
                         (void *)ld, (long)id, 0 );                          (void *)ld, (long)id, msg );
   
                 goto retry_ber;                  goto retry_ber;
         }          }
 #ifdef LDAP_CONNECTIONLESS  #ifdef LDAP_CONNECTIONLESS
         if (LDAP_IS_UDP(ld) && isv2) {          if ( LDAP_IS_UDP(ld) && isv2 ) {
                 ber_scanf(ber, "x{");                  ber_scanf(ber, "x{");
         }          }
 nextresp2:  nextresp2:
 #endif  #endif
         /* the message type */          /* the message type */
         if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {          tag = ber_peek_tag( ber, &len );
           if ( tag == LBER_ERROR ) {
                 ld->ld_errno = LDAP_DECODING_ERROR;                  ld->ld_errno = LDAP_DECODING_ERROR;
                 ber_free( ber, 1 );                  ber_free( ber, 1 );
                 return( -1 );                  return( -1 );
Line 569  nextresp2: Line 610  nextresp2:
   
         Debug( LDAP_DEBUG_TRACE,          Debug( LDAP_DEBUG_TRACE,
                 "read1msg: ld %p msgid %ld message type %s\n",                  "read1msg: ld %p msgid %ld message type %s\n",
                 (void *)ld, (long) lr->lr_msgid, ldap_int_msgtype2str( tag ));                  (void *)ld, (long)lr->lr_msgid, ldap_int_msgtype2str( tag ) );
   
         id = lr->lr_origid;          id = lr->lr_origid;
         refer_cnt = 0;          refer_cnt = 0;
Line 582  nextresp2: Line 623  nextresp2:
          * referral / search reference, or pass it back to the application           * referral / search reference, or pass it back to the application
          */           */
         v3ref = V3REF_NOREF;    /* Assume not a V3 search reference/referral */          v3ref = V3REF_NOREF;    /* Assume not a V3 search reference/referral */
         if( (tag != LDAP_RES_SEARCH_ENTRY) && (ld->ld_version > LDAP_VERSION2) ) {          if ( tag != LDAP_RES_SEARCH_ENTRY && ld->ld_version > LDAP_VERSION2 ) {
                 BerElement      tmpber = *ber;  /* struct copy */                  BerElement      tmpber = *ber;  /* struct copy */
                 char **refs = NULL;                  char            **refs = NULL;
   
                 if( tag == LDAP_RES_SEARCH_REFERENCE ) {                  if ( tag == LDAP_RES_SEARCH_REFERENCE ) {
                         /* This is a V3 search reference */                          /* This is a V3 search reference */
                         /* Assume we do not chase the reference,                          /* Assume we do not chase the reference,
                          * but pass it to application */                           * but pass it to application */
                         v3ref = V3REF_TOAPP;                          v3ref = V3REF_TOAPP;
                         if( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) ||                          if ( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) ||
                                         (lr->lr_parent != NULL) )                                          lr->lr_parent != NULL )
                         {                          {
                                 /* Get the referral list */                                  /* Get the referral list */
                                 if ( ber_scanf( &tmpber, "{v}", &refs ) == LBER_ERROR ) {                                  if ( ber_scanf( &tmpber, "{v}", &refs ) == LBER_ERROR ) {
Line 601  nextresp2: Line 642  nextresp2:
                                 } else {                                  } else {
                                         /* Note: refs array is freed by ldap_chase_v3referrals */                                          /* Note: refs array is freed by ldap_chase_v3referrals */
                                         refer_cnt = ldap_chase_v3referrals( ld, lr, refs,                                          refer_cnt = ldap_chase_v3referrals( ld, lr, refs,
                                             1, &lr->lr_res_error, &hadref );                                                  1, &lr->lr_res_error, &hadref );
                                         if ( refer_cnt > 0 ) {                                          if ( refer_cnt > 0 ) {
                                                 /* sucessfully chased reference */                                                  /* sucessfully chased reference */
                                                 /* If haven't got end search, set chasing referrals */                                                  /* If haven't got end search, set chasing referrals */
Line 611  nextresp2: Line 652  nextresp2:
                                                                 "read1msg:  search ref chased, "                                                                  "read1msg:  search ref chased, "
                                                                 "mark request chasing refs, "                                                                  "mark request chasing refs, "
                                                                 "id = %d\n",                                                                  "id = %d\n",
                                                                 lr->lr_msgid, 0, 0);                                                                  lr->lr_msgid, 0, 0 );
                                                 }                                                  }
   
                                                 /* We sucessfully chased the reference */                                                  /* We sucessfully chased the reference */
Line 644  nextresp2: Line 685  nextresp2:
                                 if ( ber_peek_tag( &tmpber, &len ) == LDAP_TAG_REFERRAL ) {                                  if ( ber_peek_tag( &tmpber, &len ) == LDAP_TAG_REFERRAL ) {
                                         /* We have a V3 referral, assume we cannot chase it */                                          /* We have a V3 referral, assume we cannot chase it */
                                         v3ref = V3REF_TOAPP;                                          v3ref = V3REF_TOAPP;
                                         if( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS)                                          if ( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS)
                                                          || (lr->lr_parent != NULL) )                                                           || lr->lr_parent != NULL )
                                         {                                          {
                                                 /* Assume referral not chased and return it to app */                                                  /* Assume referral not chased and return it to app */
                                                 v3ref = V3REF_TOAPP;                                                  v3ref = V3REF_TOAPP;
   
                                                 /* Get the referral list */                                                  /* Get the referral list */
                                                 if( ber_scanf( &tmpber, "{v}", &refs) == LBER_ERROR) {                                                  if ( ber_scanf( &tmpber, "{v}", &refs) == LBER_ERROR) {
                                                         rc = LDAP_DECODING_ERROR;                                                          rc = LDAP_DECODING_ERROR;
                                                         lr->lr_status = LDAP_REQST_COMPLETED;                                                          lr->lr_status = LDAP_REQST_COMPLETED;
                                                         Debug( LDAP_DEBUG_TRACE,                                                          Debug( LDAP_DEBUG_TRACE,
                                                                 "read1msg: referral decode error, mark request completed, ld %p msgid %d\n",                                                                  "read1msg: referral decode error, "
                                                                 (void *)ld, lr->lr_msgid, 0);                                                                  "mark request completed, ld %p msgid %d\n",
                                                                   (void *)ld, lr->lr_msgid, 0 );
   
                                                 } else {                                                  } else {
                                                         /* Chase the referral                                                           /* Chase the referral 
Line 666  nextresp2: Line 708  nextresp2:
                                                                 0, &lr->lr_res_error, &hadref );                                                                  0, &lr->lr_res_error, &hadref );
                                                         lr->lr_status = LDAP_REQST_COMPLETED;                                                          lr->lr_status = LDAP_REQST_COMPLETED;
                                                         Debug( LDAP_DEBUG_TRACE,                                                          Debug( LDAP_DEBUG_TRACE,
                                                                 "read1msg: referral chased, mark request completed, ld %p msgid %d\n",                                                                  "read1msg: referral chased, "
                                                                   "mark request completed, ld %p msgid %d\n",
                                                                 (void *)ld, lr->lr_msgid, 0);                                                                  (void *)ld, lr->lr_msgid, 0);
                                                         if( refer_cnt > 0) {                                                          if ( refer_cnt > 0 ) {
                                                                 /* Referral successfully chased */                                                                  /* Referral successfully chased */
                                                                 v3ref = V3REF_SUCCESS;                                                                  v3ref = V3REF_SUCCESS;
                                                         }                                                          }
Line 676  nextresp2: Line 719  nextresp2:
                                         }                                          }
                                 }                                  }
   
                                 if( lr->lr_res_matched != NULL ) {                                  if ( lr->lr_res_matched != NULL ) {
                                         LDAP_FREE( lr->lr_res_matched );                                          LDAP_FREE( lr->lr_res_matched );
                                         lr->lr_res_matched = NULL;                                          lr->lr_res_matched = NULL;
                                 }                                  }
   
                                 if( lr->lr_res_error != NULL ) {                                  if ( lr->lr_res_error != NULL ) {
                                         LDAP_FREE( lr->lr_res_error );                                          LDAP_FREE( lr->lr_res_error );
                                         lr->lr_res_error = NULL;                                          lr->lr_res_error = NULL;
                                 }                                  }
Line 693  nextresp2: Line 736  nextresp2:
          * go through the following code.  This code also chases V2 referrals           * go through the following code.  This code also chases V2 referrals
          * and checks if all referrals have been chased.           * and checks if all referrals have been chased.
          */           */
         if ( (tag != LDAP_RES_SEARCH_ENTRY) && (v3ref != V3REF_TOAPP) &&          if ( tag != LDAP_RES_SEARCH_ENTRY &&
                 (tag != LDAP_RES_INTERMEDIATE ))                  v3ref != V3REF_TOAPP &&
                   tag != LDAP_RES_INTERMEDIATE )
         {          {
                 /* For a v3 search referral/reference, only come here if already chased it */                  /* For a v3 search referral/reference, only come here if already chased it */
                 if ( ld->ld_version >= LDAP_VERSION2 &&                  if ( ld->ld_version >= LDAP_VERSION2 &&
Line 734  nextresp2: Line 778  nextresp2:
                                         break;                                          break;
   
                                 default:                                  default:
                                         if ( lr->lr_res_error == NULL                                          if ( lr->lr_res_error == NULL ||
                                                 || lr->lr_res_error[ 0 ] == '\0' )                                                  lr->lr_res_error[ 0 ] == '\0' )
                                         {                                          {
                                                 break;                                                  break;
                                         }                                          }
Line 753  nextresp2: Line 797  nextresp2:
   
                                 /* save errno, message, and matched string */                                  /* save errno, message, and matched string */
                                 if ( !hadref || lr->lr_res_error == NULL ) {                                  if ( !hadref || lr->lr_res_error == NULL ) {
                                         lr->lr_res_errno = ( lderr ==                                          lr->lr_res_errno =
                                         LDAP_PARTIAL_RESULTS ) ? LDAP_SUCCESS                                                  lderr == LDAP_PARTIAL_RESULTS
                                         : lderr;                                                  ? LDAP_SUCCESS : lderr;
   
                                 } else if ( ld->ld_errno != LDAP_SUCCESS ) {                                  } else if ( ld->ld_errno != LDAP_SUCCESS ) {
                                         lr->lr_res_errno = ld->ld_errno;                                          lr->lr_res_errno = ld->ld_errno;
Line 828  nextresp2: Line 872  nextresp2:
                         }                          }
   
                         /* This is the parent request if the request has referrals */                          /* This is the parent request if the request has referrals */
                         if ( lr->lr_outrefcnt <= 0 && lr->lr_parent == NULL &&                          if ( lr->lr_outrefcnt <= 0 &&
                                   lr->lr_parent == NULL &&
                                 tmplr == NULL )                                  tmplr == NULL )
                         {                          {
                                 id = lr->lr_msgid;                                  id = lr->lr_msgid;
                                 tag = lr->lr_res_msgtype;                                  tag = lr->lr_res_msgtype;
                                 Debug( LDAP_DEBUG_ANY, "request done: ld %p msgid %ld\n",                                  Debug( LDAP_DEBUG_ANY, "request done: ld %p msgid %ld\n",
                                         (void *)ld, (long) id, 0 );                                          (void *)ld, (long) id, 0 );
 Debug( LDAP_DEBUG_TRACE,                                  Debug( LDAP_DEBUG_TRACE,
 "res_errno: %d, res_error: <%s>, res_matched: <%s>\n",                                          "res_errno: %d, res_error: <%s>, "
 lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "",                                          "res_matched: <%s>\n",
 lr->lr_res_matched ? lr->lr_res_matched : "" );                                          lr->lr_res_errno,
                                           lr->lr_res_error ? lr->lr_res_error : "",
                                           lr->lr_res_matched ? lr->lr_res_matched : "" );
                                 if ( !simple_request ) {                                  if ( !simple_request ) {
                                         ber_free( ber, 1 );                                          ber_free( ber, 1 );
                                         ber = NULL;                                          ber = NULL;
Line 908  lr->lr_res_matched ? lr->lr_res_matched Line 955  lr->lr_res_matched ? lr->lr_res_matched
                                  */                                   */
                                 ber = ber_dup( ber );                                  ber = ber_dup( ber );
                                 ber_scanf( ber, "x" );                                  ber_scanf( ber, "x" );
                                 if (ber_peek_tag(ber, &len) != LBER_DEFAULT) {                                  if ( ber_peek_tag( ber, &len ) != LBER_DEFAULT ) {
                                         /* There's more - dup the ber buffer so they can all be                                          /* There's more - dup the ber buffer so they can all be
                                          * individually freed by ldap_msgfree.                                           * individually freed by ldap_msgfree.
                                          */                                           */
                                         struct berval bv;                                          struct berval bv;
                                         ber_get_option(ber, LBER_OPT_BER_REMAINING_BYTES, &len);                                          ber_get_option( ber, LBER_OPT_BER_REMAINING_BYTES, &len );
                                         bv.bv_val = LDAP_MALLOC(len);                                          bv.bv_val = LDAP_MALLOC( len );
                                         if (bv.bv_val) {                                          if ( bv.bv_val ) {
                                                 ok=1;                                                  ok = 1;
                                                 ber_read(ber, bv.bv_val, len);                                                  ber_read( ber, bv.bv_val, len );
                                                 bv.bv_len = len;                                                  bv.bv_len = len;
                                                 ber_init2(ber, &bv, ld->ld_lberoptions );                                                  ber_init2( ber, &bv, ld->ld_lberoptions );
                                         }                                          }
                                 }                                  }
                         } else {                          } else {
Line 941  lr->lr_res_matched ? lr->lr_res_matched Line 988  lr->lr_res_matched ? lr->lr_res_matched
                         chain_head->lm_chain_tail = newmsg;                          chain_head->lm_chain_tail = newmsg;
                         tmp = newmsg;                          tmp = newmsg;
                         /* "ok" means there's more to parse */                          /* "ok" means there's more to parse */
                         if (ok) {                          if ( ok ) {
                                 if (isv2) goto nextresp2;                                  if ( isv2 ) {
                                 else goto nextresp3;                                          goto nextresp2;
   
                                   } else {
                                           goto nextresp3;
                                   }
                         } else {                          } else {
                                 /* got to end of datagram without a SearchResult. Free                                  /* got to end of datagram without a SearchResult. Free
                                  * our dup'd ber, but leave any buffer alone. For v2 case,                                   * our dup'd ber, but leave any buffer alone. For v2 case,
                                  * the previous response is still using this buffer. For v3,                                   * the previous response is still using this buffer. For v3,
                                  * the new ber has no buffer to free yet.                                   * the new ber has no buffer to free yet.
                                  */                                   */
                                 ber_free(ber, 0);                                  ber_free( ber, 0 );
                                 return -1;                                  return -1;
                         }                          }
                 } else if ( moremsgs ) {                  } else if ( moremsgs ) {
Line 970  lr->lr_res_matched ? lr->lr_res_matched Line 1021  lr->lr_res_matched ? lr->lr_res_matched
         /* is this the one we're looking for? */          /* is this the one we're looking for? */
         if ( msgid == LDAP_RES_ANY || id == msgid ) {          if ( msgid == LDAP_RES_ANY || id == msgid ) {
                 if ( all == LDAP_MSG_ONE                  if ( all == LDAP_MSG_ONE
                     || (newmsg->lm_msgtype != LDAP_RES_SEARCH_RESULT                          || ( newmsg->lm_msgtype != LDAP_RES_SEARCH_RESULT
                     && newmsg->lm_msgtype != LDAP_RES_SEARCH_ENTRY                                  && newmsg->lm_msgtype != LDAP_RES_SEARCH_ENTRY
                     && newmsg->lm_msgtype != LDAP_RES_SEARCH_REFERENCE) ) {                                  && newmsg->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) )
                   {
                         *result = newmsg;                          *result = newmsg;
                         ld->ld_errno = LDAP_SUCCESS;                          ld->ld_errno = LDAP_SUCCESS;
                         return( tag );                          return( tag );
   
                 } else if ( newmsg->lm_msgtype == LDAP_RES_SEARCH_RESULT) {                  } else if ( newmsg->lm_msgtype == LDAP_RES_SEARCH_RESULT) {
                         foundit = 1;    /* return the chain later */                          foundit = 1;    /* return the chain later */
                 }                  }
Line 1056  build_result_ber( LDAP *ld, BerElement * Line 1109  build_result_ber( LDAP *ld, BerElement *
                 lr->lr_res_error ? lr->lr_res_error : "" ) == -1 )                  lr->lr_res_error ? lr->lr_res_error : "" ) == -1 )
         {          {
                 ld->ld_errno = LDAP_ENCODING_ERROR;                  ld->ld_errno = LDAP_ENCODING_ERROR;
                 ber_free(ber, 1);                  ber_free( ber, 1 );
                 return( LBER_ERROR );                  return( LBER_ERROR );
         }          }
   
Line 1064  build_result_ber( LDAP *ld, BerElement * Line 1117  build_result_ber( LDAP *ld, BerElement *
   
         if ( ber_skip_tag( ber, &len ) == LBER_ERROR ) {          if ( ber_skip_tag( ber, &len ) == LBER_ERROR ) {
                 ld->ld_errno = LDAP_DECODING_ERROR;                  ld->ld_errno = LDAP_DECODING_ERROR;
                 ber_free(ber, 1);                  ber_free( ber, 1 );
                 return( LBER_ERROR );                  return( LBER_ERROR );
         }          }
   
         if ( ber_get_enum( ber, &along ) == LBER_ERROR ) {          if ( ber_get_enum( ber, &along ) == LBER_ERROR ) {
                 ld->ld_errno = LDAP_DECODING_ERROR;                  ld->ld_errno = LDAP_DECODING_ERROR;
                 ber_free(ber, 1);                  ber_free( ber, 1 );
                 return( LBER_ERROR );                  return( LBER_ERROR );
         }          }
   
Line 1078  build_result_ber( LDAP *ld, BerElement * Line 1131  build_result_ber( LDAP *ld, BerElement *
   
         if ( tag == LBER_ERROR ) {          if ( tag == LBER_ERROR ) {
                 ld->ld_errno = LDAP_DECODING_ERROR;                  ld->ld_errno = LDAP_DECODING_ERROR;
                 ber_free(ber, 1);                  ber_free( ber, 1 );
                 return( LBER_ERROR );                  return( LBER_ERROR );
         }          }
   
Line 1097  merge_error_info( LDAP *ld, LDAPRequest Line 1150  merge_error_info( LDAP *ld, LDAPRequest
                 parentr->lr_res_errno = lr->lr_res_errno;                  parentr->lr_res_errno = lr->lr_res_errno;
                 if ( lr->lr_res_error != NULL ) {                  if ( lr->lr_res_error != NULL ) {
                         (void)ldap_append_referral( ld, &parentr->lr_res_error,                          (void)ldap_append_referral( ld, &parentr->lr_res_error,
                             lr->lr_res_error );                                  lr->lr_res_error );
                 }                  }
   
         } else if ( lr->lr_res_errno != LDAP_SUCCESS &&          } else if ( lr->lr_res_errno != LDAP_SUCCESS &&
Line 1145  ldap_msgid( LDAPMessage *lm ) Line 1198  ldap_msgid( LDAPMessage *lm )
 }  }
   
   
 char * ldap_int_msgtype2str( ber_tag_t tag )  const char *
   ldap_int_msgtype2str( ber_tag_t tag )
 {  {
         switch( tag ) {          switch( tag ) {
         case LDAP_RES_ADD: return "add";          case LDAP_RES_ADD: return "add";
Line 1190  int Line 1244  int
 ldap_msgdelete( LDAP *ld, int msgid )  ldap_msgdelete( LDAP *ld, int msgid )
 {  {
         LDAPMessage     *lm, *prev;          LDAPMessage     *lm, *prev;
         int rc = 0;          int             rc = 0;
   
         assert( ld != NULL );          assert( ld != NULL );
   
Line 1221  ldap_msgdelete( LDAP *ld, int msgid ) Line 1275  ldap_msgdelete( LDAP *ld, int msgid )
 #ifdef LDAP_R_COMPILE  #ifdef LDAP_R_COMPILE
         ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );          ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
 #endif  #endif
         if ( lm && ldap_msgfree( lm ) == LDAP_RES_SEARCH_ENTRY ) {          if ( lm ) {
                 rc = -1;                  switch ( ldap_msgfree( lm ) ) {
                   case LDAP_RES_SEARCH_ENTRY:
                   case LDAP_RES_SEARCH_REFERENCE:
                   case LDAP_RES_INTERMEDIATE:
                           rc = -1;
                           break;
   
                   default:
                           break;
                   }
         }          }
   
         return rc;          return rc;
Line 1230  ldap_msgdelete( LDAP *ld, int msgid ) Line 1293  ldap_msgdelete( LDAP *ld, int msgid )
   
   
 /*  /*
  * ldap_abandoned_idx   * ldap_abandoned
  *   *
  * return the location of the message id in the array of abandoned   * return the location of the message id in the array of abandoned
  * message ids, or -1   * message ids, or -1
Line 1238  ldap_msgdelete( LDAP *ld, int msgid ) Line 1301  ldap_msgdelete( LDAP *ld, int msgid )
  * expects ld_res_mutex to be locked   * expects ld_res_mutex to be locked
  */   */
 static int  static int
 ldap_abandoned_idx( LDAP *ld, ber_int_t msgid )  ldap_abandoned( LDAP *ld, ber_int_t msgid, int *idxp )
 {  {
         int     begin,  
                 end;  
   
 #ifdef LDAP_R_COMPILE  #ifdef LDAP_R_COMPILE
         LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );          LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );
 #endif  #endif
   
           assert( idxp != NULL );
           assert( msgid >= 0 );
         assert( ld->ld_nabandoned >= 0 );          assert( ld->ld_nabandoned >= 0 );
   
         if ( ld->ld_abandoned == NULL || ld->ld_nabandoned == 0 ) {          return lutil_bisect_find( ld->ld_abandoned, ld->ld_nabandoned, msgid, idxp );
                 return -1;  
         }  
   
         begin = 0;  
         end = ld->ld_nabandoned - 1;  
   
         /* use bisection */  
         if ( msgid < ld->ld_abandoned[ begin ] ) {  
                 return -1;  
         }  
   
         if ( msgid > ld->ld_abandoned[ end ] ) {  
                 return -1;  
         }  
   
         while ( end >= begin ) {  
                 int     pos = (begin + end)/2;  
                 int     curid = ld->ld_abandoned[ pos ];  
   
                 if ( msgid < curid ) {  
                         end = pos - 1;  
   
                 } else if ( msgid > curid ) {  
                         begin = pos + 1;  
   
                 } else {  
                         return pos;  
                 }  
         }  
   
         /* not abandoned */  
         return -1;  
 }  }
   
 /*  /*
Line 1290  ldap_abandoned_idx( LDAP *ld, ber_int_t Line 1320  ldap_abandoned_idx( LDAP *ld, ber_int_t
  * expects ld_res_mutex to be locked   * expects ld_res_mutex to be locked
  */   */
 static int  static int
 ldap_mark_abandoned( LDAP *ld, ber_int_t msgid )  ldap_mark_abandoned( LDAP *ld, ber_int_t msgid, int idx )
 {  {
         int     i, idx;          int             i;
   
 #ifdef LDAP_R_COMPILE  #ifdef LDAP_R_COMPILE
         LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );          LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_res_mutex );
 #endif  #endif
   
         idx = ldap_abandoned_idx( ld, msgid );          /* NOTE: those assertions are repeated in lutil_bisect_delete() */
         if ( idx == -1 ) {          assert( idx >= 0 );
                 return -1;          assert( idx < ld->ld_nabandoned );
         }          assert( ld->ld_abandoned[ idx ] == msgid );
   
         --ld->ld_nabandoned;  #if 0
         assert( ld->ld_nabandoned >= 0 );          fprintf( stderr, "--> ldap_mark_abandoned %p %p %d %d:\n", (void *)&i, (void *)ld, msgid, idx );
         for ( i = idx; i < ld->ld_nabandoned; i++ ) {          for ( i = 0; i < ld->ld_nabandoned; i++ ) {
                 ld->ld_abandoned[ i ] = ld->ld_abandoned[ i + 1 ];                  fprintf( stderr, "\t%p %p %d\n", (void *)&i, (void *)ld, ld->ld_abandoned[ i ] );
         }          }
   #endif
   
         return 0;          return lutil_bisect_delete( &ld->ld_abandoned, &ld->ld_nabandoned, msgid, idx );
 }  }

Removed from v.1.138  
changed lines
  Added in v.1.139


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org