2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2000-2004 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
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>.
16 * This work was initially developed by Pierangelo Masarati for
17 * inclusion in OpenLDAP Software.
22 #include "rewrite-int.h"
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;
43 struct rewrite_info *info;
44 struct rewrite_context *context;
47 case REWRITE_MODE_ERR:
49 case REWRITE_MODE_COPY_INPUT:
50 case REWRITE_MODE_USE_DEFAULT:
53 mode = REWRITE_MODE_USE_DEFAULT;
59 * Resets the running context for parsing ...
61 rewrite_int_curr_context = NULL;
63 info = calloc( sizeof( struct rewrite_info ), 1 );
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 ) {
82 #ifdef USE_REWRITE_LDAP_PVT_THREADS
83 if ( ldap_pvt_thread_rdwr_init( &info->li_cookies_mutex ) ) {
87 if ( ldap_pvt_thread_rdwr_init( &info->li_params_mutex ) ) {
91 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
97 * Cleans up the info structure
101 struct rewrite_info **pinfo
104 struct rewrite_info *info;
106 assert( pinfo != NULL );
107 assert( *pinfo != NULL );
111 if ( info->li_context ) {
112 avl_free( info->li_context, rewrite_context_free );
114 info->li_context = NULL;
116 if ( info->li_maps ) {
117 avl_free( info->li_maps, rewrite_builtin_map_free );
119 info->li_context = NULL;
121 rewrite_session_destroy( info );
123 #ifdef USE_REWRITE_LDAP_PVT_THREADS
124 ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
125 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
127 rewrite_param_destroy( info );
129 #ifdef USE_REWRITE_LDAP_PVT_THREADS
130 ldap_pvt_thread_rdwr_destroy( &info->li_params_mutex );
131 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
136 return REWRITE_SUCCESS;
140 * Rewrites a string according to context.
141 * If the engine is off, OK is returned, but the return string will be NULL.
142 * In case of 'unwilling to perform', UNWILLING is returned, and the
143 * return string will also be null. The same in case of error.
144 * Otherwise, OK is returned, and result will hold a newly allocated string
145 * with the rewriting.
147 * What to do in case of non-existing rewrite context is still an issue.
148 * Four possibilities:
150 * - ok with NULL result,
151 * - ok with copy of string as result,
152 * - use the default rewrite context.
156 struct rewrite_info *info,
157 const char *rewriteContext,
162 return rewrite_session( info, rewriteContext,
163 string, NULL, result );
168 struct rewrite_info *info,
169 const char *rewriteContext,
175 struct rewrite_context *context;
176 struct rewrite_op op = { 0, 0, NULL, NULL, NULL };
179 assert( info != NULL );
180 assert( rewriteContext != NULL );
181 assert( string != NULL );
182 assert( result != NULL );
185 * cookie can be null; means: don't care about session stuff
189 op.lo_cookie = cookie;
192 * Engine not on means no failure, but explicit no rewriting
194 if ( info->li_state != REWRITE_ON ) {
195 rc = REWRITE_REGEXEC_OK;
200 * Undefined context means no rewriting also
201 * (conservative, are we sure it's what we want?)
203 context = rewrite_context_find( info, rewriteContext );
204 if ( context == NULL ) {
205 switch ( info->li_rewrite_mode ) {
206 case REWRITE_MODE_ERR:
207 rc = REWRITE_REGEXEC_ERR;
210 case REWRITE_MODE_OK:
211 rc = REWRITE_REGEXEC_OK;
214 case REWRITE_MODE_COPY_INPUT:
215 *result = strdup( string );
216 rc = REWRITE_REGEXEC_OK;
219 case REWRITE_MODE_USE_DEFAULT:
220 context = rewrite_context_find( info,
221 REWRITE_DEFAULT_CONTEXT );
226 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
227 op.lo_string = strdup( string );
228 if ( op.lo_string == NULL ) {
229 rc = REWRITE_REGEXEC_ERR;
235 * Applies rewrite context
237 rc = rewrite_context_apply( info, &op, context, string, result );
238 assert( op.lo_depth == 0 );
240 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
241 free( op.lo_string );
248 case REWRITE_REGEXEC_OK:
249 case REWRITE_REGEXEC_STOP:
251 * If rewrite succeeded return OK regardless of how
252 * the successful rewriting was obtained!
254 rc = REWRITE_REGEXEC_OK;
259 * Internal or forced error, return = NULL; rc already OK.
261 case REWRITE_REGEXEC_UNWILLING:
262 case REWRITE_REGEXEC_ERR:
263 if ( *result != NULL ) {
274 rewrite_var_delete( op.lo_vars );