Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / openldap / dist / libraries / librewrite / info.c
blob45f8c72e6e93d062cdbbb11fcd3f48f134986116
1 /* $OpenLDAP: pkg/ldap/libraries/librewrite/info.c,v 1.15.2.3 2008/02/11 23:26:42 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2000-2008 The OpenLDAP Foundation.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
9 * Public License.
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
15 /* ACKNOWLEDGEMENT:
16 * This work was initially developed by Pierangelo Masarati for
17 * inclusion in OpenLDAP Software.
20 #include <portable.h>
22 #include "rewrite-int.h"
25 * Global data
29 * This becomes the running context for subsequent calls to
30 * rewrite_parse; it can be altered only by a
31 * rewriteContext config line or by a change in info.
33 struct rewrite_context *rewrite_int_curr_context = NULL;
36 * Inits the info
38 struct rewrite_info *
39 rewrite_info_init(
40 int mode
43 struct rewrite_info *info;
44 struct rewrite_context *context;
46 switch ( mode ) {
47 case REWRITE_MODE_ERR:
48 case REWRITE_MODE_OK:
49 case REWRITE_MODE_COPY_INPUT:
50 case REWRITE_MODE_USE_DEFAULT:
51 break;
52 default:
53 mode = REWRITE_MODE_USE_DEFAULT;
54 break;
55 /* return NULL */
59 * Resets the running context for parsing ...
61 rewrite_int_curr_context = NULL;
63 info = calloc( sizeof( struct rewrite_info ), 1 );
64 if ( info == NULL ) {
65 return NULL;
68 info->li_state = REWRITE_DEFAULT;
69 info->li_max_passes = REWRITE_MAX_PASSES;
70 info->li_max_passes_per_rule = REWRITE_MAX_PASSES;
71 info->li_rewrite_mode = mode;
74 * Add the default (empty) rule
76 context = rewrite_context_create( info, REWRITE_DEFAULT_CONTEXT );
77 if ( context == NULL ) {
78 free( info );
79 return NULL;
82 #ifdef USE_REWRITE_LDAP_PVT_THREADS
83 if ( ldap_pvt_thread_rdwr_init( &info->li_cookies_mutex ) ) {
84 avl_free( info->li_context, rewrite_context_free );
85 free( info );
86 return NULL;
88 if ( ldap_pvt_thread_rdwr_init( &info->li_params_mutex ) ) {
89 ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
90 avl_free( info->li_context, rewrite_context_free );
91 free( info );
92 return NULL;
94 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
96 return info;
100 * Cleans up the info structure
103 rewrite_info_delete(
104 struct rewrite_info **pinfo
107 struct rewrite_info *info;
109 assert( pinfo != NULL );
110 assert( *pinfo != NULL );
112 info = *pinfo;
114 if ( info->li_context ) {
115 avl_free( info->li_context, rewrite_context_free );
117 info->li_context = NULL;
119 if ( info->li_maps ) {
120 avl_free( info->li_maps, rewrite_builtin_map_free );
122 info->li_maps = NULL;
124 rewrite_session_destroy( info );
126 #ifdef USE_REWRITE_LDAP_PVT_THREADS
127 ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
128 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
130 rewrite_param_destroy( info );
132 #ifdef USE_REWRITE_LDAP_PVT_THREADS
133 ldap_pvt_thread_rdwr_destroy( &info->li_params_mutex );
134 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
136 free( info );
137 *pinfo = NULL;
139 return REWRITE_SUCCESS;
143 * Rewrites a string according to context.
144 * If the engine is off, OK is returned, but the return string will be NULL.
145 * In case of 'unwilling to perform', UNWILLING is returned, and the
146 * return string will also be null. The same in case of error.
147 * Otherwise, OK is returned, and result will hold a newly allocated string
148 * with the rewriting.
150 * What to do in case of non-existing rewrite context is still an issue.
151 * Four possibilities:
152 * - error,
153 * - ok with NULL result,
154 * - ok with copy of string as result,
155 * - use the default rewrite context.
158 rewrite(
159 struct rewrite_info *info,
160 const char *rewriteContext,
161 const char *string,
162 char **result
165 return rewrite_session( info, rewriteContext,
166 string, NULL, result );
170 rewrite_session(
171 struct rewrite_info *info,
172 const char *rewriteContext,
173 const char *string,
174 const void *cookie,
175 char **result
178 struct rewrite_context *context;
179 struct rewrite_op op = { 0, 0, NULL, NULL, NULL };
180 int rc;
182 assert( info != NULL );
183 assert( rewriteContext != NULL );
184 assert( string != NULL );
185 assert( result != NULL );
188 * cookie can be null; means: don't care about session stuff
191 *result = NULL;
192 op.lo_cookie = cookie;
195 * Engine not on means no failure, but explicit no rewriting
197 if ( info->li_state != REWRITE_ON ) {
198 rc = REWRITE_REGEXEC_OK;
199 goto rc_return;
203 * Undefined context means no rewriting also
204 * (conservative, are we sure it's what we want?)
206 context = rewrite_context_find( info, rewriteContext );
207 if ( context == NULL ) {
208 switch ( info->li_rewrite_mode ) {
209 case REWRITE_MODE_ERR:
210 rc = REWRITE_REGEXEC_ERR;
211 goto rc_return;
213 case REWRITE_MODE_OK:
214 rc = REWRITE_REGEXEC_OK;
215 goto rc_return;
217 case REWRITE_MODE_COPY_INPUT:
218 *result = strdup( string );
219 rc = REWRITE_REGEXEC_OK;
220 goto rc_return;
222 case REWRITE_MODE_USE_DEFAULT:
223 context = rewrite_context_find( info,
224 REWRITE_DEFAULT_CONTEXT );
225 break;
229 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
230 op.lo_string = strdup( string );
231 if ( op.lo_string == NULL ) {
232 rc = REWRITE_REGEXEC_ERR;
233 goto rc_return;
235 #endif
238 * Applies rewrite context
240 rc = rewrite_context_apply( info, &op, context, string, result );
241 assert( op.lo_depth == 0 );
243 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
244 free( op.lo_string );
245 #endif
247 switch ( rc ) {
249 * Success
251 case REWRITE_REGEXEC_OK:
252 case REWRITE_REGEXEC_STOP:
254 * If rewrite succeeded return OK regardless of how
255 * the successful rewriting was obtained!
257 rc = REWRITE_REGEXEC_OK;
258 break;
262 * Internal or forced error, return = NULL; rc already OK.
264 case REWRITE_REGEXEC_UNWILLING:
265 case REWRITE_REGEXEC_ERR:
266 if ( *result != NULL ) {
267 if ( *result != string ) {
268 free( *result );
270 *result = NULL;
273 default:
274 break;
277 rc_return:;
278 if ( op.lo_vars ) {
279 rewrite_var_delete( op.lo_vars );
282 return rc;