#define REWRITE_REGEXEC_OK 0x0000
#define REWRITE_REGEXEC_ERR 0x0001
#define REWRITE_REGEXEC_STOP 0x0002
-#define REWRITE_REGEXEC_UNWILLING 0x0004
+#define REWRITE_REGEXEC_UNWILLING 0x0003
+#define REWRITE_REGEXEC_USER 0x0004 /* and above ... */
/*
* Rewrite variable flags
* referenced string is available for
* the entire life scope of the variable.
*/
+#define REWRITE_VAR_NONE 0x0000
#define REWRITE_VAR_INSERT 0x0001
#define REWRITE_VAR_UPDATE 0x0002
#define REWRITE_VAR_COPY_NAME 0x0004
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:
/* ... */
* This will instruct the server to return
* an `unwilling to perform' error message
*/
- case REWRITE_REGEXEC_UNWILLING:
+ 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 */
#define REWRITE_FLAG_STOP '@'
#define REWRITE_FLAG_UNWILLING '#'
#define REWRITE_FLAG_GOTO 'G' /* requires an arg */
+#define REWRITE_FLAG_USER 'U' /* requires an arg */
#define REWRITE_FLAG_IGNORE_ERR 'I'
/*
#define REWRITE_ACTION_UNWILLING 0x0002
#define REWRITE_ACTION_GOTO 0x0003
#define REWRITE_ACTION_IGNORE_ERR 0x0004
+#define REWRITE_ACTION_USER 0x0005
int la_type;
void *la_args;
};
rewriteContext != NULL;
rewriteContext = sep,
sep ? sep = strchr( rewriteContext, ',' ) : NULL ) {
+ char *errmsg = "";
+
if ( sep != NULL ) {
sep[ 0 ] = '\0';
sep++;
rc = rewrite_session( info, rewriteContext, string,
cookie, &result );
- fprintf( stdout, "%s -> %s\n", string,
- ( result ? result : "unwilling to perform" ) );
+ switch ( rc ) {
+ case REWRITE_REGEXEC_OK:
+ errmsg = "ok";
+ break;
+
+ case REWRITE_REGEXEC_ERR:
+ errmsg = "error";
+ break;
+
+ case REWRITE_REGEXEC_STOP:
+ errmsg = "stop";
+ break;
+
+ case REWRITE_REGEXEC_UNWILLING:
+ errmsg = "unwilling to perform";
+ break;
+
+ default:
+ if (rc >= REWRITE_REGEXEC_USER) {
+ errmsg = "user-defined";
+ } else {
+ errmsg = "unknown";
+ }
+ break;
+ }
+
+ fprintf( stdout, "%s -> %s [%d:%s]\n", string,
+ ( result ? result : "(null)" ),
+ rc, errmsg );
if ( result == NULL ) {
break;
}
*/
static int
append_action(
- struct rewrite_action *base,
+ struct rewrite_action **pbase,
struct rewrite_action *action
)
{
- struct rewrite_action *a;
+ struct rewrite_action **pa;
- assert( base != NULL );
+ assert( pbase != NULL );
assert( action != NULL );
- for ( a = base; a->la_next != NULL; a = a->la_next );
- a->la_next = action;
+ for ( pa = pbase; *pa != NULL; pa = &(*pa)->la_next );
+ *pa = action;
return REWRITE_SUCCESS;
}
/* do something */
switch ( action->la_type ) {
- case REWRITE_FLAG_GOTO: {
+ case REWRITE_FLAG_GOTO:
+ case REWRITE_FLAG_USER: {
int *pi = (int *)action->la_args;
if ( pi ) {
action->la_type = REWRITE_ACTION_UNWILLING;
break;
- case REWRITE_FLAG_GOTO: { /* 'G' */
+ case REWRITE_FLAG_GOTO: /* 'G' */
/*
* After applying rule, jump N rules
*/
+ case REWRITE_FLAG_USER: { /* 'U' */
+ /*
+ * After applying rule, return user-defined
+ * error code
+ */
char buf[16], *q;
size_t l;
int *d;
return REWRITE_ERR;
}
- l = q - p + 2;
+ l = q - p + 1;
if ( l >= sizeof( buf ) ) {
/* XXX Need to free stuff */
return REWRITE_ERR;
/* cleanup ... */
return REWRITE_ERR;
}
- action->la_type = REWRITE_ACTION_GOTO;
+ switch ( p[ 0 ] ) {
+ case REWRITE_FLAG_GOTO:
+ action->la_type = REWRITE_ACTION_GOTO;
+ break;
+
+ case REWRITE_FLAG_USER:
+ action->la_type = REWRITE_ACTION_USER;
+ break;
+
+ default:
+ assert(0);
+ }
+
action->la_args = (void *)d;
p = q; /* p is incremented by the for ... */
* Stupid way to append to a list ...
*/
if ( action != NULL ) {
- if ( first_action == NULL ) {
- first_action = action;
- } else {
- append_action( first_action, action );
- }
+ append_action( &first_action, action );
action = NULL;
}
}
struct rewrite_subst *
rewrite_subst_compile(
struct rewrite_info *info,
- const char *result
+ const char *str
)
{
size_t subs_len;
struct rewrite_subst *s = NULL;
- const char *begin, *p;
+ char *result, *begin, *p;
int nsub = 0, l;
assert( info != NULL );
- assert( result != NULL );
+ assert( str != NULL );
+
+ result = strdup( str );
+ if ( result == NULL ) {
+ return NULL;
+ }
/*
* Take care of substitution string
tmps = ( struct berval * )realloc( subs,
sizeof( struct berval )*( nsub + 1 ) );
if ( tmps == NULL ) {
- /* FIXME: cleanup */
- return NULL;
+ goto cleanup;
}
subs = tmps;
subs[ nsub ].bv_len = l;
subs[ nsub ].bv_val = malloc( l + 1 );
if ( subs[ nsub ].bv_val == NULL ) {
- return NULL;
+ goto cleanup;
}
AC_MEMCPY( subs[ nsub ].bv_val, begin, l );
subs[ nsub ].bv_val[ l ] = '\0';
tmpsm = ( struct rewrite_submatch * )realloc( submatch,
sizeof( struct rewrite_submatch )*( nsub + 1 ) );
if ( tmpsm == NULL ) {
- /* cleanup */
- return NULL;
+ goto cleanup;
}
submatch = tmpsm;
submatch[ nsub ].ls_submatch = d;
REWRITE_SUBMATCH_XMAP;
map = rewrite_xmap_parse( info,
- p + 3, &begin );
+ p + 3, (const char **)&begin );
if ( map == NULL ) {
- /* cleanup */
- return NULL;
+ goto cleanup;
}
submatch[ nsub ].ls_map = map;
p = begin - 1;
struct rewrite_map *map;
struct rewrite_submatch *tmpsm;
- map = rewrite_map_parse( info, p + 2, &begin );
+ map = rewrite_map_parse( info, p + 2,
+ (const char **)&begin );
if ( map == NULL ) {
- /* cleanup */
- return NULL;
+ goto cleanup;
}
p = begin - 1;
tmpsm = ( struct rewrite_submatch * )realloc( submatch,
sizeof( struct rewrite_submatch )*( nsub + 1 ) );
if ( tmpsm == NULL ) {
- /* cleanup */
- return NULL;
+ goto cleanup;
}
submatch = tmpsm;
submatch[ nsub ].ls_type =
continue;
} else {
- return NULL;
+ goto cleanup;
}
nsub++;
* XXX need to free the value subst stuff!
*/
free( subs );
- return NULL;
+ goto cleanup;
}
subs = tmps;
l = p - begin;
s = calloc( sizeof( struct rewrite_subst ), 1 );
if ( s == NULL ) {
- /* cleanup */
- return NULL;
+ goto cleanup;
}
s->lt_subs_len = subs_len;
s->lt_num_submatch = nsub;
s->lt_submatch = submatch;
+cleanup:;
+ free( result );
+
return s;
}
}
if ( rc != REWRITE_SUCCESS ) {
- rc = REWRITE_REGEXEC_ERR;
goto cleanup;
}
break;
rc = REWRITE_ERR;
break;
}
-
+
if ( rc != REWRITE_SUCCESS ) {
rc = REWRITE_REGEXEC_ERR;
}