* with msgid. If all is LDAP_MSG_ONE (0) the first message with id
* msgid will be accepted, otherwise, ldap_result will wait for all
* responses with id msgid and then return a pointer to the entire list
- * of messages. This is only useful for search responses, which can be
- * of two message types (zero or more entries, followed by an
- * ldap result). The type of the first message received is returned.
+ * of messages. In general, this is only useful for search responses,
+ * which can be of three message types (zero or more entries, zero or
+ * search references, followed by an ldap result). An extension to
+ * LDAPv3 allows partial extended responses to be returned in response
+ * to any request. The type of the first message received is returned.
* When waiting, any messages that have been abandoned are discarded.
*
* Example:
}
static LDAPMessage *
-chkResponseList( LDAP *ld,
- int msgid,
- int all)
+chkResponseList(
+ LDAP *ld,
+ int msgid,
+ int all)
{
LDAPMessage *lm, *lastlm, *nextlm;
/*
* wait until it arrives or timeout occurs.
*/
- Debug( LDAP_DEBUG_TRACE, "chkResponseList for msgid %d, all %d\n",
+ Debug( LDAP_DEBUG_TRACE,
+ "ldap_chkResponseList for msgid=%d, all=%d\n",
msgid, all, 0 );
lastlm = NULL;
for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) {
nextlm = lm->lm_next;
if ( ldap_abandoned( ld, lm->lm_msgid ) ) {
- Debug( LDAP_DEBUG_TRACE, "chkResponseList msg abandoned, msgid %d\n",
+ Debug( LDAP_DEBUG_TRACE,
+ "ldap_chkResponseList msg abandoned, msgid %d\n",
msgid, 0, 0 );
ldap_mark_abandoned( ld, lm->lm_msgid );
if ( msgid == LDAP_RES_ANY || lm->lm_msgid == msgid ) {
LDAPMessage *tmp;
- if ( all == LDAP_MSG_ONE
- || (lm->lm_msgtype != LDAP_RES_SEARCH_RESULT
- && lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE /* LDAPv3 */
- && lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY
- && lm->lm_msgtype != LDAP_RES_EXTENDED_PARTIAL) )
+ if ( all == LDAP_MSG_ONE || msgid == LDAP_RES_UNSOLICITED ) {
break;
+ }
for ( tmp = lm; tmp != NULL; tmp = tmp->lm_chain ) {
- if ( tmp->lm_msgtype == LDAP_RES_SEARCH_RESULT )
+ if ( tmp->lm_msgtype != LDAP_RES_SEARCH_ENTRY
+ && tmp->lm_msgtype != LDAP_RES_SEARCH_REFERENCE
+ && tmp->lm_msgtype != LDAP_RES_EXTENDED_PARTIAL )
+ {
break;
+ }
}
if ( tmp == NULL ) {
}
lastlm = lm;
}
+
if ( lm != NULL ) {
/* Found an entry, remove it from the list */
if ( lastlm == NULL ) {
lastlm->lm_next = (all == LDAP_MSG_ONE && lm->lm_chain != NULL
? lm->lm_chain : lm->lm_next);
}
- if ( all == LDAP_MSG_ONE && lm->lm_chain != NULL )
- {
+ if ( all == LDAP_MSG_ONE && lm->lm_chain != NULL ) {
lm->lm_chain->lm_next = lm->lm_next;
lm->lm_chain = NULL;
}
#ifdef LDAP_DEBUG
if( lm == NULL) {
- Debug( LDAP_DEBUG_TRACE, "chkResponseList returns NULL\n", 0, 0, 0);
+ Debug( LDAP_DEBUG_TRACE,
+ "ldap_chkResponseList returns NULL\n", 0, 0, 0);
} else {
- Debug( LDAP_DEBUG_TRACE, "chkResponseList returns msgid %d, type %lu\n",
- lm->lm_msgid, (unsigned long) lm->lm_msgtype, 0);
+ Debug( LDAP_DEBUG_TRACE,
+ "ldap_chkResponseList returns msgid %d, type 0x%02lu\n",
+ lm->lm_msgid, (unsigned long) lm->lm_msgtype, 0);
}
#endif
return lm;
}
+
static int
wait4msg(
LDAP *ld,
}
if ( lc == NULL ) {
- rc = do_ldap_select( ld, tvp );
+ rc = ldap_int_select( ld, tvp );
#ifdef LDAP_DEBUG
if ( rc == -1 ) {
Debug( LDAP_DEBUG_TRACE,
- "do_ldap_select returned -1: errno %d\n",
+ "ldap_int_select returned -1: errno %d\n",
errno, 0, 0 );
}
#endif
ber_int_t msgid,
int all,
Sockbuf *sb,
- LDAPConn *lc,
+ LDAPConn *lc,
LDAPMessage **result )
{
BerElement *ber;
}
ber = lc->lconn_ber;
- assert( BER_VALID (ber) );
+ assert( LBER_VALID (ber) );
/* get the next message */
errno = 0;
+#ifdef LDAP_CONNECTIONLESS
+ if ( LDAP_IS_UDP(ld) ) {
+ struct sockaddr from;
+ ber_int_sb_read(sb, &from, sizeof(struct sockaddr));
+ }
+#endif
if ( (tag = ber_get_next( sb, &len, ber ))
!= LDAP_TAG_MESSAGE ) {
if ( tag == LBER_DEFAULT) {
ber_free( ber, 1 );
return( -2 ); /* continue looking */
}
-
+#ifdef LDAP_CONNECTIONLESS
+ if (LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == LDAP_VERSION2) {
+ char *blank;
+ ber_scanf(ber, "a{", &blank);
+ if (blank)
+ ber_memfree(blank);
+ }
+#endif
/* the message type */
if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
ld->ld_errno = LDAP_DECODING_ERROR;
return( -1 );
}
- Debug( LDAP_DEBUG_TRACE, "ldap_read: message type %s msgid %ld, original id %ld\n",
+ Debug( LDAP_DEBUG_TRACE,
+ "ldap_read: message type %s msgid %ld, original id %ld\n",
ldap_int_msgtype2str( tag ),
(long) lr->lr_msgid, (long) lr->lr_origid );
tmpber = *ber; /* struct copy */
if ( v3ref == 1 ) {
; /* V3 search reference or V3 referral sucessfully chased */
- } else
- if ( ber_scanf( &tmpber, "{iaa}", &lderr,
+ } else if ( ber_scanf( &tmpber, "{iaa}", &lderr,
&lr->lr_res_matched, &lr->lr_res_error )
!= LBER_ERROR ) {
if ( lderr != LDAP_SUCCESS ) {
/* referrals are in error string */
refer_cnt = ldap_chase_referrals( ld, lr,
- &lr->lr_res_error, &hadref );
+ &lr->lr_res_error, -1, &hadref );
lr->lr_status = LDAP_REQST_COMPLETED;
Debug( LDAP_DEBUG_TRACE,
"read1msg: V2 referral chased, mark request completed, id = %d\n", lr->lr_msgid, 0, 0);
}
/* Check if all requests are finished, lr is now parent */
- for(tmplr=lr ; tmplr != NULL; tmplr=tmplr->lr_refnext) {
+ tmplr = lr;
+ if (tmplr->lr_status == LDAP_REQST_COMPLETED) {
+ for(tmplr=lr->lr_child; tmplr != NULL; tmplr=tmplr->lr_refnext) {
if( tmplr->lr_status != LDAP_REQST_COMPLETED) {
break;
+ }
}
}