Skip to content

Commit

Permalink
Expose fr_cond_t, but don't use it (yet)
Browse files Browse the repository at this point in the history
  • Loading branch information
alandekok committed Apr 19, 2013
1 parent 438edec commit a76cadc
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 75 deletions.
34 changes: 33 additions & 1 deletion src/include/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,39 @@ RCSIDH(parser_h, "$Id$");
extern "C" {
#endif

ssize_t fr_condition_tokenize(const char *start, const char **error);
typedef struct fr_cond_t fr_cond_t;

typedef enum cond_op_t {
COND_NONE = 0,
COND_TRUE,
COND_NOT = '!',
COND_AND = '&',
COND_OR = '|'
} cond_op_t;


/*
* Allow for the following structures:
*
* FOO no OP, RHS is NULL
* FOO OP BAR
* (COND) no LHS/RHS, child is COND, child OP is TRUE
* (!(COND)) no LHS/RHS, child is COND, child OP is NOT
* (COND1 OP COND2) no LHS/RHS, next is COND2, next OP is OP
*/
struct fr_cond_t {
char *lhs;
char *rhs;
FR_TOKEN op;
int regex_i;

cond_op_t next_op;
fr_cond_t *next;
cond_op_t child_op;
fr_cond_t *child;
};

ssize_t fr_condition_tokenize(TALLOC_CTX *ctx, const char *start, fr_cond_t **head, const char **error);

/*
* In xlat.c for now
Expand Down
19 changes: 15 additions & 4 deletions src/main/conffile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,7 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
int spaces = FALSE;
char *cbuf = buf;
size_t len;
fr_cond_t *cond = NULL;

this = current; /* add items here */

Expand Down Expand Up @@ -1579,7 +1580,7 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
if (!server) goto invalid_location;
}

slen = fr_condition_tokenize(ptr, &error);
slen = fr_condition_tokenize(this, ptr, &cond, &error);
if (p) *p = '{';

if (slen < 0) {
Expand All @@ -1603,7 +1604,8 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
}

if ((size_t) slen >= (sizeof(buf2) - 1)) {
ERROR("%s[%d]: Condition is too large after \"%s\"",
talloc_free(cond);
DEBUGE("%s[%d]: Condition is too large after \"%s\"",
filename, *lineno, buf1);
return -1;
}
Expand All @@ -1614,7 +1616,8 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
t2 = T_BARE_WORD;

if (gettoken(&ptr, buf3, sizeof(buf3)) != T_LCBRACE) {
ERROR("%s[%d]: Expected '{'",
talloc_free(cond);
DEBUGE("%s[%d]: Expected '{'",
filename, *lineno);
return -1;
}
Expand Down Expand Up @@ -1711,7 +1714,10 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,

case T_LCBRACE:
section_alloc:
if (seen_too_much(filename, *lineno, ptr)) return -1;
if (seen_too_much(filename, *lineno, ptr)) {
if (cond) talloc_free(cond);
return -1;
}

css = cf_section_alloc(this, buf1,
t2 == T_LCBRACE ? NULL : buf2);
Expand All @@ -1724,6 +1730,11 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
css->item.filename = filename;
css->item.lineno = *lineno;

if (cond) {
cf_data_add_internal(css, "if", cond, NULL, FALSE);
cond = NULL; /* eaten by the above line */
}

/*
* The current section is now the child section.
*/
Expand Down
36 changes: 20 additions & 16 deletions src/main/modcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ RCSID("$Id$")
#include <freeradius-devel/radiusd.h>
#include <freeradius-devel/modpriv.h>
#include <freeradius-devel/modcall.h>
#include <freeradius-devel/parser.h>
#include <freeradius-devel/rad_assert.h>


Expand Down Expand Up @@ -67,7 +68,8 @@ typedef struct {
int grouptype; /* after mc */
modcallable *children;
CONF_SECTION *cs;
value_pair_map_t *map;
value_pair_map_t *map; /* update */
const fr_cond_t *cond; /* if/elsif */
} modgroup;

typedef struct {
Expand Down Expand Up @@ -458,6 +460,10 @@ int modcall(int component, modcallable *c, REQUEST *request)
if ((child->type == MOD_IF) || (child->type == MOD_ELSIF)) {
int condition = TRUE;
const char *p = child->name;
modgroup *g;

g = mod_callabletogroup(child);
rad_assert(g->cond != NULL);

RDEBUG2("%.*s? %s %s",
stack.pointer + 1, modcall_spaces,
Expand Down Expand Up @@ -1683,9 +1689,6 @@ static modcallable *do_compile_modsingle(modcallable *parent,
int grouptype,
const char **modname)
{
#ifdef WITH_UNLANG
int result;
#endif
const char *modrefname;
modsingle *single;
modcallable *csingle;
Expand Down Expand Up @@ -1759,6 +1762,8 @@ static modcallable *do_compile_modsingle(modcallable *parent,

#ifdef WITH_UNLANG
} else if (strcmp(modrefname, "if") == 0) {
modgroup *g;

if (!cf_section_name2(cs)) {
cf_log_err(ci, "'if' without condition.");
return NULL;
Expand All @@ -1770,17 +1775,17 @@ static modcallable *do_compile_modsingle(modcallable *parent,
grouptype);
if (!csingle) return NULL;
csingle->type = MOD_IF;

if (!radius_evaluate_condition(NULL, 0, 0, modname,
FALSE, &result)) {
modcallable_free(&csingle);
return NULL;
}
*modname = name2;

g = mod_callabletogroup(csingle);
g->cond = cf_data_find(g->cs, "if");
rad_assert(g->cond != NULL);

return csingle;

} else if (strcmp(modrefname, "elsif") == 0) {
modgroup *g;

if (parent &&
((parent->type == MOD_LOAD_BALANCE) ||
(parent->type == MOD_REDUNDANT_LOAD_BALANCE))) {
Expand All @@ -1799,14 +1804,12 @@ static modcallable *do_compile_modsingle(modcallable *parent,
grouptype);
if (!csingle) return NULL;
csingle->type = MOD_ELSIF;

if (!radius_evaluate_condition(NULL, 0, 0, modname,
FALSE, &result)) {
modcallable_free(&csingle);
return NULL;
}
*modname = name2;

g = mod_callabletogroup(csingle);
g->cond = cf_data_find(g->cs, "if");
rad_assert(g->cond != NULL);

return csingle;

} else if (strcmp(modrefname, "else") == 0) {
Expand Down Expand Up @@ -2176,6 +2179,7 @@ static modcallable *do_compile_modgroup(modcallable *parent,
memset(g, 0, sizeof(*g));
g->grouptype = grouptype;
g->children = NULL;
g->cs = cs;

c = mod_grouptocallable(g);
c->parent = parent;
Expand Down
70 changes: 17 additions & 53 deletions src/main/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,40 +43,8 @@ RCSID("$Id$")
#endif
#endif

typedef enum cond_op_t {
COND_NONE = 0,
COND_TRUE,
COND_NOT = '!',
COND_AND = '&',
COND_OR = '|'
} cond_op_t;


typedef struct cond_t cond_t;

/*
* Allow for the following structures:
*
* FOO no OP, RHS is NULL
* FOO OP BAR
* (COND) no LHS/RHS, child is COND, child OP is TRUE
* (!(COND)) no LHS/RHS, child is COND, child OP is NOT
* (COND1 OP COND2) no LHS/RHS, next is COND2, next OP is OP
*/
struct cond_t {
char *lhs;
char *rhs;
FR_TOKEN op;
int regex_i;

cond_op_t next_op;
cond_t *next;
cond_op_t child_op;
cond_t *child;
};

DIAG_OFF(unused-function)
static void cond_debug(const cond_t *c)
W_UNUSEDDEC_OFF
static void cond_debug(const fr_cond_t *c)
{

next:
Expand Down Expand Up @@ -233,15 +201,15 @@ static ssize_t condition_tokenize_word(TALLOC_CTX *ctx, const char *start, char
* @param[out] error the parse error (if any)
* @return length of the string skipped, or when negative, the offset to the offending error
*/
static ssize_t condition_tokenize(TALLOC_CTX *ctx, const char *start, int brace, cond_t **pcond, const char **error)
static ssize_t condition_tokenize(TALLOC_CTX *ctx, const char *start, int brace, fr_cond_t **pcond, const char **error)
{
ssize_t slen;
const char *p = start;
cond_t *c;
fr_cond_t *c;

COND_DEBUG("START %s", p);

c = talloc_zero(ctx, cond_t);
c = talloc_zero(ctx, fr_cond_t);

rad_assert(c != NULL);

Expand Down Expand Up @@ -377,6 +345,14 @@ static ssize_t condition_tokenize(TALLOC_CTX *ctx, const char *start, int brace,
p += 2;

} else if (p[1] == '*') {
/*
* FOO !* BAR
*
* is really !(FOO)
*
* FIXME: we should
* really re-write it...
*/
c->op = T_OP_CMP_FALSE;
p += 2;

Expand Down Expand Up @@ -553,25 +529,13 @@ static ssize_t condition_tokenize(TALLOC_CTX *ctx, const char *start, int brace,

/** Tokenize a conditional check
*
* @param[in] ctx for talloc
* @param[in] start the start of the string to process. Should be "(..."
* @param[out] head the parsed condition structure
* @param[out] error the parse error (if any)
* @return length of the string skipped, or when negative, the offset to the offending error
*/
ssize_t fr_condition_tokenize(const char *start, const char **error)
ssize_t fr_condition_tokenize(TALLOC_CTX *ctx, const char *start, fr_cond_t **head, const char **error)
{
ssize_t slen;
cond_t *c = NULL;

slen = condition_tokenize(NULL, start, FALSE, &c, error);
if (slen <= 0) return slen;

if (!c) {
COND_DEBUG("RETURN %d", __LINE__);
*error = "Empty condition is invalid";
return -1;
}

talloc_free(c);

return slen;
return condition_tokenize(ctx, start, FALSE, head, error);
}
5 changes: 4 additions & 1 deletion src/main/radattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,13 +542,16 @@ static void parse_condition(const char *input, char *output, size_t outlen)
{
ssize_t slen;
const char *error = NULL;
fr_cond_t *cond;

slen = fr_condition_tokenize(input, &error);
slen = fr_condition_tokenize(NULL, input, &cond, &error);
if (slen <= 0) {
snprintf(output, outlen, "ERROR offset %d '%s'", (int) -slen, error);
return;
}

talloc_free(cond);

input += slen;
if (*input != '\0') {
snprintf(output, outlen, "ERROR offset %d 'Too much text'", (int) slen);
Expand Down

0 comments on commit a76cadc

Please sign in to comment.