]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/search.c
3105cb00649aa47a2d3b4c7e5321194d6bb428f9
[openldap] / servers / slapd / back-monitor / search.c
1 /* search.c - monitor backend search function */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2001-2004 The OpenLDAP Foundation.
6  * Portions Copyright 2001-2003 Pierangelo Masarati.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* ACKNOWLEDGEMENTS:
18  * This work was initially developed by Pierangelo Masarati for inclusion
19  * in OpenLDAP Software.
20  */
21
22 #include "portable.h"
23
24 #include <stdio.h>
25
26 #include <ac/string.h>
27 #include <ac/socket.h>
28
29 #include "slap.h"
30 #include "back-monitor.h"
31 #include "proto-back-monitor.h"
32
33 static int
34 monitor_send_children(
35         Operation       *op,
36         SlapReply       *rs,
37         Entry           *e_parent,
38         int             sub
39 )
40 {
41         monitor_info_t  *mi = ( monitor_info_t * )op->o_bd->be_private;
42         Entry                   *e, *e_tmp, *e_ch;
43         monitor_entry_t *mp;
44         int                     rc;
45
46         mp = ( monitor_entry_t * )e_parent->e_private;
47         e = mp->mp_children;
48
49         e_ch = NULL;
50         if ( MONITOR_HAS_VOLATILE_CH( mp ) ) {
51                 monitor_entry_create( op, NULL, e_parent, &e_ch );
52         }
53         monitor_cache_release( mi, e_parent );
54
55         /* no volatile entries? */
56         if ( e_ch == NULL ) {
57                 /* no persistent entries? return */
58                 if ( e == NULL ) {
59                         return( 0 );
60                 }
61         
62         /* volatile entries */
63         } else {
64                 /* if no persistent, return only volatile */
65                 if ( e == NULL ) {
66                         e = e_ch;
67                         monitor_cache_lock( e_ch );
68
69                 /* else append persistent to volatile */
70                 } else {
71                         e_tmp = e_ch;
72                         do {
73                                 mp = ( monitor_entry_t * )e_tmp->e_private;
74                                 e_tmp = mp->mp_next;
75         
76                                 if ( e_tmp == NULL ) {
77                                         mp->mp_next = e;
78                                         break;
79                                 }
80                         } while ( e_tmp );
81                         e = e_ch;
82                 }
83         }
84
85         /* return entries */
86         for ( ; e != NULL; ) {
87                 mp = ( monitor_entry_t * )e->e_private;
88
89                 monitor_entry_update( op, e );
90                 
91                 rc = test_filter( op, e, op->oq_search.rs_filter );
92                 if ( rc == LDAP_COMPARE_TRUE ) {
93                         rs->sr_entry = e;
94                         rs->sr_flags = 0;
95                         send_search_entry( op, rs );
96                         rs->sr_entry = NULL;
97                 }
98
99                 if ( ( mp->mp_children || MONITOR_HAS_VOLATILE_CH( mp ) )
100                                 && sub ) {
101                         rc = monitor_send_children( op, rs, e, sub );
102                         if ( rc ) {
103                                 return( rc );
104                         }
105                 }
106
107                 e_tmp = mp->mp_next;
108                 if ( e_tmp != NULL ) {
109                         monitor_cache_lock( e_tmp );
110                 }
111                 monitor_cache_release( mi, e );
112                 e = e_tmp;
113         }
114         
115         return( 0 );
116 }
117
118 int
119 monitor_back_search( Operation *op, SlapReply *rs )
120 {
121         monitor_info_t  *mi = ( monitor_info_t * )op->o_bd->be_private;
122         int             rc = LDAP_SUCCESS;
123         Entry           *e = NULL, *matched = NULL;
124
125         Debug( LDAP_DEBUG_TRACE, "=> monitor_back_search\n", 0, 0, 0 );
126
127
128         /* get entry with reader lock */
129         monitor_cache_dn2entry( op, &op->o_req_ndn, &e, &matched );
130         if ( e == NULL ) {
131                 rs->sr_err = LDAP_NO_SUCH_OBJECT;
132                 if ( matched ) {
133                         rs->sr_matched = matched->e_dn;
134                 }
135
136                 send_ldap_result( op, rs );
137                 if ( matched ) {
138                         monitor_cache_release( mi, matched );
139                         rs->sr_matched = NULL;
140                 }
141
142                 return( 0 );
143         }
144
145         rs->sr_attrs = op->oq_search.rs_attrs;
146         switch ( op->oq_search.rs_scope ) {
147         case LDAP_SCOPE_BASE:
148                 monitor_entry_update( op, e );
149                 rc = test_filter( op, e, op->oq_search.rs_filter );
150                 if ( rc == LDAP_COMPARE_TRUE ) {
151                         rs->sr_entry = e;
152                         rs->sr_flags = 0;
153                         send_search_entry( op, rs );
154                         rs->sr_entry = NULL;
155                 }
156                 rc = LDAP_SUCCESS;
157                 monitor_cache_release( mi, e );
158                 break;
159
160         case LDAP_SCOPE_ONELEVEL:
161                 rc = monitor_send_children( op, rs, e, 0 );
162                 if ( rc ) {
163                         rc = LDAP_OTHER;
164                 }
165                 
166                 break;
167
168         case LDAP_SCOPE_SUBTREE:
169                 monitor_entry_update( op, e );
170                 rc = test_filter( op, e, op->oq_search.rs_filter );
171                 if ( rc == LDAP_COMPARE_TRUE ) {
172                         rs->sr_entry = e;
173                         rs->sr_flags = 0;
174                         send_search_entry( op, rs );
175                         rs->sr_entry = NULL;
176                 }
177
178                 rc = monitor_send_children( op, rs, e, 1 );
179                 if ( rc ) {
180                         rc = LDAP_OTHER;
181                 }
182
183                 break;
184         }
185         
186         rs->sr_attrs = NULL;
187         rs->sr_err = rc;
188         send_ldap_result( op, rs );
189
190         return( rc == LDAP_SUCCESS ? 0 : 1 );
191 }
192