*
* The pair created by this function should fed to #cf_pair_parse for parsing.
*
- * @param[out] out Where to write the CONF_PAIR we created with the default value.
- * @param[in] cs to parent the CONF_PAIR from.
- * @param[in] name of the CONF_PAIR to create.
- * @param[in] type of conf item being parsed (determines default quoting).
- * @param[in] dflt value to assign the CONF_PAIR.
- * @param[in] dflt_quote surrounding the CONF_PAIR.
+ * @param[out] out Where to write the CONF_PAIR we created with the default value.
+ * @param[in] cs to parent the CONF_PAIR from.
+ * @param[in] rule to use to create the default.
* @return
* - 0 on success.
* - -1 on failure.
*/
-static int cf_pair_default(CONF_PAIR **out, CONF_SECTION *cs, char const *name,
- int type, char const *dflt, fr_token_t dflt_quote)
+static int cf_pair_default(CONF_PAIR **out, CONF_SECTION *cs, CONF_PARSER const *rule)
+
{
int lineno = 0;
char const *expanded;
CONF_PAIR *cp;
char buffer[8192];
+ int type;
+ fr_token_t dflt_quote = rule->quote;
- fr_assert(dflt);
+ fr_assert(rule->dflt || rule->dflt_func);
- type = FR_BASE_TYPE(type);
+ type = FR_BASE_TYPE(rule->type);
/*
- * Defaults may need their values expanding
+ * If no default quote was set, determine it from the type
*/
- expanded = cf_expand_variables("<internal>", lineno, cs, buffer, sizeof(buffer), dflt, -1, NULL);
- if (!expanded) {
- cf_log_err(cs, "Failed expanding variable %s", name);
- return -1;
+ if (dflt_quote == T_INVALID) {
+ if (fr_type_is_quoted(type)) {
+ dflt_quote = T_DOUBLE_QUOTED_STRING;
+ } else {
+ dflt_quote = T_BARE_WORD;
+ }
}
/*
- * If no default quote was set, determine it from the type
+ * Use the dynamic default function if set
*/
- if (dflt_quote == T_INVALID) {
- switch (type) {
- case FR_TYPE_STRING:
- dflt_quote = T_DOUBLE_QUOTED_STRING;
- break;
+ if (rule->dflt_func) {
+ if (rule->dflt_func(out, cs, dflt_quote, rule) < 0) {
+ cf_log_perr(cs, "Failed producing default for %s", rule->name);
+ return -1;
+ }
- case FR_TYPE_FILE_INPUT:
- case FR_TYPE_FILE_OUTPUT:
- dflt_quote = T_DOUBLE_QUOTED_STRING;
- break;
+ return 0;
+ }
- default:
- dflt_quote = T_BARE_WORD;
- break;
- }
+ expanded = cf_expand_variables("<internal>", lineno, cs, buffer, sizeof(buffer), rule->dflt, -1, NULL);
+ if (!expanded) {
+ cf_log_err(cs, "Failed expanding variable %s", rule->name);
+ return -1;
}
- cp = cf_pair_alloc(cs, name, expanded, T_OP_EQ, T_BARE_WORD, dflt_quote);
+ cp = cf_pair_alloc(cs, rule->name, expanded, T_OP_EQ, T_BARE_WORD, dflt_quote);
if (!cp) return -1;
- cp->parsed = true;
-
/*
* Set the ret to indicate we used a default value
*/
static int CC_HINT(nonnull(4,5)) cf_pair_parse_internal(TALLOC_CTX *ctx, void *out, void *base,
CONF_SECTION *cs, CONF_PARSER const *rule)
{
- bool multi, required, deprecated;
+ bool multi, required, deprecated, secret;
size_t count = 0;
CONF_PAIR *cp, *dflt_cp = NULL;
multi = (type & FR_TYPE_MULTI);
required = (type & FR_TYPE_REQUIRED);
deprecated = (type & FR_TYPE_DEPRECATED);
+ secret = (type & FR_TYPE_SECRET);
/*
* If the item is multi-valued we allocate an array
return 1;
}
- if (cf_pair_default(&dflt_cp, cs, rule->name, type, dflt, dflt_quote) < 0) return -1;
+ if (cf_pair_default(&dflt_cp, cs, rule) < 0) return -1;
cp = dflt_cp;
count = 1; /* Need one to hold the default */
} else {
return 1;
}
- if (cf_pair_default(&dflt_cp, cs, rule->name, type, dflt, dflt_quote) < 0) return -1;
+ if (cf_pair_default(&dflt_cp, cs, rule) < 0) return -1;
cp = dflt_cp;
} else if (cp->parsed) {
cp->parsed = true;
if (rule->func) {
- cf_log_debug(cs, "%.*s%s = %s", PAIR_SPACE(cs), parse_spaces, cp->attr, cp->value);
+ cf_pair_debug(cs, cp, type, secret);
cp->printed = true;
func = rule->func;
}
* - 0 on success.
* - -1 on failure.
*/
-typedef int (* cf_parse_t)(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, CONF_PARSER const *rule);
+typedef int (*cf_parse_t)(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, CONF_PARSER const *rule);
+
+/** Callback for producing dynamic defaults from 3rd party libraries
+ *
+ * @param[out] out Where to write default conf pair.
+ * @param[in] cs to allocate pair in.
+ * @param[in] quote to use when allocing the pair. Provided as a convenience.
+ * @param[in] rule to produce default for.
+ * @return
+ * - 0 on success.
+ * - -1 on failure.
+ */
+typedef int (*cf_dflt_t)(CONF_PAIR **out, CONF_SECTION *cs, fr_token_t quote, CONF_PARSER const *rule);
/** Defines a #CONF_PAIR to C data type mapping
*
};
union {
- char const *dflt; //!< Default as it would appear in radiusd.conf.
+ struct {
+ char const *dflt; //!< Default as it would appear in radiusd.conf.
+
+ cf_dflt_t dflt_func; //!< Function to produce dynamic defaults.
+ };
struct {
- struct CONF_PARSER const *subcs; //!< When type is set to #FR_TYPE_SUBSECTION, should
+ struct CONF_PARSER const *subcs;//!< When type is set to #FR_TYPE_SUBSECTION, should
//!< be a pointer to the start of another array of
//!< #CONF_PARSER structs, forming the subsection.
size_t subcs_size; //!< If non-zero, allocate structs of this size to hold