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