Commit e9314574 authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

allow memory ownership specification when using (session- wide) variables

parent 43f5b503
......@@ -74,6 +74,30 @@
#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
*/
......
......@@ -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
*/
......
......@@ -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 );
......
......@@ -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;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment