]> git.sur5r.net Git - openldap/commitdiff
allow memory ownership specification when using (session- wide) variables
authorPierangelo Masarati <ando@openldap.org>
Sat, 27 Dec 2003 18:48:06 +0000 (18:48 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 27 Dec 2003 18:48:06 +0000 (18:48 +0000)
include/rewrite.h
libraries/librewrite/rewrite-int.h
libraries/librewrite/session.c
libraries/librewrite/var.c

index fdf7c1f4dfb86aa3d18a070226178413ed4beb69..6e6bc86e062d866f055b8ea6ea12c9230e72ceff 100644 (file)
 #define REWRITE_REGEXEC_STOP            0x0002
 #define REWRITE_REGEXEC_UNWILLING       0x0004
 
+/*
+ * Rewrite variable flags
+ *     REWRITE_VAR_INSERT              insert mode (default) when adding
+ *                                     a variable; if not set during value
+ *                                     update, the variable is not inserted
+ *                                     if not present
+ *     REWRITE_VAR_UPDATE              update mode (default) when updating
+ *                                     a variable; if not set during insert,
+ *                                     the value is not updated if the
+ *                                     variable already exists
+ *     REWRITE_VAR_COPY_NAME           copy the variable name; if not set,
+ *                                     the name is not copied; be sure the
+ *                                     referenced string is available for
+ *                                     the entire life scope of the variable.
+ *     REWRITE_VAR_COPY_VALUE          copy the variable value; if not set,
+ *                                     the value is not copied; be sure the
+ *                                     referenced string is available for
+ *                                     the entire life scope of the variable.
+ */
+#define REWRITE_VAR_INSERT             0x0001
+#define REWRITE_VAR_UPDATE             0x0002
+#define REWRITE_VAR_COPY_NAME          0x0004
+#define REWRITE_VAR_COPY_VALUE         0x0008
+
 /*
  * Rewrite info
  */
@@ -177,13 +201,18 @@ rewrite_session_init(
  * Defines and inits a variable with session scope
  */
 LDAP_REWRITE_F (int)
-rewrite_session_var_set(
+rewrite_session_var_set_f(
                struct rewrite_info *info,
                const void *cookie,
                const char *name,
-               const char *value
+               const char *value,
+               int flags
 );
 
+#define rewrite_session_var_set(info, cookie, name, value) \
+       rewrite_session_var_set_f((info), (cookie), (name), (value), \
+                       REWRITE_VAR_INSERT|REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE)
+
 /*
  * Deletes a session
  */
index 3f14b0c16030f63b3f8c3fbe582089708f998212..c08b5f047a6cdf18c31b4e089e3d495c20ad6b84 100644 (file)
@@ -248,6 +248,7 @@ struct rewrite_session {
  */
 struct rewrite_var {
        char                           *lv_name;
+       int                             lv_flags;
        struct berval                   lv_value;
 };
 
@@ -459,11 +460,12 @@ rewrite_session_find(
  * Defines and inits a variable with session scope
  */
 LDAP_REWRITE_F (int)
-rewrite_session_var_set(
+rewrite_session_var_set_f(
                 struct rewrite_info *info,
                 const void *cookie,
                 const char *name,
-                const char *value
+                const char *value,
+               int flags
 );
 
 /*
@@ -508,27 +510,46 @@ rewrite_var_find(
                 const char *name
 );
 
+/*
+ * Replaces the value of a variable
+ */
+LDAP_REWRITE_F (int)
+rewrite_var_replace(
+               struct rewrite_var *var,
+               const char *value,
+               int flags
+);
+
 /*
  * Inserts a newly created var
  */
 LDAP_REWRITE_F (struct rewrite_var *)
-rewrite_var_insert(
+rewrite_var_insert_f(
                 Avlnode **tree,
                 const char *name,
-                const char *value
+                const char *value,
+               int flags
 );
 
+#define rewrite_var_insert(tree, name, value) \
+       rewrite_var_insert_f((tree), (name), (value), \
+                       REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE)
+
 /*
  * Sets/inserts a var
  */
 LDAP_REWRITE_F (struct rewrite_var *)
-rewrite_var_set(
+rewrite_var_set_f(
                 Avlnode **tree,
                 const char *name,
                 const char *value,
-                int insert
+                int flags
 );
 
+#define rewrite_var_set(tree, name, value, insert) \
+       rewrite_var_set_f((tree), (name), (value), \
+                       REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE|((insert)? REWRITE_VAR_INSERT : 0))
+
 /*
  * Deletes a var tree
  */
index 3a09fb40d2be1a82371621a9556a665a2754cea0..34feb4959ed0213c04bbb3438c8e542d6cc1d210 100644 (file)
@@ -185,11 +185,12 @@ rewrite_session_return(
  * Defines and inits a var with session scope
  */
 int
-rewrite_session_var_set(
+rewrite_session_var_set_f(
                struct rewrite_info *info,
                const void *cookie,
                const char *name,
-               const char *value
+               const char *value,
+               int flags
 )
 {
        struct rewrite_session *session;
@@ -212,11 +213,11 @@ rewrite_session_var_set(
        var = rewrite_var_find( session->ls_vars, name );
        if ( var != NULL ) {
                assert( var->lv_value.bv_val != NULL );
-               free( var->lv_value.bv_val );
-               var->lv_value.bv_val = strdup( value );
-               var->lv_value.bv_len = strlen( value );
+
+               (void)rewrite_var_replace( var, value, flags );
+
        } else {
-               var = rewrite_var_insert( &session->ls_vars, name, value );
+               var = rewrite_var_insert_f( &session->ls_vars, name, value, flags );
                if ( var == NULL ) {
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
                        ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
index 9a4ca786f90f1a65b03b76a7bb977493595f56a5..80bba9f1824c699b78e8157b25593d7f8f6d3a3f 100644 (file)
@@ -65,6 +65,39 @@ rewrite_var_dup(
        return ( strcasecmp( v1->lv_name, v2->lv_name ) == 0 ? -1 : 0 );
 }
 
+/*
+ * Frees a var
+ */
+static void 
+rewrite_var_free(
+               void *v_var
+)
+{
+       struct rewrite_var *var = v_var;
+       assert( var != NULL );
+
+       assert( var->lv_name != NULL );
+       assert( var->lv_value.bv_val != NULL );
+
+       if ( var->lv_flags & REWRITE_VAR_COPY_NAME )
+               free( var->lv_name );
+       if ( var->lv_flags & REWRITE_VAR_COPY_VALUE )
+               free( var->lv_value.bv_val );
+       free( var );
+}
+
+/*
+ * Deletes a var tree
+ */
+int
+rewrite_var_delete(
+               Avlnode *tree
+)
+{
+       avl_free( tree, rewrite_var_free );
+       return REWRITE_SUCCESS;
+}
+
 /*
  * Finds a var
  */
@@ -83,51 +116,112 @@ rewrite_var_find(
                        ( caddr_t )&var, rewrite_var_cmp );
 }
 
+int
+rewrite_var_replace(
+               struct rewrite_var *var,
+               const char *value,
+               int flags
+)
+{
+       ber_len_t       len = strlen( value );
+
+       if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) {
+               if ( flags & REWRITE_VAR_COPY_VALUE ) {
+                       if ( len <= var->lv_value.bv_len ) {
+                               AC_MEMCPY(var->lv_value.bv_val, value, len + 1);
+
+                       } else {
+                               free( var->lv_value.bv_val );
+                               var->lv_value.bv_val = strdup( value );
+                       }
+
+               } else {
+                       free( var->lv_value.bv_val );
+                       var->lv_value.bv_val = (char *)value;
+                       var->lv_flags &= ~REWRITE_VAR_COPY_VALUE;
+               }
+
+       } else {
+               if ( flags & REWRITE_VAR_COPY_VALUE ) {
+                       var->lv_value.bv_val = strdup( value );
+                       var->lv_flags |= REWRITE_VAR_COPY_VALUE;
+
+               } else {
+                       var->lv_value.bv_val = (char *)value;
+               }
+       }
+
+       var->lv_value.bv_len = len;
+
+       return 0;
+}
+
 /*
  * Inserts a newly created var
  */
 struct rewrite_var *
-rewrite_var_insert(
+rewrite_var_insert_f(
                Avlnode **tree,
                const char *name,
-               const char *value
+               const char *value,
+               int flags
 )
 {
        struct rewrite_var *var;
-       int rc;
+       int rc = 0;
 
        assert( tree != NULL );
        assert( name != NULL );
        assert( value != NULL );
        
+       var = rewrite_var_find( *tree, name );
+       if ( var != NULL ) {
+               if ( flags & REWRITE_VAR_UPDATE ) {
+                       (void)rewrite_var_replace( var, value, flags );
+                       goto cleanup;
+               }
+               rc = -1;
+               goto cleanup;
+       }
+
        var = calloc( sizeof( struct rewrite_var ), 1 );
        if ( var == NULL ) {
                return NULL;
        }
+
        memset( var, 0, sizeof( struct rewrite_var ) );
-       var->lv_name = strdup( name );
-       if ( var->lv_name == NULL ) {
-               rc = -1;
-               goto cleanup;
+
+       if ( flags & REWRITE_VAR_COPY_NAME ) {
+               var->lv_name = strdup( name );
+               if ( var->lv_name == NULL ) {
+                       rc = -1;
+                       goto cleanup;
+               }
+               var->lv_flags |= REWRITE_VAR_COPY_NAME;
+
+       } else {
+               var->lv_name = (char *)name;
        }
-       var->lv_value.bv_val = strdup( value );
-       if ( var->lv_value.bv_val == NULL ) {
-               rc = -1;
-               goto cleanup;
+
+       if ( flags & REWRITE_VAR_COPY_VALUE ) {
+               var->lv_value.bv_val = strdup( value );
+               if ( var->lv_value.bv_val == NULL ) {
+                       rc = -1;
+                       goto cleanup;
+               }
+               var->lv_flags |= REWRITE_VAR_COPY_VALUE;
+               
+       } else {
+               var->lv_value.bv_val = (char *)value;
        }
        var->lv_value.bv_len = strlen( value );
        rc = avl_insert( tree, ( caddr_t )var,
                        rewrite_var_cmp, rewrite_var_dup );
-       if ( rc != 0 ) { 
-               rc = -1;
-               goto cleanup;
-       }
 
 cleanup:;
-       if ( rc != 0 ) {
-               free( var->lv_name );
-               free( var->lv_value.bv_val );
-               free( var );
+       if ( rc != 0 && var ) {
+               avl_delete( tree, ( caddr_t )var, rewrite_var_cmp );
+               rewrite_var_free( var );
                var = NULL;
        }
 
@@ -138,11 +232,11 @@ cleanup:;
  * Sets/inserts a var
  */
 struct rewrite_var *
-rewrite_var_set(
+rewrite_var_set_f(
                Avlnode **tree,
                const char *name,
                const char *value,
-               int insert
+               int flags
 )
 {
        struct rewrite_var *var;
@@ -153,50 +247,19 @@ rewrite_var_set(
        
        var = rewrite_var_find( *tree, name );
        if ( var == NULL ) {
-               if ( insert ) {
-                       return rewrite_var_insert( tree, name, value );
+               if ( flags & REWRITE_VAR_INSERT ) {
+                       return rewrite_var_insert_f( tree, name, value, flags );
+
                } else {
                        return NULL;
                }
+
        } else {
                assert( var->lv_value.bv_val != NULL );
 
-               free( var->lv_value.bv_val );
-               var->lv_value.bv_val = strdup( value );
-               var->lv_value.bv_len = strlen( value );
+               (void)rewrite_var_replace( var, value, flags );
        }
 
        return var;
 }
 
-/*
- * Frees a var
- */
-static void 
-rewrite_var_free(
-               void *v_var
-)
-{
-       struct rewrite_var *var = v_var;
-       assert( var != NULL );
-
-       assert( var->lv_name != NULL );
-       assert( var->lv_value.bv_val != NULL );
-
-       free( var->lv_name );
-       free( var->lv_value.bv_val );
-       free( var );
-}
-
-/*
- * Deletes a var tree
- */
-int
-rewrite_var_delete(
-               Avlnode *tree
-)
-{
-       avl_free( tree, rewrite_var_free );
-       return REWRITE_SUCCESS;
-}
-