bool read_only;
bool intermediate; //!< intermediate commands can't have callbacks
bool live; //!< is this entry live?
+ bool added_name; //!< was this name added?
};
int argc = 0, depth = 0;
fr_cmd_argv_t *syntax_argv;
+ /*
+ * This is a place-holder for tab expansion.
+ */
if (!table->name) {
- fr_strerror_printf("A name MUST be specified for table with parent %s syntax %s", table->parent, table->syntax);
+ fr_strerror_printf("A name MUST be specified.");
return -1;
}
cmd = fr_command_find(start, parents[i], &insert);
if (!cmd) {
cmd = fr_command_alloc(talloc_ctx, insert, parents[i]);
+ cmd->live = true;
}
if (!cmd->intermediate) {
* Add an intermediate name, e.g. "network X"
*/
if (table->add_name) {
+ fr_cmd_t **added_insert;
+
+ /*
+ * See if we need to create the automatic
+ * place-holder command for help text.
+ */
+ cmd = fr_command_find(start, "STRING", &added_insert);
+ if (!cmd) {
+ cmd = fr_command_alloc(talloc_ctx, added_insert, "STRING");
+ }
+
+ /*
+ * In the place-holders children, see if we need
+ * to add this subcommand.
+ */
+ cmd = fr_command_find(&(cmd->child), table->name, &added_insert);
+ if (!cmd) {
+ cmd = fr_command_alloc(talloc_ctx, added_insert, table->name);
+
+ if (table->syntax) cmd->syntax = talloc_strdup(cmd, table->syntax);
+ if (table->help) cmd->help = talloc_strdup(cmd, table->help);
+ }
+
+ /*
+ * Now insert or add the extended name to the command hierarchy.
+ */
cmd = fr_command_find(start, name, &insert);
if (!cmd) {
cmd = fr_command_alloc(talloc_ctx, insert, name);
+ cmd->added_name = true;
+ cmd->live = true;
}
start = &(cmd->child);
fprintf(fp, "%s %s\n", cmd->name, cmd->syntax);
}
- if (cmd->help) {
+ if (cmd->help && ((options & FR_COMMAND_OPTION_HELP) != 0)) {
fprintf(fp, "\t%s\n", cmd->help);
}
}
fr_cmd_t *cmd;
for (cmd = head; cmd != NULL; cmd = cmd->next) {
+ if (cmd->added_name) continue;
+
+ // We DO print out commands are !cmd->live
+
if (cmd->child && ((depth + 1) < max_depth)) {
argv[depth] = cmd->name;
fr_command_list_internal(fp, cmd->child, depth + 1, max_depth, argv, options);
while (cmd) {
SKIP_SPACES;
+ /*
+ * Skip commands which we shouldn't know about...
+ */
+ if (!cmd->live) {
+ cmd = cmd->next;
+ continue;
+ }
+
/*
* End of the input. Tab expand everything here.
*/
while (cmd) {
SKIP_SPACES;
+ /*
+ * Skip commands which we shouldn't know about...
+ */
+ if (!cmd->live) {
+ cmd = cmd->next;
+ continue;
+ }
+
/*
* End of the input. Tab expand everything here.
*/
if (!*word) {
expand:
while (cmd && (count < max_expansions)) {
+ if (!cmd->live) goto next;
+
SKIP_NAME(cmd->name);
/*
expansions[count] = strdup(cmd->name);
count++;
}
+
+ next:
cmd = cmd->next;
}
static TALLOC_CTX *instance_ctx = NULL;
static int module_instantiate(CONF_SECTION *root, char const *name);
+static fr_cmd_table_t cmd_module_table[];
/** Initialise a module specific exfile handle
*
if (mi->instantiated) return 0;
+ if (fr_command_register_hook(mi->name, mi, cmd_module_table) < 0) {
+ ERROR("Failed registering radmin commands for module %s - %s",
+ mi->name, fr_strerror());
+ return -1;
+ }
+
/*
* Now that ALL modules are instantiated, and ALL xlats
* are defined, go compile the config items marked as XLAT.
}
-static int cmd_show_module_config(FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
+static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
{
- module_instance_t *mi;
- CONF_SECTION *modules = (CONF_SECTION *) ctx;
-
- mi = cf_data_value(cf_data_find(modules, module_instance_t, info->argv[0]));
- if (!mi) {
- fprintf(fp_err, "No such module '%s'\n", info->argv[0]);
- return -1;
- }
+ module_instance_t *mi = ctx;
rad_assert(mi->dl_inst->conf != NULL);
return 0;
}
-
-static int cmd_show_module_status(FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
+static int cmd_show_module_status(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUSED fr_cmd_info_t const *info)
{
- module_instance_t *mi;
- CONF_SECTION *modules = (CONF_SECTION *) ctx;
-
- mi = cf_data_value(cf_data_find(modules, module_instance_t, info->argv[0]));
- if (!mi) {
- fprintf(fp_err, "No such module '%s'\n", info->argv[0]);
- return -1;
- }
+ module_instance_t *mi = ctx;
if (!mi->force) {
fprintf(fp, "alive\n");
return 0;
}
-static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
+static int cmd_set_module_status(UNUSED FILE *fp, UNUSED FILE *fp_err, void *ctx, fr_cmd_info_t const *info)
{
- module_instance_t *mi;
- CONF_SECTION *modules = (CONF_SECTION *) ctx;
+ module_instance_t *mi = ctx;
rlm_rcode_t rcode;
- mi = cf_data_value(cf_data_find(modules, module_instance_t, info->argv[0]));
- if (!mi) {
- fprintf(fp_err, "No such module '%s'\n", info->argv[0]);
- return -1;
- }
-
if (strcmp(info->argv[1], "alive") == 0) {
mi->force = false;
return 0;
return 0;
}
-static fr_cmd_table_t cmd_table[] = {
+
+static fr_cmd_table_t cmd_module_table[] = {
{
- .parent = "show",
- .name = "module",
- .help = "Show information about modules.",
+ .parent = "show module",
+ .add_name = true,
+ .name = "status",
+ .func = cmd_show_module_status,
+ .help = "Show the status of a particular module.",
.read_only = true,
},
{
.parent = "show module",
- .name = "list",
- .func = cmd_show_module_list,
- .help = "Show the list of modules loaded in the server.",
+ .add_name = true,
+ .name = "config",
+ .func = cmd_show_module_config,
+ .help = "Show configuration for a module",
+ // @todo - do tab expand, by walking over the whole module list...
.read_only = true,
},
{
- .parent = "show config",
+ .parent = "set module",
+ .add_name = true,
+ .name = "status",
+ .syntax = "(alive|ok|fail|reject|handled|invalid|userlock|notfound|noop|updated)",
+ .func = cmd_set_module_status,
+ .help = "Change module status to fixed value.",
+ .read_only = false,
+ },
+
+ CMD_TABLE_END
+};
+
+
+static fr_cmd_table_t cmd_table[] = {
+ {
+ .parent = "show",
.name = "module",
- .syntax = "STRING",
- .func = cmd_show_module_config,
+ .help = "Show information about modules.",
.tab_expand = module_name_tab_expand,
- .help = "show module config NAME",
- // @todo - do tab expand, by walking over the whole module list...
.read_only = true,
},
+ // @todo - what if there's a module called "list" ?
{
.parent = "show module",
- .name = "status",
- .syntax = "STRING",
- .func = cmd_show_module_status,
- .tab_expand = module_name_tab_expand,
- .help = "show module status NAME",
+ .name = "list",
+ .func = cmd_show_module_list,
+ .help = "Show the list of modules loaded in the server.",
.read_only = true,
},
.parent = "set",
.name = "module",
.help = "Change module settings.",
+ .tab_expand = module_name_tab_expand,
.read_only = false,
},
- {
- .parent = "set module",
- .name = "status",
- .syntax = "STRING (alive|ok|fail|reject|handled|invalid|userlock|notfound|noop|updated)",
- .func = cmd_set_module_status,
- .help = "Change module status to fixed value.",
- .read_only = false,
- },
CMD_TABLE_END
};