1N/A * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. 1N/A * Use is subject to license terms. 1N/A#
pragma ident "%Z%%M% %I% %E% SMI" 1N/A/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1N/A * The contents of this file are subject to the Netscape Public License 1N/A * Version 1.0 (the "NPL"); you may not use this file except in 1N/A * compliance with the NPL. You may obtain a copy of the NPL at 1N/A * Software distributed under the NPL is distributed on an "AS IS" basis, 1N/A * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL 1N/A * for the specific language governing rights and limitations under the 1N/A * The Initial Developer of this code under the NPL is Netscape 1N/A * Communications Corporation. Portions created by Netscape are 1N/A * Copyright (C) 1998 Netscape Communications Corporation. All Rights 1N/A * Copyright (c) 1990 Regents of the University of Michigan. 1N/A * All rights reserved. 1N/Astatic char copyright[] =
"@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
1N/A/* high resolution timer usage */ 1N/A#
if 0
/* these functions are no longer used */ 1N/A * ldap_result - wait for an ldap result response to a message from the 1N/A * ldap server. If msgid is -1, any message will be accepted, otherwise 1N/A * ldap_result will wait for a response with msgid. If all is 0 the 1N/A * first message with id msgid will be accepted, otherwise, ldap_result 1N/A * will wait for all responses with id msgid and then return a pointer to 1N/A * the entire list of messages. This is only useful for search responses, 1N/A * which can be of two message types (zero or more entries, followed by an 1N/A * ldap result). The type of the first message received is returned. 1N/A * When waiting, any messages that have been abandoned are discarded. 1N/A * ldap_result( s, msgid, all, timeout, result ) 1N/A return( -
1 );
/* punt */ 1N/A "nsldapi_result_nolock (msgid=%d, all=%d)\n",
msgid,
all, 0 );
1N/A * First, look through the list of responses we have received on 1N/A * this association and see if the response we're interested in 1N/A * is there. If it is, return it. If not, call wait4msg() to 1N/A * wait until it arrives or timeout occurs. 1N/A * XXXmcs should use cache function pointers to hook in memcache 1N/A * Look through the list of queued responses for a message that matches the 1N/A * criteria in the msgid and all parameters. msgid == LDAP_RES_ANY matches 1N/A * If an appropriate message is found, a non-zero value is returned and the 1N/A * message is dequeued and assigned to *result. 1N/A * If not, *result is set to NULL and this function returns 0. 1N/A "=> check_response_queue (msgid=%d, all=%d)\n",
msgid,
all, 0 );
1N/A "<= check_response_queue NOT FOUND\n",
1N/A return( 0 );
/* no message to return */ 1N/A * if we did not find a message OR if the one we found is a result for 1N/A * a request that is still pending, return failure. 1N/A "<= check_response_queue NOT FOUND\n",
1N/A return( 0 );
/* no message to return */ 1N/A "<= check_response_queue returning msgid %d type %d\n",
1N/A return(
1 );
/* a message was found and returned in *result */ 1N/A#
endif /* LDAP_DEBUG */ 1N/A /* check the cache */ 1N/A /* if ( unlock_permitted ) LDAP_MUTEX_UNLOCK( ld ); */ 1N/A /* if ( unlock_permitted ) LDAP_MUTEX_LOCK( ld ); */ 1N/A return( 0 );
/* timeout */ 1N/A * if we are looking for a specific msgid, check to see if it is 1N/A * associated with a dead connection and return an error if so. 1N/A "unknown message id") ));
1N/A return( -
1 );
/* could not find request for msgid */ 1N/A return( -
1 );
/* connection dead */ 1N/A#
endif /* LDAP_DEBUG */ 1N/A "nsldapi_iostatus_poll returned -1: errno %d\n",
1N/A rc = -
2;
/* select interrupted: loop */ 1N/A * It is possible that recursion occurred while chasing 1N/A * referrals and as a result the message we are looking 1N/A * for may have been placed on the response queue. Look 1N/A * for it there before continuing so we don't end up 1N/A * waiting on the network for a message that we already 1N/A * honor the timeout if specified 1N/A * read1msg() should be called with LDAP_CONN_LOCK and LDAP_REQ_LOCK locked. 1N/A * if we are not already in the midst of reading a message, allocate 1N/A * a ber that is associated with this connection 1N/A * ber_get_next() doesn't set errno on EOF, so we pre-set it to 1N/A * zero to avoid getting tricked by leftover "EAGAIN" errors 1N/A /* get the next message */ 1N/A return( -
2 );
/* try again */ 1N/A * Since we have received a complete message now, we pull this ber 1N/A * out of the connection structure and never read into it again. 1N/A /* if it's been abandoned, toss it */ 1N/A return( -
2 );
/* continue looking */ 1N/A "no request for response with msgid %ld (tossing)\n",
1N/A return( -
2 );
/* continue looking */ 1N/A /* the message type */ 1N/A rc = -
2;
/* default is to keep looking (no response found) */ 1N/A * we're chasing one or more new refs... 1N/A * this request is complete... 1N/A /* request without any refs */ 1N/A * If this is not a child request and it is a bind 1N/A * request, reset the connection's bind DN and 1N/A * status based on the result of the operation. 1N/A * if this response is to a child request, we toss 1N/A * the message contents and just merge error info. 1N/A break;
/* not completely done yet */ 1N/A * we recognize a request as complete when: 1N/A * 1) it has no outstanding referrals 1N/A * 2) it is not a child request 1N/A * 3) we have received a result for the request (i.e., 1N/A * something other than an entry or a reference). 1N/A "request %ld done\n",
id, 0, 0 );
1N/A"res_errno: %d, res_error: <%s>, res_matched: <%s>\n",
1N/A rc = -
1;
/* fatal error */ 1N/A /* make a new ldap message */ 1N/A * if this is a search entry or if this request is complete (i.e., 1N/A * there are no outstanding referrals) then add to cache and check 1N/A * to see if we should return this to the caller right away or not. 1N/A * return the first response we have for this 1N/A * search request later (possibly an entire 1N/A * chain of messages). 1N/A * if not, we must add it to the list of responses. if 1N/A * the msgid is already there, it must be part of an existing 1N/A /* not part of an existing search response */ 1N/A "adding new response id %d type %d (looking for id %d)\n",
1N/A return( -
2 );
/* continue looking */ 1N/A "adding response id %d type %d (looking for id %d)\n",
1N/A * part of a search response - add to end of list of entries 1N/A * the first step is to find the end of the list of entries and 1N/A * references. after the following loop is executed, tmp points to 1N/A * the last entry or reference in the chain. If there are none, 1N/A * tmp points to the search result. 1N/A * If this is a manufactured result message and a result is already 1N/A * queued we throw away the one that is queued and replace it with 1N/A * our new result. This is necessary so we don't end up returning 1N/A * more than one result. 1N/A * the result is the only thing in the chain... replace it. 1N/A * entries or references are also present, so the result 1N/A * is the next entry after tmp. replace it. 1N/A * the result is the only thing in the chain... add before it. 1N/A * entries and/or references are present... add to the end 1N/A * return the first response or the whole chain if that's what 1N/A * we were looking for.... 1N/A * only return the first response in the chain 1N/A * return all of the responses (may be a chain) 1N/A return( -
2 );
/* continue looking */ 1N/A * check for LDAPv2+ (UMich extension) or LDAPv3 referrals or references 1N/A * errors are merged in "lr". 1N/A /* referrals are not supported or are disabled */ 1N/A /* referrals may be present in the error string */ 1N/A /* set LDAP errno, message, and matched string appropriately */ 1N/A /* substitute success for referral error codes */ 1N/A /* preserve existing non-referral error code */ 1N/A /* error occurred while trying to chase referrals */ 1N/A /* some referrals were not recognized */ 1N/A "check_for_refs: new result: msgid %d, res_errno %d, ",
1N/A "check_for_refs: %d new refs(s); chasing %d of them\n",
1N/A/* returns an LDAP error code and also sets it in LDAP * */ 1N/A * Merge error information in "lr" with "parentr" error code and string. 1N/A/* XXXmcs: was revised to support extended I/O callbacks but never compiled! */ 1N/A#
else /* USE_SYSCONF */ 1N/A#
endif /* USE_SYSCONF */ 1N/A * clamp value so we don't overrun the fd_set structure 1N/A /* XXXmcs: UNIX platforms should use poll() */ 1N/A "nsldapi_iostatus_poll: unknown I/O type %d\n",
1N/A rc = 0;
/* simulate a timeout (what else to do?) */ 1N/A#
endif /* !macintosh */ 1N/A /* XXXmcs: needs to be revised to support I/O callbacks */ 1N/A#
endif /* macintosh */ 1N/A/* XXXmcs: needs to be revised to support extended I/O callbacks */ 1N/A /* XXXmcs: UNIX platforms should use poll() */ 1N/A#
endif /* WINSOCK || _WINDOWS */ 1N/A * ldap_msgdelete - delete a message. It returns: 1N/A * 0 if the entire message was deleted 1N/A * -1 if the message was not found, or only part of it was found 1N/A return( -
1 );
/* punt */ 1N/A * return 1 if message msgid is waiting to be abandoned, 0 otherwise 1N/A /* get the next message */ 1N/A "nsldapi_post_result(ld=0x%x, msgid=%d, result=0x%x)\n",
1N/A * Look for any pending request for which someone is waiting. 1N/A * If we did't find a pending request, lp is NULL at this 1N/A * point, and we will leave this function without doing 1N/A * anything more -- which is exactly what we want to do. 1N/A * Look for a pending request specific to this message id 1N/A * No pending requests for this response... append to 1N/A * our pending result list. 1N/A * Wake up a thread that is waiting for this result. 1N/A#
if 0
/* these functions are no longer used */