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