1 /******************************************************************************
3 * Copyright (C) 2000 Pierangelo Masarati, <ando@sys-net.it>
6 * Permission is granted to anyone to use this software for any purpose
7 * on any computer system, and to alter it and redistribute it, subject
8 * to the following restrictions:
10 * 1. The author is not responsible for the consequences of use of this
11 * software, no matter how awful, even if they arise from flaws in it.
13 * 2. The origin of this software must not be misrepresented, either by
14 * explicit claim or by omission. Since few users ever read sources,
15 * credits should appear in the documentation.
17 * 3. Altered versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software. Since few users
19 * ever read sources, credits should appear in the documentation.
21 * 4. This notice may not be removed or altered.
23 ******************************************************************************/
27 #include "rewrite-int.h"
34 * This becomes the running context for subsequent calls to
35 * rewrite_parse; it can be altered only by a
36 * rewriteContext config line or by a change in info.
38 struct rewrite_context *rewrite_int_curr_context = NULL;
48 struct rewrite_info *info;
49 struct rewrite_context *context;
52 case REWRITE_MODE_ERR:
54 case REWRITE_MODE_COPY_INPUT:
55 case REWRITE_MODE_USE_DEFAULT:
58 mode = REWRITE_MODE_USE_DEFAULT;
64 * Resets the running context for parsing ...
66 rewrite_int_curr_context = NULL;
68 info = calloc( sizeof( struct rewrite_info ), 1 );
73 info->li_state = REWRITE_DEFAULT;
74 info->li_max_passes = REWRITE_MAX_PASSES;
75 info->li_rewrite_mode = mode;
78 * Add the default (empty) rule
80 context = rewrite_context_create( info, REWRITE_DEFAULT_CONTEXT );
81 if ( context == NULL ) {
86 #ifdef USE_REWRITE_LDAP_PVT_THREADS
87 if ( ldap_pvt_thread_rdwr_init( &info->li_cookies_mutex ) ) {
91 if ( ldap_pvt_thread_rdwr_init( &info->li_params_mutex ) ) {
95 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
101 * Cleans up the info structure
105 struct rewrite_info **pinfo
108 struct rewrite_info *info;
110 assert( pinfo != NULL );
111 assert( *pinfo != NULL );
115 if ( info->li_context ) {
116 avl_free( info->li_context, rewrite_context_free );
118 info->li_context = NULL;
120 if ( info->li_maps ) {
121 avl_free( info->li_maps, rewrite_builtin_map_free );
123 info->li_context = NULL;
125 rewrite_session_destroy( info );
127 #ifdef USE_REWRITE_LDAP_PVT_THREADS
128 ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
129 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
131 rewrite_param_destroy( info );
133 #ifdef USE_REWRITE_LDAP_PVT_THREADS
134 ldap_pvt_thread_rdwr_destroy( &info->li_params_mutex );
135 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
140 return REWRITE_SUCCESS;
144 * Rewrites a string according to context.
145 * If the engine is off, OK is returned, but the return string will be NULL.
146 * In case of 'unwilling to perform', UNWILLING is returned, and the
147 * return string will also be null. The same in case of error.
148 * Otherwise, OK is returned, and result will hold a newly allocated string
149 * with the rewriting.
151 * What to do in case of non-existing rewrite context is still an issue.
152 * Four possibilities:
154 * - ok with NULL result,
155 * - ok with copy of string as result,
156 * - use the default rewrite context.
160 struct rewrite_info *info,
161 const char *rewriteContext,
166 return rewrite_session( info, rewriteContext,
167 string, NULL, result );
172 struct rewrite_info *info,
173 const char *rewriteContext,
179 struct rewrite_context *context;
180 struct rewrite_op op = { 0, 0, NULL, NULL, NULL };
183 assert( info != NULL );
184 assert( rewriteContext != NULL );
185 assert( string != NULL );
186 assert( result != NULL );
189 * cookie can be null; means: don't care about session stuff
193 op.lo_cookie = cookie;
196 * Engine not on means no failure, but explicit no rewriting
198 if ( info->li_state != REWRITE_ON ) {
199 rc = REWRITE_REGEXEC_OK;
204 * Undefined context means no rewriting also
205 * (conservative, are we sure it's what we want?)
207 context = rewrite_context_find( info, rewriteContext );
208 if ( context == NULL ) {
209 switch ( info->li_rewrite_mode ) {
210 case REWRITE_MODE_ERR:
211 rc = REWRITE_REGEXEC_ERR;
214 case REWRITE_MODE_OK:
215 rc = REWRITE_REGEXEC_OK;
218 case REWRITE_MODE_COPY_INPUT:
219 *result = strdup( string );
220 rc = REWRITE_REGEXEC_OK;
223 case REWRITE_MODE_USE_DEFAULT:
224 context = rewrite_context_find( info,
225 REWRITE_DEFAULT_CONTEXT );
230 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
231 op.lo_string = strdup( string );
232 if ( op.lo_string == NULL ) {
233 rc = REWRITE_REGEXEC_ERR;
239 * Applies rewrite context
241 rc = rewrite_context_apply( info, &op, context, string, result );
242 assert( op.lo_depth == 0 );
244 #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
245 free( op.lo_string );
252 case REWRITE_REGEXEC_OK:
253 case REWRITE_REGEXEC_STOP:
255 * If rewrite succeeded return OK regardless of how
256 * the successful rewriting was obtained!
258 rc = REWRITE_REGEXEC_OK;
263 * Internal or forced error, return = NULL; rc already OK.
265 case REWRITE_REGEXEC_UNWILLING:
266 case REWRITE_REGEXEC_ERR:
268 if ( *result != NULL ) {
276 rewrite_var_delete( op.lo_vars );