]> git.sur5r.net Git - openldap/blob - libraries/libldap/abandon.c
a5e93798c1bc3c4750321fa30bff11835d2bdbf3
[openldap] / libraries / libldap / abandon.c
1 /*
2  *  Copyright (c) 1990 Regents of the University of Michigan.
3  *  All rights reserved.
4  *
5  *  abandon.c
6  */
7
8 #include "portable.h"
9
10 #ifndef lint 
11 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
12 #endif
13
14 #include <stdio.h>
15 #include <stdlib.h>
16
17 #include <ac/socket.h>
18 #include <ac/string.h>
19
20 #include "lber.h"
21 #include "ldap.h"
22 #include "ldap-int.h"
23
24 static int do_abandon LDAP_P(( LDAP *ld, int origid, int msgid ));
25
26 /*
27  * ldap_abandon - perform an ldap (and X.500) abandon operation. Parameters:
28  *
29  *      ld              LDAP descriptor
30  *      msgid           The message id of the operation to abandon
31  *
32  * ldap_abandon returns 0 if everything went ok, -1 otherwise.
33  *
34  * Example:
35  *      ldap_abandon( ld, msgid );
36  */
37 int
38 ldap_abandon( LDAP *ld, int msgid )
39 {
40         Debug( LDAP_DEBUG_TRACE, "ldap_abandon %d\n", msgid, 0, 0 );
41         return( do_abandon( ld, msgid, msgid ));
42 }
43
44
45 static int
46 do_abandon( LDAP *ld, int origid, int msgid )
47 {
48         BerElement      *ber;
49         int             i, err, sendabandon;
50         Sockbuf         *sb;
51 #ifdef LDAP_REFERRALS
52         LDAPRequest     *lr;
53 #endif /* LDAP_REFERRALS */
54
55         /*
56          * An abandon request looks like this:
57          *      AbandonRequest ::= MessageID
58          */
59
60         Debug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n",
61                 origid, msgid, 0 );
62
63         sendabandon = 1;
64
65 #ifdef LDAP_REFERRALS
66         /* find the request that we are abandoning */
67         for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
68                 if ( lr->lr_msgid == msgid ) {  /* this message */
69                         break;
70                 }
71                 if ( lr->lr_origid == msgid ) { /* child:  abandon it */
72                         do_abandon( ld, msgid, lr->lr_msgid );
73                 }
74         }
75
76         if ( lr != NULL ) {
77                 if ( origid == msgid && lr->lr_parent != NULL ) {
78                         /* don't let caller abandon child requests! */
79                         ld->ld_errno = LDAP_PARAM_ERROR;
80                         return( -1 );
81                 }
82                 if ( lr->lr_status != LDAP_REQST_INPROGRESS ) {
83                         /* no need to send abandon message */
84                         sendabandon = 0;
85                 }
86         }
87 #endif /* LDAP_REFERRALS */
88
89         if ( ldap_msgdelete( ld, msgid ) == 0 ) {
90                 ld->ld_errno = LDAP_SUCCESS;
91                 return( 0 );
92         }
93
94         err = 0;
95         if ( sendabandon ) {
96                 /* create a message to send */
97                 if ( (ber = ldap_alloc_ber_with_options( ld )) == NULLBER ) {
98                         err = -1;
99                         ld->ld_errno = LDAP_NO_MEMORY;
100                 } else {
101 #ifdef CLDAP
102                         if ( ld->ld_sb.sb_naddr > 0 ) {
103                                 err = ber_printf( ber, "{isti}",
104                                     ++ld->ld_msgid, ld->ld_cldapdn,
105                                     LDAP_REQ_ABANDON, msgid );
106                         } else {
107 #endif /* CLDAP */
108                                 err = ber_printf( ber, "{iti}", ++ld->ld_msgid,
109                                     LDAP_REQ_ABANDON, msgid );
110 #ifdef CLDAP
111                         }
112 #endif /* CLDAP */
113
114                         if ( err == -1 ) {
115                                 ld->ld_errno = LDAP_ENCODING_ERROR;
116                                 ber_free( ber, 1 );
117                         } else {
118                                 /* send the message */
119 #ifdef LDAP_REFERRALS
120                                 if ( lr != NULL ) {
121                                         sb = lr->lr_conn->lconn_sb;
122                                 } else {
123                                         sb = &ld->ld_sb;
124                                 }
125 #else /* LDAP_REFERRALS */
126                                 sb = &ld->ld_sb;
127 #endif /* LDAP_REFERRALS */
128                                 if ( ber_flush( sb, ber, 1 ) != 0 ) {
129                                         ld->ld_errno = LDAP_SERVER_DOWN;
130                                         err = -1;
131                                 } else {
132                                         err = 0;
133                                 }
134                         }
135                 }
136         }
137
138 #ifdef LDAP_REFERRALS
139         if ( lr != NULL ) {
140                 if ( sendabandon ) {
141                         ldap_free_connection( ld, lr->lr_conn, 0, 1 );
142                 }
143                 if ( origid == msgid ) {
144                         ldap_free_request( ld, lr );
145                 }
146         }
147 #endif /* LDAP_REFERRALS */
148
149
150         if ( ld->ld_abandoned == NULL ) {
151                 if ( (ld->ld_abandoned = (int *) malloc( 2 * sizeof(int) ))
152                     == NULL ) {
153                         ld->ld_errno = LDAP_NO_MEMORY;
154                         return( -1 );
155                 }
156                 i = 0;
157         } else {
158                 for ( i = 0; ld->ld_abandoned[i] != -1; i++ )
159                         ;       /* NULL */
160                 if ( (ld->ld_abandoned = (int *) realloc( (char *)
161                     ld->ld_abandoned, (i + 2) * sizeof(int) )) == NULL ) {
162                         ld->ld_errno = LDAP_NO_MEMORY;
163                         return( -1 );
164                 }
165         }
166         ld->ld_abandoned[i] = msgid;
167         ld->ld_abandoned[i + 1] = -1;
168
169         if ( err != -1 ) {
170                 ld->ld_errno = LDAP_SUCCESS;
171         }
172         return( err );
173 }