From: Alan T. DeKok Date: Mon, 7 May 2018 12:17:54 +0000 (-0400) Subject: added ON_READ for parsing callback functions when reading files X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a2cc3e3be6b6c2aeef2a9626fe0fb936320a3b38;p=thirdparty%2Ffreeradius-server.git added ON_READ for parsing callback functions when reading files --- diff --git a/src/include/cf_parse.h b/src/include/cf_parse.h index c6cad06cc7c..2e2e36ba97c 100644 --- a/src/include/cf_parse.h +++ b/src/include/cf_parse.h @@ -311,6 +311,7 @@ _Generic((_ct), \ //!< left as the default to is_set_offset //!< or is_set_ptr. #define FR_TYPE_OK_MISSING (1 << 22) //!< OK if it's missing +#define FR_TYPE_ON_READ (1 << 23) //!< run the parse callback during the file read phase #define FR_BASE_TYPE(_t) (0xff & (_t)) /* @} **/ diff --git a/src/main/cf_parse.c b/src/main/cf_parse.c index eba5fbab85a..8cdf29432bd 100644 --- a/src/main/cf_parse.c +++ b/src/main/cf_parse.c @@ -130,6 +130,7 @@ static int CC_HINT(nonnull(2, 3, 4)) cf_pair_parse_value(TALLOC_CTX *ctx, void * rad_assert(cp); rad_assert(!(type & FR_TYPE_ATTRIBUTE) || tmpl); /* Attribute flag only valid for templates */ + rad_assert((type & FR_TYPE_ON_READ) == 0); if (required) cant_be_empty = true; /* May want to review this in the future... */ @@ -1104,6 +1105,11 @@ int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs) rule = cf_data_value(rule_cd); + /* + * Ignore ON_READ parse rules + */ + if ((rule->type & FR_TYPE_ON_READ) != 0) continue; + /* * Pre-allocate the config structure to hold default values */ @@ -1428,7 +1434,7 @@ int _cf_section_rule_push(CONF_SECTION *cs, CONF_PARSER const *rule, char const */ if (!_cf_data_add_static(CF_TO_ITEM(cs), rule, "CONF_PARSER", rule->name, filename, lineno)) { CONF_DATA const *cd; - CONF_PARSER const *old; + CONF_PARSER *old; cd = cf_data_find(CF_TO_ITEM(cs), CONF_PARSER, rule->name); old = cf_data_value(cd); @@ -1441,6 +1447,22 @@ int _cf_section_rule_push(CONF_SECTION *cs, CONF_PARSER const *rule, char const return 0; } + /* + * Remove any ON_READ callbacks, and add the new + * rule in its place. + */ + if ((old->type & FR_TYPE_ON_READ) != 0) { + (void) cf_remove(CF_TO_ITEM(cs), CF_TO_ITEM(cd)); + talloc_const_free(cd); + + if (!_cf_data_add_static(CF_TO_ITEM(cs), rule, "CONF_PARSER", rule->name, filename, lineno)) { + cf_log_err(cs, "Failed adding rule '%s'", rule->name); + cf_debug(cs); + return -1; + } + return 0; + } + /* * If we have a duplicate sub-section, just * recurse and add the new sub-rules to the diff --git a/src/main/cf_priv.h b/src/main/cf_priv.h index d0194a3f66d..c6956e5a114 100644 --- a/src/main/cf_priv.h +++ b/src/main/cf_priv.h @@ -144,6 +144,8 @@ typedef struct cf_file_t { struct stat buf; } cf_file_t; +CONF_ITEM *cf_remove(CONF_ITEM *parent, CONF_ITEM *child); + #ifdef __cplusplus } #endif diff --git a/src/main/cf_util.c b/src/main/cf_util.c index e228e356198..b7e4f74168b 100644 --- a/src/main/cf_util.c +++ b/src/main/cf_util.c @@ -395,7 +395,7 @@ void _cf_item_add(CONF_ITEM *parent, CONF_ITEM *child) * - The item removed. * - NULL if the item wasn't set. */ -static CONF_ITEM *cf_remove(CONF_ITEM *parent, CONF_ITEM *child) +CONF_ITEM *cf_remove(CONF_ITEM *parent, CONF_ITEM *child) { CONF_ITEM *found; bool in_ident1, in_ident2;