Back to index

openldap  2.4.31
Functions
context.c File Reference
#include <portable.h>
#include "rewrite-int.h"

Go to the source code of this file.

Functions

static int rewrite_context_cmp (const void *c1, const void *c2)
static int rewrite_context_dup (void *c1, void *c2)
struct rewrite_contextrewrite_context_find (struct rewrite_info *info, const char *rewriteContext)
struct rewrite_contextrewrite_context_create (struct rewrite_info *info, const char *rewriteContext)
static struct rewrite_rulerewrite_action_goto (struct rewrite_action *action, struct rewrite_rule *rule)
int rewrite_context_apply (struct rewrite_info *info, struct rewrite_op *op, struct rewrite_context *context, const char *string, char **result)
void rewrite_context_free (void *tmp)
int rewrite_context_destroy (struct rewrite_context **pcontext)

Function Documentation

static struct rewrite_rule* rewrite_action_goto ( struct rewrite_action action,
struct rewrite_rule rule 
) [static, read]

Definition at line 165 of file context.c.

{
       int n;
       
       assert( action != NULL );
       assert( action->la_args != NULL );
       assert( rule != NULL );
       
       n = ((int *)action->la_args)[ 0 ];
       
       if ( n > 0 ) {
              for ( ; n > 1 && rule != NULL ; n-- ) {
                     rule = rule->lr_next;
              }
       } else if ( n <= 0 ) {
              for ( ; n < 1 && rule != NULL ; n++ ) {
                     rule = rule->lr_prev;
              }
       }

       return rule;
}

Here is the caller graph for this function:

int rewrite_context_apply ( struct rewrite_info info,
struct rewrite_op op,
struct rewrite_context context,
const char *  string,
char **  result 
)

Definition at line 198 of file context.c.

{
       struct rewrite_rule *rule;
       char *s, *res = NULL;
       int return_code = REWRITE_REGEXEC_OK;
       
       assert( info != NULL );
       assert( op != NULL );
       assert( context != NULL );
       assert( context->lc_rule != NULL );
       assert( string != NULL );
       assert( result != NULL );

       op->lo_depth++;

       Debug( LDAP_DEBUG_TRACE, "==> rewrite_context_apply"
                     " [depth=%d] string='%s'\n",
                     op->lo_depth, string, 0 );
       assert( op->lo_depth > 0 );
       
       s = (char *)string;
       
       for ( rule = context->lc_rule->lr_next;
                     rule != NULL && op->lo_num_passes < info->li_max_passes;
                     rule = rule->lr_next, op->lo_num_passes++ ) {
              int rc;
              
              /*
               * Apply a single rule
               */
              rc = rewrite_rule_apply( info, op, rule, s, &res );
              
              /*
               * A rule may return:
               *     OK            with result != NULL if matched
               *     ERR           if anything was wrong
               *     UNWILLING     if the server should drop the request
               * the latter case in honored immediately;
               * the other two may require some special actions to take
               * place.
               */
              switch ( rc ) {
                     
              case REWRITE_REGEXEC_ERR:
                     Debug( LDAP_DEBUG_ANY, "==> rewrite_context_apply"
                                   " error ...\n", 0, 0, 0);

                     /*
                      * Checks for special actions to be taken
                      * in case of error ...
                      */
                     if ( rule->lr_action != NULL ) {
                            struct rewrite_action *action;
                            int do_continue = 0;
                            
                            for ( action = rule->lr_action;
                                          action != NULL;
                                          action = action->la_next ) {
                                   switch ( action->la_type ) {
                                   
                                   /*
                                    * This action takes precedence
                                    * over the others in case of failure
                                    */
                                   case REWRITE_ACTION_IGNORE_ERR:
                                          Debug( LDAP_DEBUG_ANY,
                                   "==> rewrite_context_apply"
                                   " ignoring error ...\n", 0, 0, 0 );
                                          do_continue = 1;
                                          break;

                                   /*
                                    * Goto is honored only if it comes
                                    * after ignore error
                                    */
                                   case REWRITE_ACTION_GOTO:
                                          if ( do_continue ) {
                                                 rule = rewrite_action_goto( action, rule );
                                                 if ( rule == NULL ) {
                                                        return_code = REWRITE_REGEXEC_ERR;
                                                        goto rc_end_of_context;
                                                 }
                                          }
                                          break;

                                   /*
                                    * Other actions are ignored
                                    */
                                   default:
                                          break;
                                   }
                            }

                            if ( do_continue ) {
                                   if ( rule->lr_next == NULL ) {
                                          res = s;
                                   }
                                   goto rc_continue;
                            }
                     }

                     /* 
                      * Default behavior is to bail out ...
                      */
                     return_code = REWRITE_REGEXEC_ERR;
                     goto rc_end_of_context;
              
              /*
               * OK means there were no errors or special return codes;
               * if res is defined, it means the rule matched and we
               * got a sucessful rewriting
               */
              case REWRITE_REGEXEC_OK:

                     /*
                      * It matched! Check for actions ...
                      */
                     if ( res != NULL ) {
                            struct rewrite_action *action;
                            
                            if ( s != string && s != res ) {
                                   free( s );
                            }
                            s = res;

                            for ( action = rule->lr_action;
                                          action != NULL;
                                          action = action->la_next ) {

                                   switch ( action->la_type ) {

                                   /*
                                    * This ends the rewrite context
                                    * successfully
                                    */
                                   case REWRITE_ACTION_STOP:
                                          goto rc_end_of_context;
                                   
                                   /*
                                    * This instructs the server to return
                                    * an `unwilling to perform' error
                                    * message
                                    */
                                   case REWRITE_ACTION_UNWILLING:
                                          return_code = REWRITE_REGEXEC_UNWILLING;
                                          goto rc_end_of_context;
                                   
                                   /*
                                    * This causes the processing to
                                    * jump n rules back and forth
                                    */
                                   case REWRITE_ACTION_GOTO:
                                          rule = rewrite_action_goto( action, rule );
                                          if ( rule == NULL ) {
                                                 return_code = REWRITE_REGEXEC_ERR;
                                                 goto rc_end_of_context;
                                          }
                                          break;

                                   /*
                                    * This ends the rewrite context
                                    * and returns a user-defined
                                    * error code
                                    */
                                   case REWRITE_ACTION_USER:
                                          return_code = ((int *)action->la_args)[ 0 ];
                                          goto rc_end_of_context;
                                   
                                   default:
                                          /* ... */
                                          break;
                                   }
                            }

                     /*
                      * If result was OK and string didn't match,
                      * in case of last rule we need to set the
                      * result back to the string
                      */
                     } else if ( rule->lr_next == NULL ) {
                            res = s;
                     }
                     
                     break;

              /*
               * A STOP has propagated ...
               */
              case REWRITE_REGEXEC_STOP:
                     goto rc_end_of_context;

              /*
               * This will instruct the server to return
               * an `unwilling to perform' error message
               */
              case REWRITE_REGEXEC_UNWILLING:
                     return_code = REWRITE_REGEXEC_UNWILLING;
                     goto rc_end_of_context;

              /*
               * A user-defined error code has propagated ...
               */
              default:
                     assert( rc >= REWRITE_REGEXEC_USER );
                     goto rc_end_of_context;

              }
              
rc_continue:; /* sent here by actions that require to continue */

       }

rc_end_of_context:;
       *result = res;

       Debug( LDAP_DEBUG_TRACE, "==> rewrite_context_apply"
                     " [depth=%d] res={%d,'%s'}\n",
                     op->lo_depth, return_code, ( res ? res : "NULL" ) );

       assert( op->lo_depth > 0 );
       op->lo_depth--;

       return return_code;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int rewrite_context_cmp ( const void c1,
const void c2 
) [static]

Definition at line 29 of file context.c.

{
       const struct rewrite_context *lc1, *lc2;
       
       lc1 = (const struct rewrite_context *)c1;
       lc2 = (const struct rewrite_context *)c2;
       
       assert( c1 != NULL );
       assert( c2 != NULL );
       assert( lc1->lc_name != NULL );
       assert( lc2->lc_name != NULL );
       
       return strcasecmp( lc1->lc_name, lc2->lc_name );
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct rewrite_context* rewrite_context_create ( struct rewrite_info info,
const char *  rewriteContext 
) [read]

Definition at line 108 of file context.c.

{
       struct rewrite_context *context;
       int rc;

       assert( info != NULL );
       assert( rewriteContext != NULL );
       
       context = calloc( sizeof( struct rewrite_context ), 1 );
       if ( context == NULL ) {
              return NULL;
       }
       
       /*
        * Context name
        */
       context->lc_name = strdup( rewriteContext );
       if ( context->lc_name == NULL ) {
              free( context );
              return NULL;
       }

       /*
        * The first, empty rule
        */
       context->lc_rule = calloc( sizeof( struct rewrite_rule ), 1 );
       if ( context->lc_rule == NULL ) {
              free( context->lc_name );
              free( context );
              return NULL;
       }
       memset( context->lc_rule, 0, sizeof( struct rewrite_rule ) );
       
       /*
        * Add context to tree
        */
       rc = avl_insert( &info->li_context, (caddr_t)context,
                     rewrite_context_cmp, rewrite_context_dup );
       if ( rc == -1 ) {
              free( context->lc_rule );
              free( context->lc_name );
              free( context );
              return NULL;
       }

       return context;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int rewrite_context_destroy ( struct rewrite_context **  pcontext)

Definition at line 442 of file context.c.

{
       struct rewrite_context *context;
       struct rewrite_rule *r;

       assert( pcontext != NULL );
       assert( *pcontext != NULL );

       context = *pcontext;

       assert( context->lc_rule != NULL );

       for ( r = context->lc_rule->lr_next; r; ) {
              struct rewrite_rule *cr = r;

              r = r->lr_next;
              rewrite_rule_destroy( &cr );
       }

       free( context->lc_rule );
       context->lc_rule = NULL;

       assert( context->lc_name != NULL );
       free( context->lc_name );
       context->lc_name = NULL;

       free( context );
       *pcontext = NULL;
       
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int rewrite_context_dup ( void c1,
void c2 
) [static]

Definition at line 52 of file context.c.

{
       struct rewrite_context *lc1, *lc2;
       
       lc1 = (struct rewrite_context *)c1;
       lc2 = (struct rewrite_context *)c2;
       
       assert( c1 != NULL );
       assert( c2 != NULL );
       assert( lc1->lc_name != NULL );
       assert( lc2->lc_name != NULL );
       
       return( strcasecmp( lc1->lc_name, lc2->lc_name) == 0 ? -1 : 0 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct rewrite_context* rewrite_context_find ( struct rewrite_info info,
const char *  rewriteContext 
) [read]

Definition at line 74 of file context.c.

{
       struct rewrite_context *context, c;

       assert( info != NULL );
       assert( rewriteContext != NULL );

       /*
        * Fetches the required rewrite context
        */
       c.lc_name = (char *)rewriteContext;
       context = (struct rewrite_context *)avl_find( info->li_context, 
                     (caddr_t)&c, rewrite_context_cmp );
       if ( context == NULL ) {
              return NULL;
       }

       /*
        * De-aliases the context if required
        */
       if ( context->lc_alias ) {
              return context->lc_alias;
       }

       return context;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 430 of file context.c.

{
       struct rewrite_context *context = (struct rewrite_context *)tmp;

       assert( tmp != NULL );

       rewrite_context_destroy( &context );
}

Here is the call graph for this function:

Here is the caller graph for this function: