[svn-commits] file: branch file/res_clialiases r140360 - in /team/file/res_clialiases: conf...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Aug 27 18:54:28 CDT 2008


Author: file
Date: Wed Aug 27 18:54:28 2008
New Revision: 140360

URL: http://svn.digium.com/view/asterisk?view=rev&rev=140360
Log:
Add res_clialiases. This is a module which allows 'aliased' CLI commands. Essentially in a configuration file you specify an alias command with the real command that it should behave as. It accepts and passes on arguments and also performs tab completion as though it were the real command.

Added:
    team/file/res_clialiases/configs/cli_aliases.conf.sample   (with props)
    team/file/res_clialiases/res/res_clialiases.c   (with props)

Added: team/file/res_clialiases/configs/cli_aliases.conf.sample
URL: http://svn.digium.com/view/asterisk/team/file/res_clialiases/configs/cli_aliases.conf.sample?view=auto&rev=140360
==============================================================================
--- team/file/res_clialiases/configs/cli_aliases.conf.sample (added)
+++ team/file/res_clialiases/configs/cli_aliases.conf.sample Wed Aug 27 18:54:28 2008
@@ -1,0 +1,18 @@
+;
+; CLI Aliases configuration
+;
+; This module also registers a "cli show aliases" CLI command to list
+; configured CLI aliases.
+
+[aliases]
+; To create an alias you simply set the variable name as the alias and variable value as the real
+; CLI command you want executed
+;
+; Example:
+; mr=module reload
+;
+; This will make the CLI command "mr" behave as though it is "module reload".
+
+; Alias for making voicemail reload actually do module reload app_voicemail.so
+voicemail reload=module reload app_voicemail.so
+

Propchange: team/file/res_clialiases/configs/cli_aliases.conf.sample
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/file/res_clialiases/configs/cli_aliases.conf.sample
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/file/res_clialiases/configs/cli_aliases.conf.sample
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/file/res_clialiases/res/res_clialiases.c
URL: http://svn.digium.com/view/asterisk/team/file/res_clialiases/res/res_clialiases.c?view=auto&rev=140360
==============================================================================
--- team/file/res_clialiases/res/res_clialiases.c (added)
+++ team/file/res_clialiases/res/res_clialiases.c Wed Aug 27 18:54:28 2008
@@ -1,0 +1,271 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2008, Digium, Inc.
+ *
+ * Joshua Colp <jcolp at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief CLI Aliases
+ *
+ * \author\verbatim Joshua Colp <jcolp at digium.com> \endverbatim
+ * 
+ * This module provides the capability to create aliases to other
+ * CLI commands.
+ */
+
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/module.h"
+#include "asterisk/config.h"
+#include "asterisk/cli.h"
+#include "asterisk/astobj2.h"
+
+/*! Maximum number of buckets for CLI aliases */
+#define MAX_ALIAS_BUCKETS 53
+
+/*! Configuration file used for this application */
+static const char config_file[] = "cli_aliases.conf";
+
+struct cli_alias {
+	struct ast_cli_entry cli_entry; /*!< Actual CLI structure used for this alias */
+	char *alias;                    /*!< CLI Alias */
+	char *real_cmd;                 /*!< Actual CLI command it is aliased to */
+	unsigned int marked:1;          /*!< Bit to indicate whether this CLI alias is marked for destruction or not */
+};
+
+static struct ao2_container *cli_aliases;
+
+/*! \brief Hashing function used for aliases */
+static int alias_hash_cb(const void *obj, const int flags)
+{
+	const struct cli_alias *alias = obj;
+	return ast_str_hash(alias->cli_entry.command);
+}
+
+/*! \brief Comparison function used for aliases */
+static int alias_cmp_cb(void *obj, void *arg, int flags)
+{
+	const struct cli_alias *alias0 = obj, *alias1 = arg;
+
+	return (alias0->cli_entry.command == alias1->cli_entry.command ? CMP_MATCH : 0);
+}
+
+/*! \brief Destruction function used for aliases */
+static void alias_destroy(void *obj)
+{
+	struct cli_alias *alias = obj;
+
+	/* Unregister the CLI entry from the core */
+	ast_cli_unregister(&alias->cli_entry);
+
+	ast_free(alias->alias);
+	ast_free(alias->real_cmd);
+
+	return;
+}
+
+/*! \brief Function which passes through an aliased CLI command to the real one */
+static char *cli_alias_passthrough(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	struct cli_alias *alias;
+	struct cli_alias tmp = {
+		.cli_entry.command = e->command,
+	};
+	char *generator;
+	const char *line;
+
+	/* Try to find the alias based on the CLI entry */
+	if (!(alias = ao2_find(cli_aliases, &tmp, OBJ_POINTER))) {
+		return 0;
+	}
+
+	switch (cmd) {
+	case CLI_INIT:
+		ao2_ref(alias, -1);
+		return NULL;
+	case CLI_GENERATE:
+		line = a->line;
+		line += (strlen(alias->alias));
+		if (!ast_strlen_zero(a->word)) {
+			struct ast_str *real_cmd = ast_str_alloca(strlen(alias->real_cmd) + strlen(line) + 1);
+			ast_str_append(&real_cmd, 0, "%s%s", alias->real_cmd, line);
+			generator = ast_cli_generator(real_cmd->str, a->word, a->n);
+		} else {
+			generator = ast_cli_generator(alias->real_cmd, a->word, a->n);
+		}
+		ao2_ref(alias, -1);
+		return generator;
+	}
+
+	/* If they gave us extra arguments we need to construct a string to pass in */
+	if (a->argc != e->args) {
+		struct ast_str *real_cmd = ast_str_alloca(2048);
+		int i;
+
+		ast_str_append(&real_cmd, 0, "%s", alias->real_cmd);
+
+		/* Add the additional arguments that have been passed in */
+		for (i = e->args + 1; i <= a->argc; i++) {
+			ast_str_append(&real_cmd, 0, " %s", a->argv[i - 1]);
+		}
+
+		ast_cli_command(a->fd, real_cmd->str);
+	} else {
+		ast_cli_command(a->fd, alias->real_cmd);
+	}
+
+	ao2_ref(alias, -1);
+
+	return CLI_SUCCESS;
+}
+
+/*! \brief CLI Command to display CLI Aliases */
+static char *alias_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+#define FORMAT "%-50.50s %-50.50s\n"
+	struct cli_alias *alias;
+	struct ao2_iterator i;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "cli show aliases";
+		e->usage =
+			"Usage: cli show aliases\n"
+			"       Displays a list of aliased CLI commands.\n";
+		return NULL;
+	case CLI_GENERATE:
+		return NULL;
+	}
+
+	ast_cli(a->fd, FORMAT, "Alias Command", "Real Command");
+
+	i = ao2_iterator_init(cli_aliases, 0);
+
+	for (; (alias = ao2_iterator_next(&i)); ao2_ref(alias, -1)) {
+		ast_cli(a->fd, FORMAT, alias->alias, alias->real_cmd);
+	}
+
+	return CLI_SUCCESS;
+#undef FORMAT
+}
+
+/*! \brief CLI commands to interact with things */
+static struct ast_cli_entry cli_alias[] = {
+	AST_CLI_DEFINE(alias_show, "Show CLI command aliases"),
+};
+
+/*! \brief Function called to mark an alias for destruction */
+static int alias_mark(void *obj, void *arg, int flags)
+{
+	struct cli_alias *alias = obj;
+	alias->marked = 1;
+	return 0;
+}
+
+/*! \brief Function called to see if an alias is marked for destruction */
+static int alias_marked(void *obj, void *arg, int flags)
+{
+	struct cli_alias *alias = obj;
+	return alias->marked ? CMP_MATCH : 0;
+}
+
+/*! \brief Function called to load or reload the configuration file */
+static void load_config(int reload)
+{
+	struct ast_config *cfg = NULL;
+	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+	struct cli_alias *alias;
+	struct ast_variable *v;
+
+	if (!(cfg = ast_config_load(config_file, config_flags))) {
+		ast_log(LOG_ERROR, "res_clialiases configuration file '%s' not found\n", config_file);
+		return;
+	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
+		return;
+	}
+
+	/* Mark CLI aliases for pruning */
+	if (reload) {
+		ao2_callback(cli_aliases, OBJ_NODATA, alias_mark, NULL);
+	}
+
+	/* Read in those there CLI aliases */
+	for (v = ast_variable_browse(cfg, "aliases"); v; v = v->next) {
+		if (!(alias = ao2_alloc(sizeof(*alias), alias_destroy))) {
+			continue;
+		}
+		alias->alias = ast_strdup(v->name);
+		alias->real_cmd = ast_strdup(v->value);
+		alias->cli_entry.handler = cli_alias_passthrough;
+		alias->cli_entry.command = alias->alias;
+		alias->cli_entry.usage = "Aliased CLI Command";
+		ao2_link(cli_aliases, alias);
+		ast_cli_register(&alias->cli_entry);
+		ao2_ref(alias, -1);
+		ast_verbose(VERBOSE_PREFIX_2 "Aliased CLI command '%s' to '%s'\n", v->name, v->value);
+	}
+
+	/* Drop any CLI aliases that should no longer exist */
+	if (reload) {
+		while ((alias = ao2_callback(cli_aliases, OBJ_UNLINK, alias_marked, NULL))) {
+			ao2_ref(alias, -1);
+		}
+	}
+
+	ast_config_destroy(cfg);
+
+	return;
+}
+
+/*! \brief Function called to reload the module */
+static int reload_module(void)
+{
+	load_config(1);
+	return 0;
+}
+
+/*! \brief Function called to unload the module */
+static int unload_module(void)
+{
+	ao2_ref(cli_aliases, -1);
+
+	ast_cli_unregister_multiple(cli_alias, sizeof(cli_alias) / sizeof(struct ast_cli_entry));
+
+	return 0;
+}
+
+/*! \brief Function called to load the module */
+static int load_module(void)
+{
+	if (!(cli_aliases = ao2_container_alloc(MAX_ALIAS_BUCKETS, alias_hash_cb, alias_cmp_cb))) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	load_config(0);
+
+	ast_cli_register_multiple(cli_alias, sizeof(cli_alias) / sizeof(struct ast_cli_entry));
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "CLI Aliases",
+		.load = load_module,
+		.unload = unload_module,
+		.reload = reload_module,
+		);

Propchange: team/file/res_clialiases/res/res_clialiases.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/file/res_clialiases/res/res_clialiases.c
------------------------------------------------------------------------------
    svn:keywords = 'Author Date Id Revision'

Propchange: team/file/res_clialiases/res/res_clialiases.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain




More information about the svn-commits mailing list