Skip to content

Commit

Permalink
Added cf_section_parse_pass2() for pass2 checks of config items
Browse files Browse the repository at this point in the history
and PW_TYPE_XLAT, too.

Modules can now tell the server core that config items will
be dynamically expanded.  For now, this means that the server
can parse them in pass2, and complain at compile time about
syntax errors.

We will later expand this to allowing CONF_PAIRs to have compiled
xlat's, which should be faster at run time
  • Loading branch information
alandekok committed Sep 22, 2014
1 parent 6ab6bd4 commit 1ec41ca
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/include/conffile.h
Expand Up @@ -119,6 +119,8 @@ typedef struct timeval _timeval_t;
#define PW_TYPE_FILE_INPUT ((1 << 14) | PW_TYPE_STRING)
#define PW_TYPE_FILE_OUTPUT ((1 << 15) | PW_TYPE_STRING)

#define PW_TYPE_XLAT (1 << 16) //!< string will be dynamically expanded

#define FR_INTEGER_COND_CHECK(_name, _var, _cond, _new)\
do {\
if (!(_cond)) {\
Expand Down Expand Up @@ -153,6 +155,7 @@ void cf_section_add(CONF_SECTION *parent, CONF_SECTION *cs);
int cf_pair_replace(CONF_SECTION *cs, CONF_PAIR *cp, char const *value);
int cf_item_parse(CONF_SECTION *cs, char const *name, int type, void *data, char const *dflt);
int cf_section_parse(CONF_SECTION *, void *base, CONF_PARSER const *variables);
int cf_section_parse_pass2(CONF_SECTION *, void *base, CONF_PARSER const *variables);
const CONF_PARSER *cf_section_parse_table(CONF_SECTION *cs);
CONF_SECTION *cf_file_read(char const *file);
void cf_file_free(CONF_SECTION *cs);
Expand Down
76 changes: 76 additions & 0 deletions src/main/conffile.c
Expand Up @@ -1440,6 +1440,82 @@ int cf_section_parse(CONF_SECTION *cs, void *base,
}


/*
* Check XLAT things in pass 2. But don't cache the xlat stuff anywhere.
*/
int cf_section_parse_pass2(CONF_SECTION *cs, UNUSED void *base,
CONF_PARSER const *variables)
{
int i;
ssize_t slen;
char const *error;
char *value = NULL;
xlat_exp_t *xlat;

/*
* Handle the known configuration parameters.
*/
for (i = 0; variables[i].name != NULL; i++) {
CONF_PAIR *cp;

/*
* Handle subsections specially
*/
if (variables[i].type == PW_TYPE_SUBSECTION) {
CONF_SECTION *subcs;
subcs = cf_section_sub_find(cs, variables[i].name);

if (cf_section_parse_pass2(subcs, base,
(CONF_PARSER const *) variables[i].dflt) < 0) {
goto error;
}
continue;
} /* else it's a CONF_PAIR */

/*
* Ignore everything but xlat expansions.
*/
if ((variables[i].type & PW_TYPE_XLAT) == 0) continue;

cp = cf_pair_find(cs, variables[i].name);
if (!cp || !cp->value) continue;

if ((cp->value_type != T_DOUBLE_QUOTED_STRING) &&
(cp->value_type != T_BARE_WORD)) continue;

value = talloc_strdup(cs, cp->value); /* modified by xlat_tokenize */
xlat = NULL;

slen = xlat_tokenize(cs, value, &xlat, &error);
if (slen < 0) {
char const *prefix = "";
char const *p = cp->value;
size_t indent = -slen;

if (indent >= sizeof(parse_spaces)) {
size_t offset = (indent - (sizeof(parse_spaces) - 1)) + (sizeof(parse_spaces) * 0.75);
indent -= offset;
p += offset;

prefix = "...";
}

cf_log_err(&cp->item, "Failed parsing expanded string:");
cf_log_err(&cp->item, "%s%s", prefix, p);
cf_log_err(&cp->item, "%s%.*s^ %s", prefix, (int) indent, parse_spaces, error);
error:
talloc_free(value);
talloc_free(xlat);
return -1;
}

talloc_free(value);
talloc_free(xlat);
} /* for all variables in the configuration section */

return 0;
}

static CONF_SECTION *cf_template_copy(CONF_SECTION *parent, CONF_SECTION const *template)
{
CONF_ITEM *ci;
Expand Down

0 comments on commit 1ec41ca

Please sign in to comment.