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