From aeeff8cfa2d9fa6a939f0c25f43e866a483f5c4c Mon Sep 17 00:00:00 2001 From: Terry Wilson Date: Thu, 7 Jun 2012 15:43:37 +0000 Subject: [PATCH] Add default handler documentation and standardize acl handler Added documentation describing what flags and arguments to pass to aco_option_register for default option types. Also changed the ACL handler to use the flags parameter to differentiate between "permit" and "deny" instead of adding an additional vararg parameter. Review: https://reviewboard.asterisk.org/r/1969/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@368663 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/config_options.h | 175 +++++++++++++++++++++++++++--- main/config_options.c | 40 ++++++- tests/test_config.c | 4 +- 3 files changed, 197 insertions(+), 22 deletions(-) diff --git a/include/asterisk/config_options.h b/include/asterisk/config_options.h index a1b7f37140..029434ac8a 100644 --- a/include/asterisk/config_options.h +++ b/include/asterisk/config_options.h @@ -206,26 +206,171 @@ int aco_info_init(struct aco_info *info); */ void aco_info_destroy(struct aco_info *info); -/*! \brief The option types with default handlers +/*! \brief The option types * * \note aco_option_register takes an option type which is used * to look up the handler for that type. Each non-custom type requires * field names for specific types in the struct being configured. Each - * option below is commented with the field types, *in the order - * they must be passed* to aco_option_register. The fields - * are located in the args array in the ast_config_option passed to - * the default handler function. - * */ + * option below is commented with the field types, additional arguments + * and example usage with aco_option_register + */ enum aco_option_type { - OPT_ACL_T, /*!< fields: struct ast_ha * */ - OPT_BOOL_T, /*!< fields: unsigned int */ - OPT_CODEC_T, /*!< fields: struct ast_codec pref, struct ast_format_cap * */ - OPT_CUSTOM_T, /*!< fields: none */ - OPT_DOUBLE_T, /*!< fields: double */ - OPT_INT_T, /*!< fields: int */ - OPT_SOCKADDR_T, /*!< fields: struct ast_sockaddr */ - OPT_STRINGFIELD_T, /*!< fields: ast_string_field */ - OPT_UINT_T, /*!< fields: unsigned int */ + /*! \brief Type for default option handler for ACLs + * \note aco_option_register flags: + * non-zero : "permit" + * 0 : "deny" + * aco_option_register varargs: + * FLDSET macro with the field of type struct ast_ha *. + * + * Example: + * {code} + * struct test_item { + * struct ast_ha *ha; + * }; + * aco_option_register(&cfg_info, "permit", ACO_EXACT, my_types, NULL, OPT_ACL_T, 1, FLDSET(struct test_item, ha)); + * aco_option_register(&cfg_info, "deny", ACO_EXACT, my_types, NULL, OPT_ACL_T, 0, FLDSET(struct test_item, ha)); + * {code} + */ + OPT_ACL_T, + + /*! \brief Type for default option handler for bools (ast_true/ast_false) + * \note aco_option_register flags: + * non-zero : process via ast_true + * 0 : process via ast_false + * aco_option_register varargs: + * FLDSET macro with the field of type int. It is important to note that the field + * cannot be a bitfield. If bitfields are required, they must be set via a custom handler. + * + * Example: + * {code} + * struct test_item { + * int enabled; + * }; + aco_option_register(&cfg_info, "enabled", ACO_EXACT, my_types, "no", OPT_BOOL_T, 1, FLDSET(struct test_item, enabled)); + * {endcode} + */ + OPT_BOOL_T, + + /*! \brief Type for default option handler for codec preferences/capabilities + * \note aco_option_register flags: + * non-zero : This is an "allow" style option + * 0 : This is a "disallow" style option + * aco_option_register varargs: + * FLDSET macro with fields representing a struct ast_codec_pref and a struct ast_format_cap * + * + * Example: + * {code} + * struct test_item { + * struct ast_codec_pref pref; + * struct ast_format cap *cap; + * }; + * aco_option_register(&cfg_info, "allow", ACO_EXACT, my_types, "ulaw,alaw", OPT_CODEC_T, 1, FLDSET(struct test_item, pref, cap)); + * aco_option_register(&cfg_info, "disallow", ACO_EXACT, my_types, "all", OPT_CODEC_T, 0, FLDSET(struct test_item, pref, cap)); + */ + OPT_CODEC_T, + + /*! \brief Type for a custom (user-defined) option handler */ + OPT_CUSTOM_T, + + /*! \brief Type for default option handler for doubles + * + * \note aco_option_register flags: + * See flags available for use with the PARSE_DOUBLE type for the ast_parse_arg function + * aco_option_register varargs: + * FLDSET macro with the field of type double + * + * Example: + * struct test_item { + * double dub; + * }; + * {code} + * aco_option_register(&cfg_info, "doubleopt", ACO_EXACT, my_types, "3", OPT_DOUBLE_T, FLDSET(struct test_item, dub)); + * {endcode} + */ + OPT_DOUBLE_T, + + /*! \brief Type for default option handler for signed integers + * + * \note aco_option_register flags: + * See flags available for use with the PARSE_INT32 type for the ast_parse_arg function + * aco_option_register varargs: + * FLDSET macro with the field of type int32_t + * The remaining varargs for should be arguments compatible with the varargs for the + * ast_parse_arg function with the PARSE_INT32 type and the flags passed in the + * aco_option_register flags parameter. + * + * \note In most situations, it is preferable to not pass the PARSE_DEFAULT flag. If a config + * contains an invalid value, it is better to let the config loading fail with warnings so that + * the problem is fixed by the administrator. + * + * Example: + * struct test_item { + * int32_t intopt; + * }; + * {code} + * aco_option_register(&cfg_info, "intopt", ACO_EXACT, my_types, "3", OPT_INT_T, PARSE_IN_RANGE, FLDSET(struct test_item, intopt), -10, 10); + * {endcode} + */ + OPT_INT_T, + + /*! \brief Type for default handler for ast_sockaddrs + * + * \note aco_option_register flags: + * See flags available for use with the PARSE_ADDR type for the ast_parse_arg function + * aco_option_register varargs: + * FLDSET macro with the field being of type struct ast_sockaddr. + * + * Example: + * {code} + * struct test_item { + * struct ast_sockaddr addr; + * }; + * aco_option_register(&cfg_info, "sockaddropt", ACO_EXACT, my_types, "0.0.0.0:1234", OPT_SOCKADDR_T, 0, FLDSET(struct test_item, addr)); + * {endcode} + */ + OPT_SOCKADDR_T, + + /*! \brief Type for default option handler for stringfields + * \note aco_option_register flags: + * none + * aco_option_register varargs: + * STRFLDSET macro with the field being the field created by AST_STRING_FIELD + * + * Example: + * {code} + * struct test_item { + * AST_DECLARE_STRING_FIELDS( + * AST_STRING_FIELD(thing); + * ); + * }; + * aco_option_register(&cfg_info, "thing", ACO_EXACT, my_types, NULL, OPT_STR_T, 0, STRFLDSET(struct test_item, thing)); + * {endcode} + */ + OPT_STRINGFIELD_T, + + /*! \brief Type for default option handler for unsigned integers + * + * \note aco_option_register flags: + * See flags available for use with the PARSE_UINT32 type for the ast_parse_arg function + * aco_option_register varargs: + * FLDSET macro with the field of type uint32_t + * The remaining varargs for should be arguments compatible with the varargs for the + * ast_parse_arg function with the PARSE_UINT32 type and the flags passed in the + * aco_option_register flags parameter. + * + * \note In most situations, it is preferable to not pass the PARSE_DEFAULT flag. If a config + * contains an invalid value, it is better to let the config loading fail with warnings so that + * the problem is fixed by the administrator. + * + * Example: + * struct test_item { + * int32_t intopt; + * }; + * {code} + * aco_option_register(&cfg_info, "uintopt", ACO_EXACT, my_types, "3", OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct test_item, uintopt), 1, 10); + * {endcode} + */ + OPT_UINT_T, }; /*! \brief A callback function for handling a particular option diff --git a/main/config_options.c b/main/config_options.c index 091c7f4c00..de89d8ddb0 100644 --- a/main/config_options.c +++ b/main/config_options.c @@ -596,7 +596,12 @@ int aco_set_defaults(struct aco_type *type, const char *category, void *obj) return 0; } -/* default config option handlers */ +/* Default config option handlers */ + +/*! \brief Default option handler for signed integers + * \note For a description of the opt->flags and opt->args values, see the documentation for + * enum aco_option_type in config_options.h + */ static int int_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) { int *field = (int *)(obj + opt->args[0]); unsigned int flags = PARSE_INT32 | opt->flags; @@ -623,6 +628,10 @@ static int int_handler_fn(const struct aco_option *opt, struct ast_variable *var return res; } +/*! \brief Default option handler for unsigned integers + * \note For a description of the opt->flags and opt->args values, see the documentation for + * enum aco_option_type in config_options.h + */ static int uint_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) { unsigned int *field = (unsigned int *)(obj + opt->args[0]); unsigned int flags = PARSE_INT32 | opt->flags; @@ -649,27 +658,40 @@ static int uint_handler_fn(const struct aco_option *opt, struct ast_variable *va return res; } +/*! \brief Default option handler for doubles + * \note For a description of the opt->flags and opt->args values, see the documentation for + * enum aco_option_type in config_options.h + */ static int double_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) { double *field = (double *)(obj + opt->args[0]); return ast_parse_arg(var->value, PARSE_DOUBLE | opt->flags, field); } +/*! \brief Default handler for ACLs + * \note For a description of the opt->flags and opt->args values, see the documentation for + * enum aco_option_type in config_options.h + */ static int acl_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct ast_ha **ha = (struct ast_ha **)(obj + opt->args[0]); - const char *permit = (const char *) opt->args[1]; int error = 0; - *ha = ast_append_ha(permit, var->value, *ha, &error); + *ha = ast_append_ha(opt->flags ? "permit" : "deny", var->value, *ha, &error); return error; } -/* opt->args[0] = struct ast_codec_pref, opt->args[1] struct ast_format_cap * */ +/*! \brief Default option handler for codec preferences/capabilities + * \note For a description of the opt->flags and opt->args values, see the documentation for + * enum aco_option_type in config_options.h + */ static int codec_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct ast_codec_pref *pref = (struct ast_codec_pref *)(obj + opt->args[0]); struct ast_format_cap **cap = (struct ast_format_cap **)(obj + opt->args[1]); return ast_parse_allow_disallow(pref, *cap, var->value, opt->flags); } -/* opt->args[0] = ast_string_field, opt->args[1] = field_mgr_pool, opt->args[2] = field_mgr */ +/*! \brief Default option handler for stringfields + * \note For a description of the opt->flags and opt->args values, see the documentation for + * enum aco_option_type in config_options.h + */ static int stringfield_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) { ast_string_field *field = (const char **)(obj + opt->args[0]); @@ -679,6 +701,10 @@ static int stringfield_handler_fn(const struct aco_option *opt, struct ast_varia return 0; } +/*! \brief Default option handler for bools (ast_true/ast_false) + * \note For a description of the opt->flags and opt->args values, see the documentation for + * enum aco_option_type in config_options.h + */ static int bool_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) { unsigned int *field = (unsigned int *)(obj + opt->args[0]); @@ -686,6 +712,10 @@ static int bool_handler_fn(const struct aco_option *opt, struct ast_variable *va return 0; } +/*! \brief Default handler for ast_sockaddrs + * \note For a description of the opt->flags and opt->args values, see the documentation for + * enum aco_option_type in config_options.h + */ static int sockaddr_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct ast_sockaddr *field = (struct ast_sockaddr *)(obj + opt->args[0]); diff --git a/tests/test_config.c b/tests/test_config.c index 57d2bbdedd..154b8241cd 100644 --- a/tests/test_config.c +++ b/tests/test_config.c @@ -805,8 +805,8 @@ AST_TEST_DEFINE(config_options_test) aco_option_register(&cfg_info, "doubleopt", ACO_EXACT, config_test_conf.types, DOUBLE_DEFAULT, OPT_DOUBLE_T, 0, FLDSET(struct test_item, doubleopt)); aco_option_register(&cfg_info, "sockaddropt", ACO_EXACT, config_test_conf.types, SOCKADDR_DEFAULT, OPT_SOCKADDR_T, 0, FLDSET(struct test_item, sockaddropt)); aco_option_register(&cfg_info, "boolopt", ACO_EXACT, config_test_conf.types, BOOL_DEFAULT, OPT_BOOL_T, 1, FLDSET(struct test_item, boolopt)); - aco_option_register(&cfg_info, "aclpermitopt", ACO_EXACT, config_test_conf.types, ACL_DEFAULT, OPT_ACL_T, 1, FLDSET(struct test_item, aclopt), "permit"); - aco_option_register(&cfg_info, "acldenyopt", ACO_EXACT, config_test_conf.types, ACL_DEFAULT, OPT_ACL_T, 0, FLDSET(struct test_item, aclopt), "deny"); + aco_option_register(&cfg_info, "aclpermitopt", ACO_EXACT, config_test_conf.types, ACL_DEFAULT, OPT_ACL_T, 1, FLDSET(struct test_item, aclopt)); + aco_option_register(&cfg_info, "acldenyopt", ACO_EXACT, config_test_conf.types, ACL_DEFAULT, OPT_ACL_T, 0, FLDSET(struct test_item, aclopt)); aco_option_register(&cfg_info, "codecopt", ACO_EXACT, config_test_conf.types, CODEC_DEFAULT, OPT_CODEC_T, 1, FLDSET(struct test_item, codecprefopt, codeccapopt)); aco_option_register(&cfg_info, "stropt", ACO_EXACT, config_test_conf.types, STR_DEFAULT, OPT_STRINGFIELD_T, 0, STRFLDSET(struct test_item, stropt)); aco_option_register_custom(&cfg_info, "customopt", ACO_EXACT, config_test_conf.types, CUSTOM_DEFAULT, customopt_handler, 0);