8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libldap5 / sources / ldap / common / abandon.c
blobe695cbd495e0d9063cdae25b098881f8690c89d4
1 #pragma ident "%Z%%M% %I% %E% SMI"
3 /*
4 * The contents of this file are subject to the Netscape Public
5 * License Version 1.1 (the "License"); you may not use this file
6 * except in compliance with the License. You may obtain a copy of
7 * the License at http://www.mozilla.org/NPL/
9 * Software distributed under the License is distributed on an "AS
10 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 * implied. See the License for the specific language governing
12 * rights and limitations under the License.
14 * The Original Code is Mozilla Communicator client code, released
15 * March 31, 1998.
17 * The Initial Developer of the Original Code is Netscape
18 * Communications Corporation. Portions created by Netscape are
19 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
20 * Rights Reserved.
22 * Contributor(s):
26 * Copyright (c) 1990 Regents of the University of Michigan.
27 * All rights reserved.
30 * abandon.c
33 #if 0
34 #ifndef lint
35 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
36 #endif
37 #endif
39 #include "ldap-int.h"
41 static int do_abandon( LDAP *ld, int origid, int msgid,
42 LDAPControl **serverctrls, LDAPControl **clientctrls );
45 * ldap_abandon - perform an ldap abandon operation. Parameters:
47 * ld LDAP descriptor
48 * msgid The message id of the operation to abandon
50 * ldap_abandon returns 0 if everything went ok, -1 otherwise.
52 * Example:
53 * ldap_abandon( ld, msgid );
55 int
56 LDAP_CALL
57 ldap_abandon( LDAP *ld, int msgid )
59 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_abandon %d\n", msgid, 0, 0 );
61 if ( ldap_abandon_ext( ld, msgid, NULL, NULL ) == LDAP_SUCCESS ) {
62 return( 0 );
65 return( -1 );
70 * LDAPv3 extended abandon.
71 * Returns an LDAP error code.
73 int
74 LDAP_CALL
75 ldap_abandon_ext( LDAP *ld, int msgid, LDAPControl **serverctrls,
76 LDAPControl **clientctrls )
78 int rc;
80 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );
82 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
83 return( LDAP_PARAM_ERROR );
86 LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
87 LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
88 rc = do_abandon( ld, msgid, msgid, serverctrls, clientctrls );
91 * XXXmcs should use cache function pointers to hook in memcache
93 ldap_memcache_abandon( ld, msgid );
95 LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
96 LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
98 return( rc );
103 * Abandon all outstanding requests for msgid (included child requests
104 * spawned when chasing referrals). This function calls itself recursively.
105 * No locking is done is this function so it must be done by the caller.
106 * Returns an LDAP error code and sets it in LDAP *ld as well
108 static int
109 do_abandon( LDAP *ld, int origid, int msgid, LDAPControl **serverctrls,
110 LDAPControl **clientctrls )
112 BerElement *ber;
113 int i, bererr, lderr, sendabandon;
114 Sockbuf *sb;
115 LDAPRequest *lr = NULL;
118 * An abandon request looks like this:
119 * AbandonRequest ::= MessageID
121 LDAPDebug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n",
122 origid, msgid, 0 );
124 /* optimistic */
125 lderr = LDAP_SUCCESS;
128 * this is not the best implementation...
129 * the code special cases the when async io is enabled.
130 * The logic is clear this way, at the cost of code bloat.
131 * This logic should be cleaned up post nova 4.5 rtm
133 if (ld->ld_options & LDAP_BITOPT_ASYNC)
135 /* Don't send an abandon message unless there is something to abandon. */
136 sendabandon = 0;
138 /* Find the request that we are abandoning. */
139 if (ld->ld_requests != NULL) {
140 for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
141 if ( lr->lr_msgid == msgid ) { /* this message */
142 if ( origid == msgid && lr->lr_parent != NULL ) {
143 /* don't let caller abandon child requests! */
144 lderr = LDAP_PARAM_ERROR;
145 goto set_errorcode_and_return;
147 if ( lr->lr_status == LDAP_REQST_INPROGRESS ) {
148 /* We only need to send an abandon message if the request
149 * is in progress.
151 sendabandon = 1;
153 break;
155 if ( lr->lr_origid == msgid ) { /* child: abandon it */
156 (void)do_abandon( ld, msgid, lr->lr_msgid,
157 serverctrls, clientctrls );
158 /* we ignore errors from child abandons... */
163 else
165 sendabandon = 1;
166 /* find the request that we are abandoning */
167 for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
168 if ( lr->lr_msgid == msgid ) { /* this message */
169 break;
171 if ( lr->lr_origid == msgid ) { /* child: abandon it */
172 (void)do_abandon( ld, msgid, lr->lr_msgid,
173 serverctrls, clientctrls );
174 /* we ignore errors from child abandons... */
178 if ( lr != NULL ) {
179 if ( origid == msgid && lr->lr_parent != NULL ) {
180 /* don't let caller abandon child requests! */
181 lderr = LDAP_PARAM_ERROR;
182 goto set_errorcode_and_return;
184 if ( lr->lr_status != LDAP_REQST_INPROGRESS ) {
185 /* no need to send abandon message */
186 sendabandon = 0;
190 if ( ldap_msgdelete( ld, msgid ) == 0 ) {
191 /* we had all the results and deleted them */
192 goto set_errorcode_and_return;
195 if ( sendabandon ) {
196 /* create a message to send */
197 if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber )) ==
198 LDAP_SUCCESS ) {
199 LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
200 #ifdef CLDAP
201 if ( ld->ld_dbp->sb_naddr > 0 ) {
202 bererr = ber_printf( ber, "{isti",
203 ++ld->ld_msgid, ld->ld_cldapdn,
204 LDAP_REQ_ABANDON, msgid );
205 } else {
206 #endif /* CLDAP */
207 bererr = ber_printf( ber, "{iti",
208 ++ld->ld_msgid, LDAP_REQ_ABANDON, msgid );
209 #ifdef CLDAP
211 #endif /* CLDAP */
212 LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
214 if ( bererr == -1 ||
215 ( lderr = nsldapi_put_controls( ld, serverctrls,
216 1, ber )) != LDAP_SUCCESS ) {
217 lderr = LDAP_ENCODING_ERROR;
218 ber_free( ber, 1 );
219 } else {
220 /* send the message */
221 if ( lr != NULL ) {
222 sb = lr->lr_conn->lconn_sb;
223 } else {
224 sb = ld->ld_sbp;
226 if ( nsldapi_ber_flush( ld, sb, ber, 1, 0 )
227 != 0 ) {
228 lderr = LDAP_SERVER_DOWN;
234 if ( lr != NULL ) {
235 if ( sendabandon ) {
236 nsldapi_free_connection( ld, lr->lr_conn, NULL, NULL,
237 0, 1 );
239 if ( origid == msgid ) {
240 nsldapi_free_request( ld, lr, 0 );
245 LDAP_MUTEX_LOCK( ld, LDAP_ABANDON_LOCK );
246 if ( ld->ld_abandoned == NULL ) {
247 if ( (ld->ld_abandoned = (int *)NSLDAPI_MALLOC( 2
248 * sizeof(int) )) == NULL ) {
249 lderr = LDAP_NO_MEMORY;
250 LDAP_MUTEX_UNLOCK( ld, LDAP_ABANDON_LOCK );
251 goto set_errorcode_and_return;
253 i = 0;
254 } else {
255 for ( i = 0; ld->ld_abandoned[i] != -1; i++ )
256 ; /* NULL */
257 if ( (ld->ld_abandoned = (int *)NSLDAPI_REALLOC( (char *)
258 ld->ld_abandoned, (i + 2) * sizeof(int) )) == NULL ) {
259 lderr = LDAP_NO_MEMORY;
260 LDAP_MUTEX_UNLOCK( ld, LDAP_ABANDON_LOCK );
261 goto set_errorcode_and_return;
264 ld->ld_abandoned[i] = msgid;
265 ld->ld_abandoned[i + 1] = -1;
266 LDAP_MUTEX_UNLOCK( ld, LDAP_ABANDON_LOCK );
268 set_errorcode_and_return:
269 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
270 return( lderr );