]> git.sur5r.net Git - openldap/blob - libraries/libldap/abandon.c
strlen returns size_t not int.
[openldap] / libraries / libldap / abandon.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /*  Portions
6  *  Copyright (c) 1990 Regents of the University of Michigan.
7  *  All rights reserved.
8  *
9  *  abandon.c
10  */
11
12 #include "portable.h"
13
14 #include <stdio.h>
15 #include <stdlib.h>
16
17 #include <ac/socket.h>
18 #include <ac/string.h>
19 #include <ac/time.h>
20
21 #include "ldap-int.h"
22
23 static int do_abandon LDAP_P((
24         LDAP *ld,
25         int origid,
26         int msgid,
27         LDAPControl **sctrls,
28         LDAPControl **cctrls));
29
30 /*
31  * ldap_abandon_ext - perform an ldap extended abandon operation.
32  *
33  * Parameters:
34  *      ld                      LDAP descriptor
35  *      msgid           The message id of the operation to abandon
36  *      scntrls         Server Controls
37  *      ccntrls         Client Controls
38  *
39  * ldap_abandon_ext returns a LDAP error code.
40  *              (LDAP_SUCCESS if everything went ok)
41  *
42  * Example:
43  *      ldap_abandon_ext( ld, msgid, scntrls, ccntrls );
44  */
45 int
46 ldap_abandon_ext(
47         LDAP *ld,
48         int msgid,
49         LDAPControl **sctrls,
50         LDAPControl **cctrls )
51 {
52         Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );
53
54         return do_abandon( ld, msgid, msgid, sctrls, cctrls );
55 }
56
57
58 /*
59  * ldap_abandon - perform an ldap abandon operation. Parameters:
60  *
61  *      ld              LDAP descriptor
62  *      msgid           The message id of the operation to abandon
63  *
64  * ldap_abandon returns 0 if everything went ok, -1 otherwise.
65  *
66  * Example:
67  *      ldap_abandon( ld, msgid );
68  */
69 int
70 ldap_abandon( LDAP *ld, int msgid )
71 {
72         Debug( LDAP_DEBUG_TRACE, "ldap_abandon %d\n", msgid, 0, 0 );
73         return do_abandon( ld, msgid, msgid, NULL, NULL ) == LDAP_SUCCESS
74                 ? 0 : -1;
75 }
76
77
78 static int
79 do_abandon(
80         LDAP *ld,
81         int origid,
82         int msgid,
83         LDAPControl **sctrls,
84         LDAPControl **cctrls)
85 {
86         BerElement      *ber;
87         int             i, err, sendabandon;
88         Sockbuf         *sb;
89         LDAPRequest     *lr;
90
91         /*
92          * An abandon request looks like this:
93          *      AbandonRequest ::= MessageID
94          */
95
96         Debug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n",
97                 origid, msgid, 0 );
98
99         sendabandon = 1;
100
101         /* find the request that we are abandoning */
102         for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
103                 if ( lr->lr_msgid == msgid ) {  /* this message */
104                         break;
105                 }
106                 if ( lr->lr_origid == msgid ) {/* child:  abandon it */
107                         (void) do_abandon( ld,
108                                 msgid, lr->lr_msgid, sctrls, cctrls );
109                 }
110         }
111
112         if ( lr != NULL ) {
113                 if ( origid == msgid && lr->lr_parent != NULL ) {
114                         /* don't let caller abandon child requests! */
115                         ld->ld_errno = LDAP_PARAM_ERROR;
116                         return( LDAP_PARAM_ERROR );
117                 }
118                 if ( lr->lr_status != LDAP_REQST_INPROGRESS ) {
119                         /* no need to send abandon message */
120                         sendabandon = 0;
121                 }
122         }
123
124         if ( ldap_msgdelete( ld, msgid ) == 0 ) {
125                 ld->ld_errno = LDAP_SUCCESS;
126                 return LDAP_SUCCESS;
127         }
128
129         err = 0;
130         if ( sendabandon ) {
131                 /* create a message to send */
132                 if ( (ber = ldap_alloc_ber_with_options( ld )) == NULLBER ) {
133                         err = -1;
134                         ld->ld_errno = LDAP_NO_MEMORY;
135
136                 } else {
137 #ifdef LDAP_CONNECTIONLESS
138                         if ( ld->ld_cldapnaddr > 0 ) {
139                                 err = ber_printf( ber, "{isti", /* leave open '}' */
140                                     ++ld->ld_msgid, ld->ld_cldapdn,
141                                     LDAP_REQ_ABANDON, msgid );
142                         } else
143 #endif /* LDAP_CONNECTIONLESS */
144                         {
145                                 err = ber_printf( ber, "{iti",  /* leave open '}' */
146                                         ++ld->ld_msgid,
147                                     LDAP_REQ_ABANDON, msgid );
148                         }
149
150                         if( err == -1 ) {
151                                 /* encoding error */
152                                 ld->ld_errno = LDAP_ENCODING_ERROR;
153
154                         } else {
155                                 /* Put Server Controls */
156                                 if ( ldap_int_put_controls( ld, sctrls, ber )
157                                         != LDAP_SUCCESS )
158                                 {
159                                         err = -1;
160
161                                 } else {
162                                         /* close '{' */
163                                         err = ber_printf( ber, "}" );
164
165                                         if( err == -1 ) {
166                                                 /* encoding error */
167                                                 ld->ld_errno = LDAP_ENCODING_ERROR;
168                                         }
169                                 }
170                         }
171
172                         if ( err == -1 ) {
173                                 ber_free( ber, 1 );
174
175                         } else {
176                                 /* send the message */
177                                 if ( lr != NULL ) {
178                                         sb = lr->lr_conn->lconn_sb;
179                                 } else {
180                                         sb = &ld->ld_sb;
181                                 }
182
183                                 if ( ber_flush( sb, ber, 1 ) != 0 ) {
184                                         ld->ld_errno = LDAP_SERVER_DOWN;
185                                         err = -1;
186                                 } else {
187                                         err = 0;
188                                 }
189                         }
190                 }
191         }
192
193         if ( lr != NULL ) {
194                 if ( sendabandon ) {
195                         ldap_free_connection( ld, lr->lr_conn, 0, 1 );
196                 }
197                 if ( origid == msgid ) {
198                         ldap_free_request( ld, lr );
199                 }
200         }
201
202         if ( ld->ld_abandoned == NULL ) {
203                 if ( (ld->ld_abandoned = (int *) malloc( 2 * sizeof(int) ))
204                     == NULL ) {
205                         ld->ld_errno = LDAP_NO_MEMORY;
206                         return( ld->ld_errno );
207                 }
208                 i = 0;
209         } else {
210                 for ( i = 0; ld->ld_abandoned[i] != -1; i++ )
211                         ;       /* NULL */
212                 if ( (ld->ld_abandoned = (int *) realloc( (char *)
213                     ld->ld_abandoned, (i + 2) * sizeof(int) )) == NULL ) {
214                         ld->ld_errno = LDAP_NO_MEMORY;
215                         return( ld->ld_errno );
216                 }
217         }
218         ld->ld_abandoned[i] = msgid;
219         ld->ld_abandoned[i + 1] = -1;
220
221         if ( err != -1 ) {
222                 ld->ld_errno = LDAP_SUCCESS;
223         }
224
225         return( ld->ld_errno );
226 }