Home | History | Annotate | Line # | Download | only in librewrite
info.c revision 1.1.1.2
      1  1.1.1.2  lukem /*	$NetBSD: info.c,v 1.1.1.2 2010/03/08 02:14:20 lukem Exp $	*/
      2  1.1.1.2  lukem 
      3  1.1.1.2  lukem /* OpenLDAP: pkg/ldap/libraries/librewrite/info.c,v 1.15.2.5 2009/01/22 00:00:58 kurt Exp */
      4      1.1  lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      5      1.1  lukem  *
      6  1.1.1.2  lukem  * Copyright 2000-2009 The OpenLDAP Foundation.
      7      1.1  lukem  * All rights reserved.
      8      1.1  lukem  *
      9      1.1  lukem  * Redistribution and use in source and binary forms, with or without
     10      1.1  lukem  * modification, are permitted only as authorized by the OpenLDAP
     11      1.1  lukem  * Public License.
     12      1.1  lukem  *
     13      1.1  lukem  * A copy of this license is available in the file LICENSE in the
     14      1.1  lukem  * top-level directory of the distribution or, alternatively, at
     15      1.1  lukem  * <http://www.OpenLDAP.org/license.html>.
     16      1.1  lukem  */
     17      1.1  lukem /* ACKNOWLEDGEMENT:
     18      1.1  lukem  * This work was initially developed by Pierangelo Masarati for
     19      1.1  lukem  * inclusion in OpenLDAP Software.
     20      1.1  lukem  */
     21      1.1  lukem 
     22      1.1  lukem #include <portable.h>
     23      1.1  lukem 
     24      1.1  lukem #include "rewrite-int.h"
     25      1.1  lukem 
     26      1.1  lukem /*
     27      1.1  lukem  * Global data
     28      1.1  lukem  */
     29      1.1  lukem 
     30      1.1  lukem /*
     31      1.1  lukem  * This becomes the running context for subsequent calls to
     32      1.1  lukem  * rewrite_parse; it can be altered only by a
     33      1.1  lukem  * rewriteContext config line or by a change in info.
     34      1.1  lukem  */
     35      1.1  lukem struct rewrite_context *rewrite_int_curr_context = NULL;
     36      1.1  lukem 
     37      1.1  lukem /*
     38      1.1  lukem  * Inits the info
     39      1.1  lukem  */
     40      1.1  lukem struct rewrite_info *
     41      1.1  lukem rewrite_info_init(
     42      1.1  lukem 		int mode
     43      1.1  lukem )
     44      1.1  lukem {
     45      1.1  lukem 	struct rewrite_info *info;
     46      1.1  lukem 	struct rewrite_context *context;
     47      1.1  lukem 
     48      1.1  lukem 	switch ( mode ) {
     49      1.1  lukem 	case REWRITE_MODE_ERR:
     50      1.1  lukem 	case REWRITE_MODE_OK:
     51      1.1  lukem 	case REWRITE_MODE_COPY_INPUT:
     52      1.1  lukem 	case REWRITE_MODE_USE_DEFAULT:
     53      1.1  lukem 		break;
     54      1.1  lukem 	default:
     55      1.1  lukem 		mode = REWRITE_MODE_USE_DEFAULT;
     56      1.1  lukem 		break;
     57      1.1  lukem 		/* return NULL */
     58      1.1  lukem 	}
     59      1.1  lukem 
     60      1.1  lukem 	/*
     61      1.1  lukem 	 * Resets the running context for parsing ...
     62      1.1  lukem 	 */
     63      1.1  lukem 	rewrite_int_curr_context = NULL;
     64      1.1  lukem 
     65      1.1  lukem 	info = calloc( sizeof( struct rewrite_info ), 1 );
     66      1.1  lukem 	if ( info == NULL ) {
     67      1.1  lukem 		return NULL;
     68      1.1  lukem 	}
     69      1.1  lukem 
     70      1.1  lukem 	info->li_state = REWRITE_DEFAULT;
     71      1.1  lukem 	info->li_max_passes = REWRITE_MAX_PASSES;
     72      1.1  lukem 	info->li_max_passes_per_rule = REWRITE_MAX_PASSES;
     73      1.1  lukem 	info->li_rewrite_mode = mode;
     74      1.1  lukem 
     75      1.1  lukem 	/*
     76      1.1  lukem 	 * Add the default (empty) rule
     77      1.1  lukem 	 */
     78      1.1  lukem 	context = rewrite_context_create( info, REWRITE_DEFAULT_CONTEXT );
     79      1.1  lukem 	if ( context == NULL ) {
     80      1.1  lukem 		free( info );
     81      1.1  lukem 		return NULL;
     82      1.1  lukem 	}
     83      1.1  lukem 
     84      1.1  lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
     85      1.1  lukem 	if ( ldap_pvt_thread_rdwr_init( &info->li_cookies_mutex ) ) {
     86      1.1  lukem 		avl_free( info->li_context, rewrite_context_free );
     87      1.1  lukem 		free( info );
     88      1.1  lukem 		return NULL;
     89      1.1  lukem 	}
     90      1.1  lukem 	if ( ldap_pvt_thread_rdwr_init( &info->li_params_mutex ) ) {
     91      1.1  lukem 		ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
     92      1.1  lukem 		avl_free( info->li_context, rewrite_context_free );
     93      1.1  lukem 		free( info );
     94      1.1  lukem 		return NULL;
     95      1.1  lukem 	}
     96      1.1  lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
     97      1.1  lukem 
     98      1.1  lukem 	return info;
     99      1.1  lukem }
    100      1.1  lukem 
    101      1.1  lukem /*
    102      1.1  lukem  * Cleans up the info structure
    103      1.1  lukem  */
    104      1.1  lukem int
    105      1.1  lukem rewrite_info_delete(
    106      1.1  lukem 		struct rewrite_info **pinfo
    107      1.1  lukem )
    108      1.1  lukem {
    109      1.1  lukem 	struct rewrite_info	*info;
    110      1.1  lukem 
    111      1.1  lukem 	assert( pinfo != NULL );
    112      1.1  lukem 	assert( *pinfo != NULL );
    113      1.1  lukem 
    114      1.1  lukem 	info = *pinfo;
    115      1.1  lukem 
    116      1.1  lukem 	if ( info->li_context ) {
    117      1.1  lukem 		avl_free( info->li_context, rewrite_context_free );
    118      1.1  lukem 	}
    119      1.1  lukem 	info->li_context = NULL;
    120      1.1  lukem 
    121      1.1  lukem 	if ( info->li_maps ) {
    122      1.1  lukem 		avl_free( info->li_maps, rewrite_builtin_map_free );
    123      1.1  lukem 	}
    124      1.1  lukem 	info->li_maps = NULL;
    125      1.1  lukem 
    126      1.1  lukem 	rewrite_session_destroy( info );
    127      1.1  lukem 
    128      1.1  lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
    129      1.1  lukem 	ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex );
    130      1.1  lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
    131      1.1  lukem 
    132      1.1  lukem 	rewrite_param_destroy( info );
    133      1.1  lukem 
    134      1.1  lukem #ifdef USE_REWRITE_LDAP_PVT_THREADS
    135      1.1  lukem 	ldap_pvt_thread_rdwr_destroy( &info->li_params_mutex );
    136      1.1  lukem #endif /* USE_REWRITE_LDAP_PVT_THREADS */
    137      1.1  lukem 
    138      1.1  lukem 	free( info );
    139      1.1  lukem 	*pinfo = NULL;
    140      1.1  lukem 
    141      1.1  lukem 	return REWRITE_SUCCESS;
    142      1.1  lukem }
    143      1.1  lukem 
    144      1.1  lukem /*
    145      1.1  lukem  * Rewrites a string according to context.
    146      1.1  lukem  * If the engine is off, OK is returned, but the return string will be NULL.
    147      1.1  lukem  * In case of 'unwilling to perform', UNWILLING is returned, and the
    148      1.1  lukem  * return string will also be null. The same in case of error.
    149      1.1  lukem  * Otherwise, OK is returned, and result will hold a newly allocated string
    150      1.1  lukem  * with the rewriting.
    151      1.1  lukem  *
    152      1.1  lukem  * What to do in case of non-existing rewrite context is still an issue.
    153      1.1  lukem  * Four possibilities:
    154      1.1  lukem  * 	- error,
    155      1.1  lukem  * 	- ok with NULL result,
    156      1.1  lukem  * 	- ok with copy of string as result,
    157      1.1  lukem  * 	- use the default rewrite context.
    158      1.1  lukem  */
    159      1.1  lukem int
    160      1.1  lukem rewrite(
    161      1.1  lukem 		struct rewrite_info *info,
    162      1.1  lukem 		const char *rewriteContext,
    163      1.1  lukem 		const char *string,
    164      1.1  lukem 		char **result
    165      1.1  lukem )
    166      1.1  lukem {
    167      1.1  lukem 	return rewrite_session( info, rewriteContext,
    168      1.1  lukem 			string, NULL, result );
    169      1.1  lukem }
    170      1.1  lukem 
    171      1.1  lukem int
    172      1.1  lukem rewrite_session(
    173      1.1  lukem 		struct rewrite_info *info,
    174      1.1  lukem 		const char *rewriteContext,
    175      1.1  lukem 		const char *string,
    176      1.1  lukem 		const void *cookie,
    177      1.1  lukem 		char **result
    178      1.1  lukem )
    179      1.1  lukem {
    180      1.1  lukem 	struct rewrite_context *context;
    181      1.1  lukem 	struct rewrite_op op = { 0, 0, NULL, NULL, NULL };
    182      1.1  lukem 	int rc;
    183      1.1  lukem 
    184      1.1  lukem 	assert( info != NULL );
    185      1.1  lukem 	assert( rewriteContext != NULL );
    186      1.1  lukem 	assert( string != NULL );
    187      1.1  lukem 	assert( result != NULL );
    188      1.1  lukem 
    189      1.1  lukem 	/*
    190      1.1  lukem 	 * cookie can be null; means: don't care about session stuff
    191      1.1  lukem 	 */
    192      1.1  lukem 
    193      1.1  lukem 	*result = NULL;
    194      1.1  lukem 	op.lo_cookie = cookie;
    195      1.1  lukem 
    196      1.1  lukem 	/*
    197      1.1  lukem 	 * Engine not on means no failure, but explicit no rewriting
    198      1.1  lukem 	 */
    199      1.1  lukem 	if ( info->li_state != REWRITE_ON ) {
    200      1.1  lukem 		rc = REWRITE_REGEXEC_OK;
    201      1.1  lukem 		goto rc_return;
    202      1.1  lukem 	}
    203      1.1  lukem 
    204      1.1  lukem 	/*
    205      1.1  lukem 	 * Undefined context means no rewriting also
    206      1.1  lukem 	 * (conservative, are we sure it's what we want?)
    207      1.1  lukem 	 */
    208      1.1  lukem 	context = rewrite_context_find( info, rewriteContext );
    209      1.1  lukem 	if ( context == NULL ) {
    210      1.1  lukem 		switch ( info->li_rewrite_mode ) {
    211      1.1  lukem 		case REWRITE_MODE_ERR:
    212      1.1  lukem 			rc = REWRITE_REGEXEC_ERR;
    213      1.1  lukem 			goto rc_return;
    214      1.1  lukem 
    215      1.1  lukem 		case REWRITE_MODE_OK:
    216      1.1  lukem 			rc = REWRITE_REGEXEC_OK;
    217      1.1  lukem 			goto rc_return;
    218      1.1  lukem 
    219      1.1  lukem 		case REWRITE_MODE_COPY_INPUT:
    220      1.1  lukem 			*result = strdup( string );
    221  1.1.1.2  lukem 			rc = ( *result != NULL ) ? REWRITE_REGEXEC_OK : REWRITE_REGEXEC_ERR;
    222      1.1  lukem 			goto rc_return;
    223      1.1  lukem 
    224      1.1  lukem 		case REWRITE_MODE_USE_DEFAULT:
    225      1.1  lukem 			context = rewrite_context_find( info,
    226      1.1  lukem 					REWRITE_DEFAULT_CONTEXT );
    227      1.1  lukem 			break;
    228      1.1  lukem 		}
    229      1.1  lukem 	}
    230      1.1  lukem 
    231      1.1  lukem #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
    232      1.1  lukem 	op.lo_string = strdup( string );
    233      1.1  lukem 	if ( op.lo_string == NULL ) {
    234      1.1  lukem 		rc = REWRITE_REGEXEC_ERR;
    235      1.1  lukem 		goto rc_return;
    236      1.1  lukem 	}
    237      1.1  lukem #endif
    238      1.1  lukem 
    239      1.1  lukem 	/*
    240      1.1  lukem 	 * Applies rewrite context
    241      1.1  lukem 	 */
    242      1.1  lukem 	rc = rewrite_context_apply( info, &op, context, string, result );
    243      1.1  lukem 	assert( op.lo_depth == 0 );
    244      1.1  lukem 
    245      1.1  lukem #if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */
    246      1.1  lukem 	free( op.lo_string );
    247      1.1  lukem #endif
    248      1.1  lukem 
    249      1.1  lukem 	switch ( rc ) {
    250      1.1  lukem 	/*
    251      1.1  lukem 	 * Success
    252      1.1  lukem 	 */
    253      1.1  lukem 	case REWRITE_REGEXEC_OK:
    254      1.1  lukem 	case REWRITE_REGEXEC_STOP:
    255      1.1  lukem 		/*
    256      1.1  lukem 		 * If rewrite succeeded return OK regardless of how
    257      1.1  lukem 		 * the successful rewriting was obtained!
    258      1.1  lukem 		 */
    259      1.1  lukem 		rc = REWRITE_REGEXEC_OK;
    260      1.1  lukem 		break;
    261      1.1  lukem 
    262      1.1  lukem 
    263      1.1  lukem 	/*
    264      1.1  lukem 	 * Internal or forced error, return = NULL; rc already OK.
    265      1.1  lukem 	 */
    266      1.1  lukem 	case REWRITE_REGEXEC_UNWILLING:
    267      1.1  lukem 	case REWRITE_REGEXEC_ERR:
    268      1.1  lukem 		if ( *result != NULL ) {
    269      1.1  lukem 			if ( *result != string ) {
    270      1.1  lukem 				free( *result );
    271      1.1  lukem 			}
    272      1.1  lukem 			*result = NULL;
    273      1.1  lukem 		}
    274      1.1  lukem 
    275      1.1  lukem 	default:
    276      1.1  lukem 		break;
    277      1.1  lukem 	}
    278      1.1  lukem 
    279      1.1  lukem rc_return:;
    280      1.1  lukem 	if ( op.lo_vars ) {
    281      1.1  lukem 		rewrite_var_delete( op.lo_vars );
    282      1.1  lukem 	}
    283      1.1  lukem 
    284      1.1  lukem 	return rc;
    285      1.1  lukem }
    286      1.1  lukem 
    287