Wed Oct 28 11:46:06 2009

Asterisk developer's documentation


cli.c File Reference

Standard Command Line Interface. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include <sys/signal.h>
#include <signal.h>
#include <ctype.h>
#include <regex.h>
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/lock.h"
#include "editline/readline/readline.h"
#include "asterisk/threadstorage.h"

Include dependency graph for cli.c:

Go to the source code of this file.

Data Structures

struct  ast_debug_file
 map a debug or verbose value to a filename More...
struct  debug_file_list
struct  helpers

Defines

#define AST_CLI_INITLEN   256
 Initial buffer size for resulting strings in ast_cli().
#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
#define DAY   (HOUR*24)
#define FORMAT_STRING   "%-25s %-20s %-20s\n"
#define FORMAT_STRING   "%-20.20s %-20.20s %-7.7s %-30.30s\n"
#define FORMAT_STRING2   "%-20.20s %-20.20s %-7.7s %-30.30s\n"
#define HOUR   (MINUTE*60)
#define MINUTE   (SECOND*60)
#define MODLIST_FORMAT   "%-30s %-40.40s %-10d\n"
#define MODLIST_FORMAT2   "%-30s %-40.40s %-10s\n"
#define NEEDCOMMA(x)   ((x)? ",": "")
#define SECOND   (1)
#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"
#define VERBOSE_FORMAT_STRING2   "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"
#define WEEK   (DAY*7)
#define YEAR   (DAY*365)

Functions

static char * __ast_cli_generator (const char *text, const char *word, int state, int lock)
static int __ast_cli_register (struct ast_cli_entry *e, struct ast_cli_entry *ed)
static int __ast_cli_unregister (struct ast_cli_entry *e, struct ast_cli_entry *ed)
static void __fini_helpers (void)
static void __init_ast_cli_buf (void)
static void __init_helpers (void)
void ast_builtins_init (void)
 initialize the _full_cmd string in * each of the builtins.
void ast_cli (int fd, const char *fmt,...)
int ast_cli_command (int fd, const char *s)
 Interprets a command Interpret a command s, sending output to fd.
int ast_cli_command_multiple (int fd, size_t size, const char *s)
 Executes multiple CLI commands Interpret strings separated by NULL and execute each one, sending output to fd.
char * ast_cli_complete (const char *word, char *const choices[], int state)
char ** ast_cli_completion_matches (const char *text, const char *word)
 Generates a NULL-terminated array of strings that 1) begin with the string in the second parameter, and 2) are valid in a command after the string in the first parameter.
char * ast_cli_generator (const char *text, const char *word, int state)
 Readline madness Useful for readline, that's about it.
int ast_cli_generatornummatches (const char *text, const char *word)
 Return the number of unique matches for the generator.
int ast_cli_register (struct ast_cli_entry *e)
 Registers a command or an array of commands.
int ast_cli_register_multiple (struct ast_cli_entry *e, int len)
 Register multiple commands.
int ast_cli_unregister (struct ast_cli_entry *e)
 Unregisters a command or an array of commands.
int ast_cli_unregister_multiple (struct ast_cli_entry *e, int len)
 Unregister multiple commands.
char * ast_complete_channels (const char *line, const char *word, int pos, int state, int rpos)
 Command completion for the list of active channels.
unsigned int ast_debug_get_by_file (const char *file)
 Get the debug level for a file.
unsigned int ast_verbose_get_by_file (const char *file)
 Get the debug level for a file.
static struct ast_cli_entrycli_next (struct ast_cli_entry *e)
static char * complete_fn (const char *word, int state)
static char * find_best (char *argv[])
static struct ast_cli_entryfind_cli (char *const cmds[], int match_type)
 locate a cli command in the 'helpers' list (which must be locked). exact has 3 values: 0 returns if the search key is equal or longer than the entry. note that trailing optional arguments are skipped. -1 true if the mismatch is on the last word XXX not true! 1 true only on complete, exact match.
static struct ast_debug_filefind_debug_file (const char *fn, unsigned int debug)
 Find the debug or verbose file setting.
static char * group_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_chanlist (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_commandcomplete (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_commandmatchesarray (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_commandnummatches (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_core_set_debug_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_debugchan_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_help (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_load (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_load_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_logger_mute (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_modlist (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_nodebugchan_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_reload_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showcalls (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showchan (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showuptime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_softhangup (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_unload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_unload_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_verbose (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * help1 (int fd, char *match[], int locked)
 helper for final part of handle_help if locked = 1, assume the list is already locked
static char * is_prefix (const char *word, const char *token, int pos, int *actual)
 if word is a valid prefix for token, returns the pos-th match as a malloced string, or NULL otherwise. Always tell in *actual how many matches we got.
static int modlist_modentry (const char *module, const char *description, int usecnt, const char *like)
static int more_words (char *const *dst)
 returns true if there are more words to match
static char * parse_args (const char *s, int *argc, char *argv[], int max, int *trailingwhitespace)
static void print_uptimestr (int fd, struct timeval timeval, const char *prefix, int printsec)
static int set_full_cmd (struct ast_cli_entry *e)
static int word_match (const char *cmd, const char *cli_word)

Variables

static struct ast_threadstorage ast_cli_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_ast_cli_buf , .custom_init = NULL , }
static struct ast_cli_entry cli_cli []
static struct ast_cli_entry cli_debug_channel_deprecated = AST_CLI_DEFINE(handle_debugchan_deprecated, "Enable debugging on channel")
static struct ast_cli_entry cli_module_load_deprecated = AST_CLI_DEFINE(handle_load_deprecated, "Load a module")
static struct ast_cli_entry cli_module_reload_deprecated = AST_CLI_DEFINE(handle_reload_deprecated, "reload modules by name")
static struct ast_cli_entry cli_module_unload_deprecated = AST_CLI_DEFINE(handle_unload_deprecated, "unload modules by name")
static const char cli_rsvd [] = "[]{}|*%"
static int climodentryfd = -1
static ast_mutex_t climodentrylock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static struct debug_file_list debug_files
static struct debug_file_list verbose_files


Detailed Description

Standard Command Line Interface.

Author:
Mark Spencer <markster@digium.com>

Definition in file cli.c.


Define Documentation

#define AST_CLI_INITLEN   256

Initial buffer size for resulting strings in ast_cli().

Definition at line 67 of file cli.c.

Referenced by ast_cli().

#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"

Referenced by handle_chanlist().

#define DAY   (HOUR*24)

Referenced by print_uptimestr().

#define FORMAT_STRING   "%-25s %-20s %-20s\n"

#define FORMAT_STRING   "%-20.20s %-20.20s %-7.7s %-30.30s\n"

#define FORMAT_STRING2   "%-20.20s %-20.20s %-7.7s %-30.30s\n"

Referenced by handle_chanlist().

#define HOUR   (MINUTE*60)

Referenced by print_uptimestr().

#define MINUTE   (SECOND*60)

Referenced by print_uptimestr().

#define MODLIST_FORMAT   "%-30s %-40.40s %-10d\n"

Definition at line 439 of file cli.c.

Referenced by modlist_modentry().

#define MODLIST_FORMAT2   "%-30s %-40.40s %-10s\n"

Definition at line 440 of file cli.c.

Referenced by handle_modlist().

#define NEEDCOMMA (  )     ((x)? ",": "")

Referenced by print_uptimestr().

#define SECOND   (1)

#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"

Referenced by handle_chanlist().

#define VERBOSE_FORMAT_STRING2   "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"

Referenced by handle_chanlist().

#define WEEK   (DAY*7)

Referenced by print_uptimestr().

#define YEAR   (DAY*365)

Referenced by print_uptimestr().


Function Documentation

static char * __ast_cli_generator ( const char *  text,
const char *  word,
int  state,
int  lock 
) [static]

Definition at line 1771 of file cli.c.

References ARRAY_LEN, ast_free, ast_join(), AST_MAX_ARGS, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_strlen_zero(), CLI_GENERATE, cli_next(), ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::handler, is_prefix(), ast_cli_args::line, more_words(), parse_args(), and word_match().

Referenced by ast_cli_generator(), handle_commandcomplete(), and handle_help().

01772 {
01773    char *argv[AST_MAX_ARGS];
01774    struct ast_cli_entry *e = NULL;
01775    int x = 0, argindex, matchlen;
01776    int matchnum=0;
01777    char *ret = NULL;
01778    char matchstr[80] = "";
01779    int tws = 0;
01780    /* Split the argument into an array of words */
01781    char *dup = parse_args(text, &x, argv, ARRAY_LEN(argv), &tws);
01782 
01783    if (!dup)   /* malloc error */
01784       return NULL;
01785 
01786    /* Compute the index of the last argument (could be an empty string) */
01787    argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x;
01788 
01789    /* rebuild the command, ignore terminating white space and flatten space */
01790    ast_join(matchstr, sizeof(matchstr)-1, argv);
01791    matchlen = strlen(matchstr);
01792    if (tws) {
01793       strcat(matchstr, " "); /* XXX */
01794       if (matchlen)
01795          matchlen++;
01796    }
01797    if (lock)
01798       AST_RWLIST_RDLOCK(&helpers);
01799    while ( (e = cli_next(e)) ) {
01800       /* XXX repeated code */
01801       int src = 0, dst = 0, n = 0;
01802 
01803       if (e->command[0] == '_')
01804          continue;
01805 
01806       /*
01807        * Try to match words, up to and excluding the last word, which
01808        * is either a blank or something that we want to extend.
01809        */
01810       for (;src < argindex; dst++, src += n) {
01811          n = word_match(argv[src], e->cmda[dst]);
01812          if (n < 0)
01813             break;
01814       }
01815 
01816       if (src != argindex && more_words(e->cmda + dst))  /* not a match */
01817          continue;
01818       ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n);
01819       matchnum += n; /* this many matches here */
01820       if (ret) {
01821          /*
01822           * argv[src] is a valid prefix of the next word in this
01823           * command. If this is also the correct entry, return it.
01824           */
01825          if (matchnum > state)
01826             break;
01827          ast_free(ret);
01828          ret = NULL;
01829       } else if (ast_strlen_zero(e->cmda[dst])) {
01830          /*
01831           * This entry is a prefix of the command string entered
01832           * (only one entry in the list should have this property).
01833           * Run the generator if one is available. In any case we are done.
01834           */
01835          if (e->handler) { /* new style command */
01836             struct ast_cli_args a = {
01837                .line = matchstr, .word = word,
01838                .pos = argindex,
01839                .n = state - matchnum };
01840             ret = e->handler(e, CLI_GENERATE, &a);
01841          }
01842          if (ret)
01843             break;
01844       }
01845    }
01846    if (lock)
01847       AST_RWLIST_UNLOCK(&helpers);
01848    ast_free(dup);
01849    return ret;
01850 }

static int __ast_cli_register ( struct ast_cli_entry e,
struct ast_cli_entry ed 
) [static]

Definition at line 1439 of file cli.c.

References ast_cli_entry::_deprecated_by, ast_cli_entry::_full_cmd, ast_log(), AST_MAX_CMD_LEN, AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_skip_blanks(), ast_skip_nonblanks(), ast_strdup, ast_strlen_zero(), CLI_INIT, ast_cli_entry::cmda, ast_cli_entry::cmdlen, ast_cli_entry::command, ast_cli_entry::deprecate_cmd, ast_cli_entry::deprecated, find_cli(), ast_cli_entry::handler, len(), LOG_WARNING, s, S_OR, set_full_cmd(), ast_cli_entry::summary, and ast_cli_entry::usage.

Referenced by ast_cli_register().

01440 {
01441    struct ast_cli_entry *cur;
01442    int i, lf, ret = -1;
01443 
01444    struct ast_cli_args a;  /* fake argument */
01445    char **dst = (char **)e->cmda;   /* need to cast as the entry is readonly */
01446    char *s;
01447 
01448    memset(&a, '\0', sizeof(a));
01449    e->handler(e, CLI_INIT, &a);
01450    /* XXX check that usage and command are filled up */
01451    s = ast_skip_blanks(e->command);
01452    s = e->command = ast_strdup(s);
01453    for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) {
01454       *dst++ = s; /* store string */
01455       s = ast_skip_nonblanks(s);
01456       if (*s == '\0')   /* we are done */
01457          break;
01458       *s++ = '\0';
01459       s = ast_skip_blanks(s);
01460    }
01461    *dst++ = NULL;
01462    
01463    AST_RWLIST_WRLOCK(&helpers);
01464    
01465    if (find_cli(e->cmda, 1)) {
01466       ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", e->_full_cmd);
01467       goto done;
01468    }
01469    if (set_full_cmd(e))
01470       goto done;
01471    if (!ed) {
01472       e->deprecated = 0;
01473    } else {
01474       e->deprecated = 1;
01475       e->summary = ed->summary;
01476       e->usage = ed->usage;
01477       /* XXX If command A deprecates command B, and command B deprecates command C...
01478          Do we want to show command A or command B when telling the user to use new syntax?
01479          This currently would show command A.
01480          To show command B, you just need to always use ed->_full_cmd.
01481        */
01482       e->_deprecated_by = S_OR(ed->_deprecated_by, ed->_full_cmd);
01483    }
01484 
01485    lf = e->cmdlen;
01486    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
01487       int len = cur->cmdlen;
01488       if (lf < len)
01489          len = lf;
01490       if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) {
01491          AST_RWLIST_INSERT_BEFORE_CURRENT(e, list); 
01492          break;
01493       }
01494    }
01495    AST_RWLIST_TRAVERSE_SAFE_END;
01496 
01497    if (!cur)
01498       AST_RWLIST_INSERT_TAIL(&helpers, e, list); 
01499    ret = 0; /* success */
01500 
01501 done:
01502    AST_RWLIST_UNLOCK(&helpers);
01503 
01504    if (e->deprecate_cmd) {
01505       /* This command deprecates another command.  Register that one also. */
01506       __ast_cli_register(e->deprecate_cmd, e);
01507    }
01508    
01509    return ret;
01510 }

static int __ast_cli_unregister ( struct ast_cli_entry e,
struct ast_cli_entry ed 
) [static]

Definition at line 1414 of file cli.c.

References ast_cli_entry::_full_cmd, ast_free, ast_log(), AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::deprecate_cmd, ast_cli_entry::handler, ast_cli_entry::inuse, ast_cli_entry::list, LOG_WARNING, and ast_cli_entry::usage.

Referenced by ast_cli_unregister().

01415 {
01416    if (e->deprecate_cmd) {
01417       __ast_cli_unregister(e->deprecate_cmd, e);
01418    }
01419    if (e->inuse) {
01420       ast_log(LOG_WARNING, "Can't remove command that is in use\n");
01421    } else {
01422       AST_RWLIST_WRLOCK(&helpers);
01423       AST_RWLIST_REMOVE(&helpers, e, list);
01424       AST_RWLIST_UNLOCK(&helpers);
01425       ast_free(e->_full_cmd);
01426       e->_full_cmd = NULL;
01427       if (e->handler) {
01428          /* this is a new-style entry. Reset fields and free memory. */
01429          char *cmda = (char *) e->cmda;
01430          memset(cmda, '\0', sizeof(e->cmda));
01431          ast_free(e->command);
01432          e->command = NULL;
01433          e->usage = NULL;
01434       }
01435    }
01436    return 0;
01437 }

static void __fini_helpers ( void   )  [static]

Definition at line 120 of file cli.c.

00123 {

static void __init_ast_cli_buf ( void   )  [static]

Definition at line 64 of file cli.c.

00070 {

static void __init_helpers ( void   )  [static]

Definition at line 120 of file cli.c.

00123 {

void ast_builtins_init ( void   ) 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 1251 of file cli.c.

References ast_cli_register_multiple(), and cli_cli.

Referenced by main().

01252 {
01253    ast_cli_register_multiple(cli_cli, sizeof(cli_cli) / sizeof(struct ast_cli_entry));
01254 }

void ast_cli ( int  fd,
const char *  fmt,
  ... 
)

Definition at line 69 of file cli.c.

References ast_carefulwrite(), AST_CLI_INITLEN, AST_DYNSTR_BUILD_FAILED, ast_str_set_va, ast_str_thread_get(), buf, and ast_str::str.

Referenced by __iax2_show_peers(), __say_cli_init(), _sip_show_peer(), _sip_show_peers(), agent_logoff_cmd(), agents_show(), agents_show_online(), aji_do_debug_deprecated(), aji_do_reload(), aji_do_set_debug(), aji_show_buddies(), aji_show_clients(), aji_test(), ast_cli_command(), ast_cli_netstats(), ast_console_toggle_mute(), cli_console_active(), cli_console_answer(), cli_console_autoanswer(), cli_console_dial(), cli_console_flash(), cli_console_hangup(), cli_console_mute(), cli_console_sendtext(), cli_list_available(), cli_list_devices(), cli_match_char_tree(), cli_realtime_load(), cli_realtime_update(), console_active(), console_answer(), console_autoanswer(), console_boost(), console_cmd(), console_dial(), console_do_answer(), console_flash(), console_hangup(), console_sendtext(), console_transfer(), dahdi_set_dnd(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), dahdi_show_status(), dahdi_show_version(), do_print(), dundi_do_debug_deprecated(), dundi_do_lookup(), dundi_do_precache(), dundi_do_query(), dundi_do_store_history_deprecated(), dundi_flush(), dundi_set_debug(), dundi_show_entityid(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), dundi_store_history(), features_show(), group_show_channels(), gtalk_show_channels(), handle_chanlist(), handle_cli_agi_debug(), handle_cli_agi_dump_html(), handle_cli_agi_dumphtml_deprecated(), handle_cli_agi_show(), handle_cli_core_show_channeltype(), handle_cli_core_show_channeltypes(), handle_cli_core_show_config_mappings(), handle_cli_core_show_file_formats(), handle_cli_core_show_translation(), handle_cli_database_del(), handle_cli_database_deltree(), handle_cli_database_get(), handle_cli_database_put(), handle_cli_database_show(), handle_cli_database_showkey(), handle_cli_devstate_change(), handle_cli_devstate_list(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_add_ignorepat(), handle_cli_dialplan_add_include(), handle_cli_dialplan_reload(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_remove_ignorepat(), handle_cli_dialplan_remove_include(), handle_cli_dialplan_save(), handle_cli_file_convert(), handle_cli_funcdevstate_list(), handle_cli_h323_set_debug(), handle_cli_h323_set_trace(), handle_cli_iax2_provision(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_set_debug_deprecated(), handle_cli_iax2_set_debug_jb(), handle_cli_iax2_set_debug_jb_deprecated(), handle_cli_iax2_set_debug_trunk(), handle_cli_iax2_set_debug_trunk_deprecated(), handle_cli_iax2_set_mtu(), handle_cli_iax2_show_cache(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_firmware(), handle_cli_iax2_show_netstats(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_stats(), handle_cli_iax2_show_threads(), handle_cli_iax2_show_users(), handle_cli_iax2_unregister(), handle_cli_indication_show(), handle_cli_keys_show(), handle_cli_misdn_reload(), handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_set_debug(), handle_cli_misdn_show_channels(), handle_cli_misdn_show_config(), handle_cli_misdn_show_port(), handle_cli_misdn_show_ports_stats(), handle_cli_misdn_show_stacks(), handle_cli_misdn_toggle_echocancel(), handle_cli_mixmonitor(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_cli_odbc_show(), handle_cli_osp_show(), handle_cli_radio_set_debug(), handle_cli_radio_set_debug_deprecated(), handle_cli_radio_tune(), handle_cli_realtime_pgsql_status(), handle_cli_refresh(), handle_cli_rpt_debug_level(), handle_cli_rpt_dump(), handle_cli_rpt_lstats(), handle_cli_rpt_stats(), handle_cli_rtcp_debug_deprecated(), handle_cli_rtcp_set_debug(), handle_cli_rtcp_set_stats(), handle_cli_rtcp_stats_deprecated(), handle_cli_rtp_debug_deprecated(), handle_cli_rtp_set_debug(), handle_cli_show_sqlite_status(), handle_cli_status(), handle_cli_stun_debug_deprecated(), handle_cli_stun_set_debug(), handle_cli_submit(), handle_cli_transcoder_show(), handle_cli_udptl_debug_deprecated(), handle_cli_udptl_set_debug(), handle_cli_ulimit(), handle_commandcomplete(), handle_commandmatchesarray(), handle_commandnummatches(), handle_core_set_debug_channel(), handle_core_show_image_formats(), handle_dahdi_show_cadences(), handle_feature_show(), handle_help(), handle_load(), handle_logger_reload(), handle_logger_rotate(), handle_logger_show_channels(), handle_mandebug(), handle_mgcp_audit_endpoint(), handle_mgcp_set_debug(), handle_mgcp_set_debug_deprecated(), handle_mgcp_show_endpoints(), handle_minivm_list_templates(), handle_minivm_reload(), handle_minivm_show_settings(), handle_minivm_show_stats(), handle_minivm_show_users(), handle_minivm_show_zones(), handle_modlist(), handle_parkedcalls(), handle_queue_add_member(), handle_queue_pause_member(), handle_queue_remove_member(), handle_queue_rule_show(), handle_queue_set_member_penalty(), handle_reload(), handle_restart_when_convenient(), handle_set_chanvar(), handle_set_extenpatternmatchnew(), handle_set_global(), handle_show_application(), handle_show_applications(), handle_show_dialplan(), handle_show_function(), handle_show_functions(), handle_show_globals(), handle_show_hint(), handle_show_hints(), handle_show_http(), handle_show_profile(), handle_show_routes(), handle_show_settings(), handle_show_switches(), handle_show_threads(), handle_show_version_files(), handle_showcalls(), handle_showchan(), handle_showmanager(), handle_showmanagers(), handle_showmancmd(), handle_showmancmds(), handle_showmanconn(), handle_showmaneventq(), handle_skinny_set_debug(), handle_skinny_set_debug_deprecated(), handle_skinny_show_device(), handle_skinny_show_devices(), handle_skinny_show_line(), handle_skinny_show_lines(), handle_skinny_show_settings(), handle_softhangup(), handle_stop_when_convenient(), handle_unload(), handle_unset_extenpatternmatchnew(), handle_verbose(), handle_version(), handle_voicemail_reload(), handle_voicemail_show_users(), handle_voicemail_show_zones(), help1(), help_workhorse(), iax_show_provisioning(), jingle_show_channels(), locals_show(), meetme_cmd(), modlist_modentry(), orig_app(), orig_exten(), print_bc_info(), print_codec_to_cli(), print_group(), print_uptimestr(), realtime_ldap_status(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_codec_n(), show_codecs(), show_config_description(), show_dialplan_helper(), show_license(), show_users_realtime(), show_warranty(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_do_history_deprecated(), sip_notify(), sip_prune_realtime(), sip_set_history(), sip_show_channel(), sip_show_channels(), sip_show_domains(), sip_show_history(), sip_show_inuse(), sip_show_objects(), sip_show_registry(), sip_show_settings(), sip_show_tcp(), sip_show_user(), sip_show_users(), sip_unregister(), sla_show_stations(), sla_show_trunks(), unistim_do_debug(), unistim_info(), and unistim_sp().

00070 {
00071    int res;
00072    struct ast_str *buf;
00073    va_list ap;
00074 
00075    if (!(buf = ast_str_thread_get(&ast_cli_buf, AST_CLI_INITLEN)))
00076       return;
00077 
00078    va_start(ap, fmt);
00079    res = ast_str_set_va(&buf, 0, fmt, ap);
00080    va_end(ap);
00081 
00082    if (res != AST_DYNSTR_BUILD_FAILED)
00083       ast_carefulwrite(fd, buf->str, strlen(buf->str), 100);
00084 }

int ast_cli_command ( int  fd,
const char *  s 
)

Interprets a command Interpret a command s, sending output to fd.

Parameters:
fd pipe
s incoming string
Return values:
0 on success
-1 on failure

Definition at line 1857 of file cli.c.

References ast_cli_entry::_deprecated_by, ast_cli_entry::_full_cmd, ast_atomic_fetchadd_int(), ast_cli(), ast_free, AST_MAX_ARGS, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_FAILURE, CLI_HANDLER, CLI_SHOWUSAGE, ast_cli_entry::deprecated, ast_cli_args::fd, find_best(), find_cli(), ast_cli_entry::handler, ast_cli_entry::inuse, parse_args(), S_OR, and ast_cli_entry::usage.

Referenced by action_command(), ast_cli_command_multiple(), cli_activate(), consolehandler(), exit_completely(), function_cop(), rpt_master(), and run_startup_commands().

01858 {
01859    char *args[AST_MAX_ARGS + 1];
01860    struct ast_cli_entry *e;
01861    int x;
01862    char *dup = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL);
01863    char *retval = NULL;
01864    struct ast_cli_args a = {
01865       .fd = fd, .argc = x, .argv = args+1 };
01866 
01867    if (dup == NULL)
01868       return -1;
01869 
01870    if (x < 1)  /* We need at least one entry, otherwise ignore */
01871       goto done;
01872 
01873    AST_RWLIST_RDLOCK(&helpers);
01874    e = find_cli(args + 1, 0);
01875    if (e)
01876       ast_atomic_fetchadd_int(&e->inuse, 1);
01877    AST_RWLIST_UNLOCK(&helpers);
01878    if (e == NULL) {
01879       ast_cli(fd, "No such command '%s' (type 'help %s' for other possible commands)\n", s, find_best(args + 1));
01880       goto done;
01881    }
01882    /*
01883     * Within the handler, argv[-1] contains a pointer to the ast_cli_entry.
01884     * Remember that the array returned by parse_args is NULL-terminated.
01885     */
01886    args[0] = (char *)e;
01887 
01888    retval = e->handler(e, CLI_HANDLER, &a);
01889 
01890    if (retval == CLI_SHOWUSAGE) {
01891       ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
01892       AST_RWLIST_RDLOCK(&helpers);
01893       if (e->deprecated)
01894          ast_cli(fd, "The '%s' command is deprecated and will be removed in a future release. Please use '%s' instead.\n", e->_full_cmd, e->_deprecated_by);
01895       AST_RWLIST_UNLOCK(&helpers);
01896    } else {
01897       if (retval == CLI_FAILURE)
01898          ast_cli(fd, "Command '%s' failed.\n", s);
01899       AST_RWLIST_RDLOCK(&helpers);
01900       if (e->deprecated == 1) {
01901          ast_cli(fd, "The '%s' command is deprecated and will be removed in a future release. Please use '%s' instead.\n", e->_full_cmd, e->_deprecated_by);
01902          e->deprecated = 2;
01903       }
01904       AST_RWLIST_UNLOCK(&helpers);
01905    }
01906    ast_atomic_fetchadd_int(&e->inuse, -1);
01907 done:
01908    ast_free(dup);
01909    return 0;
01910 }

int ast_cli_command_multiple ( int  fd,
size_t  size,
const char *  s 
)

Executes multiple CLI commands Interpret strings separated by NULL and execute each one, sending output to fd.

Parameters:
fd pipe
size is the total size of the string
s incoming string
Return values:
number of commands executed

Definition at line 1912 of file cli.c.

References ast_cli_command().

Referenced by netconsole().

01913 {
01914    char cmd[512];
01915    int x, y = 0, count = 0;
01916 
01917    for (x = 0; x < size; x++) {
01918       cmd[y] = s[x];
01919       y++;
01920       if (s[x] == '\0') {
01921          ast_cli_command(fd, cmd);
01922          y = 0;
01923          count++;
01924       }
01925    }
01926    return count;
01927 }

char* ast_cli_complete ( const char *  word,
char *const   choices[],
int  pos 
)

Helper function to generate cli entries from a NULL-terminated array. Returns the n-th matching entry from the array, or NULL if not found. Can be used to implement generate() for static entries as below (in this example we complete the word in position 2):

    char *my_generate(const char *line, const char *word, int pos, int n)
    {
        static char *choices = { "one", "two", "three", NULL };
   if (pos == 2)
         return ast_cli_complete(word, choices, n);
   else
      return NULL;
    }

Definition at line 1091 of file cli.c.

References ast_strdup, ast_strlen_zero(), and len().

Referenced by complete_meetmecmd(), handle_cli_devstate_change(), handle_orig(), and handle_show_applications().

01092 {
01093    int i, which = 0, len;
01094    len = ast_strlen_zero(word) ? 0 : strlen(word);
01095 
01096    for (i = 0; choices[i]; i++) {
01097       if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state)
01098          return ast_strdup(choices[i]);
01099    }
01100    return NULL;
01101 }

char** ast_cli_completion_matches ( const char *  ,
const char *   
)

Generates a NULL-terminated array of strings that 1) begin with the string in the second parameter, and 2) are valid in a command after the string in the first parameter.

The first entry (offset 0) of the result is the longest common substring in the results, useful to extend the string that has been completed. Subsequent entries are all possible values, followed by a NULL. All strings and the array itself are malloc'ed and must be freed by the caller.

Definition at line 1710 of file cli.c.

References ast_cli_generator(), ast_copy_string(), ast_malloc, and ast_realloc.

Referenced by cli_complete(), and handle_commandmatchesarray().

01711 {
01712    char **match_list = NULL, *retstr, *prevstr;
01713    size_t match_list_len, max_equal, which, i;
01714    int matches = 0;
01715 
01716    /* leave entry 0 free for the longest common substring */
01717    match_list_len = 1;
01718    while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
01719       if (matches + 1 >= match_list_len) {
01720          match_list_len <<= 1;
01721          if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(*match_list))))
01722             return NULL;
01723       }
01724       match_list[++matches] = retstr;
01725    }
01726 
01727    if (!match_list)
01728       return match_list; /* NULL */
01729 
01730    /* Find the longest substring that is common to all results
01731     * (it is a candidate for completion), and store a copy in entry 0.
01732     */
01733    prevstr = match_list[1];
01734    max_equal = strlen(prevstr);
01735    for (which = 2; which <= matches; which++) {
01736       for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
01737          continue;
01738       max_equal = i;
01739    }
01740 
01741    if (!(retstr = ast_malloc(max_equal + 1)))
01742       return NULL;
01743    
01744    ast_copy_string(retstr, match_list[1], max_equal + 1);
01745    match_list[0] = retstr;
01746 
01747    /* ensure that the array is NULL terminated */
01748    if (matches + 1 >= match_list_len) {
01749       if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list))))
01750          return NULL;
01751    }
01752    match_list[matches + 1] = NULL;
01753 
01754    return match_list;
01755 }

char* ast_cli_generator ( const char *  ,
const char *  ,
int   
)

Readline madness Useful for readline, that's about it.

Return values:
0 on success
-1 on failure

Definition at line 1852 of file cli.c.

References __ast_cli_generator().

Referenced by ast_cli_completion_matches(), and ast_cli_generatornummatches().

01853 {
01854    return __ast_cli_generator(text, word, state, 1);
01855 }

int ast_cli_generatornummatches ( const char *  text,
const char *  word 
)

Return the number of unique matches for the generator.

Definition at line 1693 of file cli.c.

References ast_cli_generator(), ast_free, and buf.

Referenced by handle_commandnummatches().

01694 {
01695    int matches = 0, i = 0;
01696    char *buf = NULL, *oldbuf = NULL;
01697 
01698    while ((buf = ast_cli_generator(text, word, i++))) {
01699       if (!oldbuf || strcmp(buf,oldbuf))
01700          matches++;
01701       if (oldbuf)
01702          ast_free(oldbuf);
01703       oldbuf = buf;
01704    }
01705    if (oldbuf)
01706       ast_free(oldbuf);
01707    return matches;
01708 }

int ast_cli_register ( struct ast_cli_entry e  ) 

Registers a command or an array of commands.

Parameters:
e which cli entry to register. Register your own command
Return values:
0 on success
-1 on failure

Definition at line 1519 of file cli.c.

References __ast_cli_register().

Referenced by ast_cdr_engine_init(), ast_cli_register_multiple(), dnsmgr_init(), do_reload(), and load_module().

01520 {
01521    return __ast_cli_register(e, NULL);
01522 }

int ast_cli_register_multiple ( struct ast_cli_entry e,
int  len 
)

Register multiple commands.

Parameters:
e pointer to first cli entry to register
len number of entries to register

Definition at line 1527 of file cli.c.

References ast_cli_register().

Referenced by __ast_register_translator(), __init_manager(), ast_builtins_init(), ast_channels_init(), ast_features_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_rtp_init(), ast_udptl_init(), ast_utils_init(), astdb_init(), astobj2_init(), crypto_init(), iax_provision_init(), init_framer(), init_logger(), load_module(), load_pbx(), main(), and register_config_cli().

01528 {
01529    int i, res = 0;
01530 
01531    for (i = 0; i < len; i++)
01532       res |= ast_cli_register(e + i);
01533 
01534    return res;
01535 }

int ast_cli_unregister ( struct ast_cli_entry e  ) 

Unregisters a command or an array of commands.

Parameters:
e which cli entry to unregister Unregister your own command. You must pass a completed ast_cli_entry structure
Returns:
0

Definition at line 1513 of file cli.c.

References __ast_cli_unregister().

Referenced by ast_cli_unregister_multiple(), do_reload(), load_module(), and unload_module().

01514 {
01515    return __ast_cli_unregister(e, NULL);
01516 }

int ast_cli_unregister_multiple ( struct ast_cli_entry e,
int  len 
)

Unregister multiple commands.

Parameters:
e pointer to first cli entry to unregister
len number of entries to unregister

Definition at line 1537 of file cli.c.

References ast_cli_unregister().

Referenced by __unload_module(), iax_provision_unload(), load_module(), and unload_module().

01538 {
01539    int i, res = 0;
01540 
01541    for (i = 0; i < len; i++)
01542       res |= ast_cli_unregister(e + i);
01543 
01544    return res;
01545 }

char* ast_complete_channels ( const char *  line,
const char *  word,
int  pos,
int  state,
int  rpos 
)

Command completion for the list of active channels.

This can be called from a CLI command completion function that wants to complete from the list of active channels. 'rpos' is the required position in the command. This function will return NULL immediately if 'rpos' is not the same as the current position, 'pos'.

Definition at line 1103 of file cli.c.

References ast_channel_unlock, ast_channel_walk_locked(), ast_strdup, and ast_channel::name.

Referenced by complete_ch(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_core_set_debug_channel(), handle_set_chanvar(), handle_showchan(), and handle_softhangup().

01104 {
01105    struct ast_channel *c = NULL;
01106    int which = 0;
01107    int wordlen;
01108    char notfound = '\0';
01109    char *ret = &notfound; /* so NULL can break the loop */
01110 
01111    if (pos != rpos)
01112       return NULL;
01113 
01114    wordlen = strlen(word); 
01115 
01116    while (ret == &notfound && (c = ast_channel_walk_locked(c))) {
01117       if (!strncasecmp(word, c->name, wordlen) && ++which > state)
01118          ret = ast_strdup(c->name);
01119       ast_channel_unlock(c);
01120    }
01121    return ret == &notfound ? NULL : ret;
01122 }

unsigned int ast_debug_get_by_file ( const char *  file  ) 

Get the debug level for a file.

  • file the filename
    Returns:
    the debug level

Definition at line 86 of file cli.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_debug_file::filename, and ast_debug_file::level.

00087 {
00088    struct ast_debug_file *adf;
00089    unsigned int res = 0;
00090 
00091    AST_RWLIST_RDLOCK(&debug_files);
00092    AST_LIST_TRAVERSE(&debug_files, adf, entry) {
00093       if (!strncasecmp(adf->filename, file, strlen(adf->filename))) {
00094          res = adf->level;
00095          break;
00096       }
00097    }
00098    AST_RWLIST_UNLOCK(&debug_files);
00099 
00100    return res;
00101 }

unsigned int ast_verbose_get_by_file ( const char *  file  ) 

Get the debug level for a file.

  • file the filename
    Returns:
    the debug level

Definition at line 103 of file cli.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_debug_file::filename, and ast_debug_file::level.

00104 {
00105    struct ast_debug_file *adf;
00106    unsigned int res = 0;
00107 
00108    AST_RWLIST_RDLOCK(&verbose_files);
00109    AST_LIST_TRAVERSE(&verbose_files, adf, entry) {
00110       if (!strncasecmp(adf->filename, file, strlen(file))) {
00111          res = adf->level;
00112          break;
00113       }
00114    }
00115    AST_RWLIST_UNLOCK(&verbose_files);
00116 
00117    return res;
00118 }

static struct ast_cli_entry* cli_next ( struct ast_cli_entry e  )  [static, read]

Definition at line 1256 of file cli.c.

References AST_LIST_FIRST, AST_LIST_NEXT, and ast_cli_entry::list.

Referenced by __ast_cli_generator(), find_cli(), and help1().

01257 {
01258    if (e) {
01259       return AST_LIST_NEXT(e, list);
01260    } else {
01261       return AST_LIST_FIRST(&helpers);
01262    }
01263 }

static char* complete_fn ( const char *  word,
int  state 
) [static]

Definition at line 122 of file cli.c.

References ast_config_AST_MODULE_DIR, ast_copy_string(), ast_strdup, and free.

Referenced by handle_load().

00123 {
00124    char *c, *d;
00125    char filename[PATH_MAX];
00126 
00127    if (word[0] == '/')
00128       ast_copy_string(filename, word, sizeof(filename));
00129    else
00130       snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word);
00131 
00132    c = d = filename_completion_function(filename, state);
00133    
00134    if (c && word[0] != '/')
00135       c += (strlen(ast_config_AST_MODULE_DIR) + 1);
00136    if (c)
00137       c = ast_strdup(c);
00138 
00139    free(d);
00140    
00141    return c;
00142 }

static char* find_best ( char *  argv[]  )  [static]

Definition at line 1395 of file cli.c.

References ast_join(), AST_MAX_CMD_LEN, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and find_cli().

Referenced by ast_cli_command(), ring_one(), store_next_lin(), and store_next_rr().

01396 {
01397    static char cmdline[80];
01398    int x;
01399    /* See how close we get, then print the candidate */
01400    char *myargv[AST_MAX_CMD_LEN];
01401    for (x=0;x<AST_MAX_CMD_LEN;x++)
01402       myargv[x]=NULL;
01403    AST_RWLIST_RDLOCK(&helpers);
01404    for (x=0;argv[x];x++) {
01405       myargv[x] = argv[x];
01406       if (!find_cli(myargv, -1))
01407          break;
01408    }
01409    AST_RWLIST_UNLOCK(&helpers);
01410    ast_join(cmdline, sizeof(cmdline), myargv);
01411    return cmdline;
01412 }

static struct ast_cli_entry* find_cli ( char *const   cmds[],
int  match_type 
) [static, read]

locate a cli command in the 'helpers' list (which must be locked). exact has 3 values: 0 returns if the search key is equal or longer than the entry. note that trailing optional arguments are skipped. -1 true if the mismatch is on the last word XXX not true! 1 true only on complete, exact match.

The search compares word by word taking care of regexps in e->cmda

Definition at line 1352 of file cli.c.

References ast_strlen_zero(), cli_next(), ast_cli_entry::cmda, and word_match().

Referenced by __ast_cli_register(), ast_cli_command(), find_best(), and handle_help().

01353 {
01354    int matchlen = -1;   /* length of longest match so far */
01355    struct ast_cli_entry *cand = NULL, *e=NULL;
01356 
01357    while ( (e = cli_next(e)) ) {
01358       /* word-by word regexp comparison */
01359       char * const *src = cmds;
01360       char * const *dst = e->cmda;
01361       int n = 0;
01362       for (;; dst++, src += n) {
01363          n = word_match(*src, *dst);
01364          if (n < 0)
01365             break;
01366       }
01367       if (ast_strlen_zero(*dst) || ((*dst)[0] == '[' && ast_strlen_zero(dst[1]))) {
01368          /* no more words in 'e' */
01369          if (ast_strlen_zero(*src)) /* exact match, cannot do better */
01370             break;
01371          /* Here, cmds has more words than the entry 'e' */
01372          if (match_type != 0) /* but we look for almost exact match... */
01373             continue;   /* so we skip this one. */
01374          /* otherwise we like it (case 0) */
01375       } else { /* still words in 'e' */
01376          if (ast_strlen_zero(*src))
01377             continue; /* cmds is shorter than 'e', not good */
01378          /* Here we have leftover words in cmds and 'e',
01379           * but there is a mismatch. We only accept this one if match_type == -1
01380           * and this is the last word for both.
01381           */
01382          if (match_type != -1 || !ast_strlen_zero(src[1]) ||
01383              !ast_strlen_zero(dst[1])) /* not the one we look for */
01384             continue;
01385          /* good, we are in case match_type == -1 and mismatch on last word */
01386       }
01387       if (src - cmds > matchlen) {  /* remember the candidate */
01388          matchlen = src - cmds;
01389          cand = e;
01390       }
01391    }
01392    return e ? e : cand;
01393 }

static struct ast_debug_file* find_debug_file ( const char *  fn,
unsigned int  debug 
) [static, read]

Find the debug or verbose file setting.

  • debug 1 for debug, 0 for verbose

Definition at line 224 of file cli.c.

References AST_LIST_TRAVERSE, and ast_debug_file::filename.

Referenced by handle_verbose().

00225 {
00226    struct ast_debug_file *df = NULL;
00227    struct debug_file_list *dfl = debug ? &debug_files : &verbose_files;
00228 
00229    AST_LIST_TRAVERSE(dfl, df, entry) {
00230       if (!strcasecmp(df->filename, fn))
00231          break;
00232    }
00233 
00234    return df;
00235 }

static char* group_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1124 of file cli.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_app_group_list_head(), ast_app_group_list_rdlock(), ast_app_group_list_unlock(), ast_cli(), AST_LIST_NEXT, ast_strlen_zero(), ast_group_info::category, ast_group_info::chan, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ESS, ast_cli_args::fd, FORMAT_STRING, ast_group_info::group, ast_group_info::group_list, ast_channel::name, and ast_cli_entry::usage.

01125 {
01126 #define FORMAT_STRING  "%-25s  %-20s  %-20s\n"
01127 
01128    struct ast_group_info *gi = NULL;
01129    int numchans = 0;
01130    regex_t regexbuf;
01131    int havepattern = 0;
01132 
01133    switch (cmd) {
01134    case CLI_INIT:
01135       e->command = "group show channels";
01136       e->usage = 
01137          "Usage: group show channels [pattern]\n"
01138          "       Lists all currently active channels with channel group(s) specified.\n"
01139          "       Optional regular expression pattern is matched to group names for each\n"
01140          "       channel.\n";
01141       return NULL;
01142    case CLI_GENERATE:
01143       return NULL;
01144    }
01145 
01146    if (a->argc < 3 || a->argc > 4)
01147       return CLI_SHOWUSAGE;
01148    
01149    if (a->argc == 4) {
01150       if (regcomp(&regexbuf, a->argv[3], REG_EXTENDED | REG_NOSUB))
01151          return CLI_SHOWUSAGE;
01152       havepattern = 1;
01153    }
01154 
01155    ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category");
01156 
01157    ast_app_group_list_rdlock();
01158    
01159    gi = ast_app_group_list_head();
01160    while (gi) {
01161       if (!havepattern || !regexec(&regexbuf, gi->group, 0, NULL, 0)) {
01162          ast_cli(a->fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category));
01163          numchans++;
01164       }
01165       gi = AST_LIST_NEXT(gi, group_list);
01166    }
01167    
01168    ast_app_group_list_unlock();
01169    
01170    if (havepattern)
01171       regfree(&regexbuf);
01172 
01173    ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
01174    return CLI_SUCCESS;
01175 #undef FORMAT_STRING
01176 }

static char* handle_chanlist ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 631 of file cli.c.

References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, ast_channel::appl, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_bridged_channel(), ast_channel_unlock, ast_channel_walk_locked(), ast_cli(), ast_processed_calls(), ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, CONCISE_FORMAT_STRING, ast_channel::context, ast_channel::data, ESS, ast_channel::exten, ast_cli_args::fd, FORMAT_STRING, FORMAT_STRING2, ast_channel::name, option_maxcalls, ast_channel::priority, S_OR, ast_cdr::start, ast_channel::uniqueid, ast_cli_entry::usage, VERBOSE_FORMAT_STRING, and VERBOSE_FORMAT_STRING2.

00632 {
00633 #define FORMAT_STRING  "%-20.20s %-20.20s %-7.7s %-30.30s\n"
00634 #define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n"
00635 #define CONCISE_FORMAT_STRING  "%s!%s!%s!%d!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
00636 #define VERBOSE_FORMAT_STRING  "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"
00637 #define VERBOSE_FORMAT_STRING2 "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"
00638 
00639    struct ast_channel *c = NULL;
00640    int numchans = 0, concise = 0, verbose = 0, count = 0;
00641    int fd, argc;
00642    char **argv;
00643 
00644    switch (cmd) {
00645    case CLI_INIT:
00646       e->command = "core show channels [concise|verbose|count]";
00647       e->usage =
00648          "Usage: core show channels [concise|verbose|count]\n"
00649          "       Lists currently defined channels and some information about them. If\n"
00650          "       'concise' is specified, the format is abridged and in a more easily\n"
00651          "       machine parsable format. If 'verbose' is specified, the output includes\n"
00652          "       more and longer fields. If 'count' is specified only the channel and call\n"
00653          "       count is output.\n"
00654          "  The 'concise' option is deprecated and will be removed from future versions\n"
00655          "  of Asterisk.\n";
00656       return NULL;
00657 
00658    case CLI_GENERATE:
00659       return NULL;
00660    }
00661    fd = a->fd;
00662    argc = a->argc;
00663    argv = a->argv;
00664 
00665    if (a->argc == e->args) {
00666       if (!strcasecmp(argv[e->args-1],"concise"))
00667          concise = 1;
00668       else if (!strcasecmp(argv[e->args-1],"verbose"))
00669          verbose = 1;
00670       else if (!strcasecmp(argv[e->args-1],"count"))
00671          count = 1;
00672       else
00673          return CLI_SHOWUSAGE;
00674    } else if (a->argc != e->args - 1)
00675       return CLI_SHOWUSAGE;
00676 
00677    if (!count) {
00678       if (!concise && !verbose)
00679          ast_cli(fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)");
00680       else if (verbose)
00681          ast_cli(fd, VERBOSE_FORMAT_STRING2, "Channel", "Context", "Extension", "Priority", "State", "Application", "Data", 
00682             "CallerID", "Duration", "Accountcode", "BridgedTo");
00683    }
00684 
00685    while ((c = ast_channel_walk_locked(c)) != NULL) {
00686       struct ast_channel *bc = ast_bridged_channel(c);
00687       char durbuf[10] = "-";
00688 
00689       if (!count) {
00690          if ((concise || verbose)  && c->cdr && !ast_tvzero(c->cdr->start)) {
00691             int duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
00692             if (verbose) {
00693                int durh = duration / 3600;
00694                int durm = (duration % 3600) / 60;
00695                int durs = duration % 60;
00696                snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
00697             } else {
00698                snprintf(durbuf, sizeof(durbuf), "%d", duration);
00699             }           
00700          }
00701          if (concise) {
00702             ast_cli(fd, CONCISE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
00703                c->appl ? c->appl : "(None)",
00704                S_OR(c->data, ""),   /* XXX different from verbose ? */
00705                S_OR(c->cid.cid_num, ""),
00706                S_OR(c->accountcode, ""),
00707                c->amaflags, 
00708                durbuf,
00709                bc ? bc->name : "(None)",
00710                c->uniqueid);
00711          } else if (verbose) {
00712             ast_cli(fd, VERBOSE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
00713                c->appl ? c->appl : "(None)",
00714                c->data ? S_OR(c->data, "(Empty)" ): "(None)",
00715                S_OR(c->cid.cid_num, ""),
00716                durbuf,
00717                S_OR(c->accountcode, ""),
00718                bc ? bc->name : "(None)");
00719          } else {
00720             char locbuf[40] = "(None)";
00721             char appdata[40] = "(None)";
00722             
00723             if (!ast_strlen_zero(c->context) && !ast_strlen_zero(c->exten)) 
00724                snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority);
00725             if (c->appl)
00726                snprintf(appdata, sizeof(appdata), "%s(%s)", c->appl, S_OR(c->data, ""));
00727             ast_cli(fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata);
00728          }
00729       }
00730       numchans++;
00731       ast_channel_unlock(c);
00732    }
00733    if (!concise) {
00734       ast_cli(fd, "%d active channel%s\n", numchans, ESS(numchans));
00735       if (option_maxcalls)
00736          ast_cli(fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
00737             ast_active_calls(), option_maxcalls, ESS(ast_active_calls()),
00738             ((double)ast_active_calls() / (double)option_maxcalls) * 100.0);
00739       else
00740          ast_cli(fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
00741 
00742       ast_cli(fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
00743    }
00744    return CLI_SUCCESS;
00745    
00746 #undef FORMAT_STRING
00747 #undef FORMAT_STRING2
00748 #undef CONCISE_FORMAT_STRING
00749 #undef VERBOSE_FORMAT_STRING
00750 #undef VERBOSE_FORMAT_STRING2
00751 }

static char* handle_commandcomplete ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 863 of file cli.c.

References __ast_cli_generator(), ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_free, buf, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

00864 {
00865    char *buf;
00866    switch (cmd) {
00867    case CLI_INIT:
00868       e->command = "_command complete";
00869       e->usage = 
00870          "Usage: _command complete \"<line>\" text state\n"
00871          "       This function is used internally to help with command completion and should.\n"
00872          "       never be called by the user directly.\n";
00873       return NULL;
00874    case CLI_GENERATE:
00875       return NULL;
00876    }
00877    if (a->argc != 5)
00878       return CLI_SHOWUSAGE;
00879    buf = __ast_cli_generator(a->argv[2], a->argv[3], atoi(a->argv[4]), 0);
00880    if (buf) {
00881       ast_cli(a->fd, "%s", buf);
00882       ast_free(buf);
00883    } else
00884       ast_cli(a->fd, "NULL\n");
00885    return CLI_SUCCESS;
00886 }

static char* handle_commandmatchesarray ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 782 of file cli.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_COMPLETE_EOF, ast_cli_completion_matches(), ast_free, ast_malloc, ast_realloc, buf, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, len(), and ast_cli_entry::usage.

00783 {
00784    char *buf, *obuf;
00785    int buflen = 2048;
00786    int len = 0;
00787    char **matches;
00788    int x, matchlen;
00789    
00790    switch (cmd) {
00791    case CLI_INIT:
00792       e->command = "_command matchesarray";
00793       e->usage = 
00794          "Usage: _command matchesarray \"<line>\" text \n"
00795          "       This function is used internally to help with command completion and should.\n"
00796          "       never be called by the user directly.\n";
00797       return NULL;
00798    case CLI_GENERATE:
00799       return NULL;
00800    }
00801 
00802    if (a->argc != 4)
00803       return CLI_SHOWUSAGE;
00804    if (!(buf = ast_malloc(buflen)))
00805       return CLI_FAILURE;
00806    buf[len] = '\0';
00807    matches = ast_cli_completion_matches(a->argv[2], a->argv[3]);
00808    if (matches) {
00809       for (x=0; matches[x]; x++) {
00810          matchlen = strlen(matches[x]) + 1;
00811          if (len + matchlen >= buflen) {
00812             buflen += matchlen * 3;
00813             obuf = buf;
00814             if (!(buf = ast_realloc(obuf, buflen))) 
00815                /* Memory allocation failure...  Just free old buffer and be done */
00816                ast_free(obuf);
00817          }
00818          if (buf)
00819             len += sprintf( buf + len, "%s ", matches[x]);
00820          ast_free(matches[x]);
00821          matches[x] = NULL;
00822       }
00823       ast_free(matches);
00824    }
00825 
00826    if (buf) {
00827       ast_cli(a->fd, "%s%s",buf, AST_CLI_COMPLETE_EOF);
00828       ast_free(buf);
00829    } else
00830       ast_cli(a->fd, "NULL\n");
00831 
00832    return CLI_SUCCESS;
00833 }

static char* handle_commandnummatches ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 837 of file cli.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_generatornummatches(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

00838 {
00839    int matches = 0;
00840 
00841    switch (cmd) {
00842    case CLI_INIT:
00843       e->command = "_command nummatches";
00844       e->usage = 
00845          "Usage: _command nummatches \"<line>\" text \n"
00846          "       This function is used internally to help with command completion and should.\n"
00847          "       never be called by the user directly.\n";
00848       return NULL;
00849    case CLI_GENERATE:
00850       return NULL;
00851    }
00852 
00853    if (a->argc != 4)
00854       return CLI_SHOWUSAGE;
00855 
00856    matches = ast_cli_generatornummatches(a->argv[2], a->argv[3]);
00857 
00858    ast_cli(a->fd, "%d", matches);
00859 
00860    return CLI_SUCCESS;
00861 }

static char* handle_core_set_debug_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 888 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_unlock, ast_channel_walk_locked(), ast_cli(), ast_complete_channels(), ast_get_channel_by_name_locked(), ast_strdup, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEBUGCHAN_FLAG, ast_cli_args::fd, ast_channel::fin, ast_channel::fout, global_fin, global_fout, ast_cli_args::line, ast_cli_args::n, ast_channel::name, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

Referenced by handle_debugchan_deprecated(), and handle_nodebugchan_deprecated().

00889 {
00890    struct ast_channel *c = NULL;
00891    int is_all, is_off = 0;
00892 
00893    switch (cmd) {
00894    case CLI_INIT:
00895       e->command = "core set debug channel";
00896       e->usage =
00897          "Usage: core set debug channel <all|channel> [off]\n"
00898          "       Enables/disables debugging on all or on a specific channel.\n";
00899       return NULL;
00900 
00901    case CLI_GENERATE:
00902       /* XXX remember to handle the optional "off" */
00903       if (a->pos != e->args)
00904          return NULL;
00905       return a->n == 0 ? ast_strdup("all") : ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
00906    }
00907    /* 'core set debug channel {all|chan_id}' */
00908    if (a->argc == e->args + 2) {
00909       if (!strcasecmp(a->argv[e->args + 1], "off"))
00910          is_off = 1;
00911       else
00912          return CLI_SHOWUSAGE;
00913    } else if (a->argc != e->args + 1)
00914       return CLI_SHOWUSAGE;
00915 
00916    is_all = !strcasecmp("all", a->argv[e->args]);
00917    if (is_all) {
00918       if (is_off) {
00919          global_fin &= ~DEBUGCHAN_FLAG;
00920          global_fout &= ~DEBUGCHAN_FLAG;
00921       } else {
00922          global_fin |= DEBUGCHAN_FLAG;
00923          global_fout |= DEBUGCHAN_FLAG;
00924       }
00925       c = ast_channel_walk_locked(NULL);
00926    } else {
00927       c = ast_get_channel_by_name_locked(a->argv[e->args]);
00928       if (c == NULL)
00929          ast_cli(a->fd, "No such channel %s\n", a->argv[e->args]);
00930    }
00931    while (c) {
00932       if (!(c->fin & DEBUGCHAN_FLAG) || !(c->fout & DEBUGCHAN_FLAG)) {
00933          if (is_off) {
00934             c->fin &= ~DEBUGCHAN_FLAG;
00935             c->fout &= ~DEBUGCHAN_FLAG;
00936          } else {
00937             c->fin |= DEBUGCHAN_FLAG;
00938             c->fout |= DEBUGCHAN_FLAG;
00939          }
00940          ast_cli(a->fd, "Debugging %s on channel %s\n", is_off ? "disabled" : "enabled", c->name);
00941       }
00942       ast_channel_unlock(c);
00943       if (!is_all)
00944          break;
00945       c = ast_channel_walk_locked(c);
00946    }
00947    ast_cli(a->fd, "Debugging on new channels is %s\n", is_off ? "disabled" : "enabled");
00948    return CLI_SUCCESS;
00949 }

static char* handle_debugchan_deprecated ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 951 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, and handle_core_set_debug_channel().

00952 {
00953    char *res;
00954 
00955    if (cmd == CLI_HANDLER && a->argc != e->args + 1)
00956       return CLI_SHOWUSAGE;
00957    res = handle_core_set_debug_channel(e, cmd, a);
00958    if (cmd == CLI_INIT)
00959       e->command = "debug channel";
00960    return res;
00961 }

static char * handle_help ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1583 of file cli.c.

References __ast_cli_generator(), ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_join(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, find_cli(), help1(), ast_cli_args::line, ast_cli_args::n, ast_cli_entry::usage, and ast_cli_args::word.

01584 {
01585    char fullcmd[80];
01586    struct ast_cli_entry *my_e;
01587    char *res = CLI_SUCCESS;
01588 
01589    if (cmd == CLI_INIT) {
01590       e->command = "help";
01591       e->usage =
01592          "Usage: help [topic]\n"
01593          "       When called with a topic as an argument, displays usage\n"
01594          "       information on the given command. If called without a\n"
01595          "       topic, it provides a list of commands.\n";
01596       return NULL;
01597 
01598    } else if (cmd == CLI_GENERATE) {
01599       /* skip first 4 or 5 chars, "help " */
01600       int l = strlen(a->line);
01601 
01602       if (l > 5)
01603          l = 5;
01604       /* XXX watch out, should stop to the non-generator parts */
01605       return __ast_cli_generator(a->line + l, a->word, a->n, 0);
01606    }
01607    if (a->argc == 1)
01608       return help1(a->fd, NULL, 0);
01609 
01610    AST_RWLIST_RDLOCK(&helpers);
01611    my_e = find_cli(a->argv + 1, 1); /* try exact match first */
01612    if (!my_e) {
01613       res = help1(a->fd, a->argv + 1, 1 /* locked */);
01614       AST_RWLIST_UNLOCK(&helpers);
01615       return res;
01616    }
01617    if (my_e->usage)
01618       ast_cli(a->fd, "%s", my_e->usage);
01619    else {
01620       ast_join(fullcmd, sizeof(fullcmd), a->argv+1);
01621       ast_cli(a->fd, "No help text available for '%s'.\n", fullcmd);
01622    }
01623    AST_RWLIST_UNLOCK(&helpers);
01624    return res;
01625 }

static char* handle_load ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 144 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_load_resource(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_fn(), ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

Referenced by handle_load_deprecated().

00145 {
00146    /* "module load <mod>" */
00147    switch (cmd) {
00148    case CLI_INIT:
00149       e->command = "module load";
00150       e->usage =
00151          "Usage: module load <module name>\n"
00152          "       Loads the specified module into Asterisk.\n";
00153       return NULL;
00154 
00155    case CLI_GENERATE:
00156       if (a->pos != e->args)
00157          return NULL;
00158       return complete_fn(a->word, a->n);
00159    }
00160    if (a->argc != e->args + 1)
00161       return CLI_SHOWUSAGE;
00162    if (ast_load_resource(a->argv[e->args])) {
00163       ast_cli(a->fd, "Unable to load module %s\n", a->argv[e->args]);
00164       return CLI_FAILURE;
00165    }
00166    return CLI_SUCCESS;
00167 }

static char* handle_load_deprecated ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 169 of file cli.c.

References CLI_INIT, ast_cli_entry::command, and handle_load().

00170 {
00171    char *res = handle_load(e, cmd, a);
00172    if (cmd == CLI_INIT)
00173       e->command = "load";
00174    return res;
00175 }

static char* handle_logger_mute ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 359 of file cli.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_console_toggle_mute(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

00360 {
00361    switch (cmd) {
00362    case CLI_INIT:
00363       e->command = "logger mute";
00364       e->usage = 
00365          "Usage: logger mute\n"
00366          "       Disables logging output to the current console, making it possible to\n"
00367          "       gather information without being disturbed by scrolling lines.\n";
00368       return NULL;
00369    case CLI_GENERATE:
00370       return NULL;
00371    }
00372 
00373    if (a->argc < 2 || a->argc > 3)
00374       return CLI_SHOWUSAGE;
00375 
00376    if (a->argc == 3 && !strcasecmp(a->argv[2], "silent"))
00377       ast_console_toggle_mute(a->fd, 1);
00378    else
00379       ast_console_toggle_mute(a->fd, 0);
00380 
00381    return CLI_SUCCESS;
00382 }

static char* handle_modlist ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 537 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_module_helper(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_module_list(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, climodentryfd, climodentrylock, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, MODLIST_FORMAT2, modlist_modentry(), ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

00538 {
00539    char *like;
00540 
00541    switch (cmd) {
00542    case CLI_INIT:
00543       e->command = "module show [like]";
00544       e->usage =
00545          "Usage: module show [like keyword]\n"
00546          "       Shows Asterisk modules currently in use, and usage statistics.\n";
00547       return NULL;
00548 
00549    case CLI_GENERATE:
00550       if (a->pos == e->args)
00551          return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0);
00552       else
00553          return NULL;
00554    }
00555    /* all the above return, so we proceed with the handler.
00556     * we are guaranteed to have argc >= e->args
00557     */
00558    if (a->argc == e->args - 1)
00559       like = "";
00560    else if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args-1], "like") )
00561       like = a->argv[e->args];
00562    else
00563       return CLI_SHOWUSAGE;
00564       
00565    ast_mutex_lock(&climodentrylock);
00566    climodentryfd = a->fd; /* global, protected by climodentrylock */
00567    ast_cli(a->fd, MODLIST_FORMAT2, "Module", "Description", "Use Count");
00568    ast_cli(a->fd,"%d modules loaded\n", ast_update_module_list(modlist_modentry, like));
00569    climodentryfd = -1;
00570    ast_mutex_unlock(&climodentrylock);
00571    return CLI_SUCCESS;
00572 }

static char* handle_nodebugchan_deprecated ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 963 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, and handle_core_set_debug_channel().

00964 {
00965    char *res;
00966    if (cmd == CLI_HANDLER) {
00967       if (a->argc != e->args + 1)
00968          return CLI_SHOWUSAGE;
00969       /* pretend we have an extra "off" at the end. We can do this as the array
00970        * is NULL terminated so we overwrite that entry.
00971        */
00972       a->argv[e->args+1] = "off";
00973       a->argc++;
00974    }
00975    res = handle_core_set_debug_channel(e, cmd, a);
00976    if (cmd == CLI_INIT)
00977       e->command = "no debug channel";
00978    return res;
00979 }

static char* handle_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 177 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_module_helper(), ast_module_reload(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

Referenced by handle_reload_deprecated().

00178 {
00179    int x;
00180 
00181    switch (cmd) {
00182    case CLI_INIT:
00183       e->command = "module reload";
00184       e->usage =
00185          "Usage: module reload [module ...]\n"
00186          "       Reloads configuration files for all listed modules which support\n"
00187          "       reloading, or for all supported modules if none are listed.\n";
00188       return NULL;
00189 
00190    case CLI_GENERATE:
00191       return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 1);
00192    }
00193    if (a->argc == e->args) {
00194       ast_module_reload(NULL);
00195       return CLI_SUCCESS;
00196    }
00197    for (x = e->args; x < a->argc; x++) {
00198       int res = ast_module_reload(a->argv[x]);
00199       /* XXX reload has multiple error returns, including -1 on error and 2 on success */
00200       switch (res) {
00201       case 0:
00202          ast_cli(a->fd, "No such module '%s'\n", a->argv[x]);
00203          break;
00204       case 1:
00205          ast_cli(a->fd, "Module '%s' does not support reload\n", a->argv[x]);
00206          break;
00207       }
00208    }
00209    return CLI_SUCCESS;
00210 }

static char* handle_reload_deprecated ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 212 of file cli.c.

References CLI_INIT, ast_cli_entry::command, handle_reload(), and s.

00213 {
00214    char *s = handle_reload(e, cmd, a);
00215    if (cmd == CLI_INIT)    /* override command name */
00216       e->command = "reload";
00217    return s;
00218 }

static char* handle_showcalls ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 576 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_cli(), ast_processed_calls(), ast_startuptime, ast_strdup, ast_tvnow(), ast_tvsub(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, ESS, ast_cli_args::fd, ast_cli_args::n, option_maxcalls, ast_cli_args::pos, print_uptimestr(), RESULT_SUCCESS, and ast_cli_entry::usage.

00577 {
00578    struct timeval curtime = ast_tvnow();
00579    int showuptime, printsec;
00580 
00581    switch (cmd) {
00582    case CLI_INIT:
00583       e->command = "core show calls [uptime]";
00584       e->usage =
00585          "Usage: core show calls [uptime] [seconds]\n"
00586          "       Lists number of currently active calls and total number of calls\n"
00587          "       processed through PBX since last restart. If 'uptime' is specified\n"
00588          "       the system uptime is also displayed. If 'seconds' is specified in\n"
00589          "       addition to 'uptime', the system uptime is displayed in seconds.\n";
00590       return NULL;
00591 
00592    case CLI_GENERATE:
00593       if (a->pos != e->args)
00594          return NULL;
00595       return a->n == 0  ? ast_strdup("seconds") : NULL;
00596    }
00597 
00598    /* regular handler */
00599    if (a->argc >= e->args && !strcasecmp(a->argv[e->args-1],"uptime")) {
00600       showuptime = 1;
00601 
00602       if (a->argc == e->args+1 && !strcasecmp(a->argv[e->args],"seconds"))
00603          printsec = 1;
00604       else if (a->argc == e->args)
00605          printsec = 0;
00606       else
00607          return CLI_SHOWUSAGE;
00608    } else if (a->argc == e->args-1) {
00609       showuptime = 0;
00610       printsec = 0;
00611    } else
00612       return CLI_SHOWUSAGE;
00613 
00614    if (option_maxcalls) {
00615       ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
00616          ast_active_calls(), option_maxcalls, ESS(ast_active_calls()),
00617          ((double)ast_active_calls() / (double)option_maxcalls) * 100.0);
00618    } else {
00619       ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
00620    }
00621    
00622    ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
00623 
00624    if (ast_startuptime.tv_sec && showuptime) {
00625       print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec);
00626    }
00627 
00628    return RESULT_SUCCESS;
00629 }

static char* handle_showchan ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 981 of file cli.c.

References ast_channel::_bridge, ast_channel::_state, ast_channel::appl, ast_cli_args::argc, ast_cli_args::argv, ast_bridged_channel(), ast_cdr_serialize_variables(), ast_channel_unlock, ast_cli(), ast_complete_channels(), AST_FLAG_BLOCKING, ast_get_channel_by_name_locked(), ast_getformatname_multiple(), ast_state2str(), ast_str_alloca, ast_test_flag, ast_tvnow(), ast_channel::blockproc, ast_channel::callgroup, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel::context, ast_channel::data, DEBUGCHAN_FLAG, ast_channel::exten, ast_cli_args::fd, ast_channel::fds, ast_channel::fin, ast_channel::fout, ast_channel::language, ast_cli_args::line, ast_cli_args::n, name, ast_channel::name, ast_channel::nativeformats, pbx_builtin_serialize_variables(), ast_channel::pickupgroup, ast_cli_args::pos, ast_channel::priority, ast_channel::readformat, ast_channel::readtrans, ast_channel::rings, S_OR, sec, ast_cdr::start, ast_str::str, ast_channel::tech, ast_channel_tech::type, ast_channel::uniqueid, ast_cli_entry::usage, ast_channel::whentohangup, ast_cli_args::word, ast_channel::writeformat, and ast_channel::writetrans.

00982 {
00983    struct ast_channel *c=NULL;
00984    struct timeval now;
00985    struct ast_str *out = ast_str_alloca(2048);
00986    char cdrtime[256];
00987    char nf[256], wf[256], rf[256];
00988    long elapsed_seconds=0;
00989    int hour=0, min=0, sec=0;
00990 #ifdef CHANNEL_TRACE
00991    int trace_enabled;
00992 #endif
00993 
00994    switch (cmd) {
00995    case CLI_INIT:
00996       e->command = "core show channel";
00997       e->usage = 
00998          "Usage: core show channel <channel>\n"
00999          "       Shows lots of information about the specified channel.\n";
01000       return NULL;
01001    case CLI_GENERATE:
01002       return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
01003    }
01004    
01005    if (a->argc != 4)
01006       return CLI_SHOWUSAGE;
01007    now = ast_tvnow();
01008    c = ast_get_channel_by_name_locked(a->argv[3]);
01009    if (!c) {
01010       ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
01011       return CLI_SUCCESS;
01012    }
01013    if (c->cdr) {
01014       elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
01015       hour = elapsed_seconds / 3600;
01016       min = (elapsed_seconds % 3600) / 60;
01017       sec = elapsed_seconds % 60;
01018       snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
01019    } else
01020       strcpy(cdrtime, "N/A");
01021    ast_cli(a->fd, 
01022       " -- General --\n"
01023       "           Name: %s\n"
01024       "           Type: %s\n"
01025       "       UniqueID: %s\n"
01026       "      Caller ID: %s\n"
01027       " Caller ID Name: %s\n"
01028       "    DNID Digits: %s\n"
01029       "       Language: %s\n"
01030       "          State: %s (%d)\n"
01031       "          Rings: %d\n"
01032       "  NativeFormats: %s\n"
01033       "    WriteFormat: %s\n"
01034       "     ReadFormat: %s\n"
01035       " WriteTranscode: %s\n"
01036       "  ReadTranscode: %s\n"
01037       "1st File Descriptor: %d\n"
01038       "      Frames in: %d%s\n"
01039       "     Frames out: %d%s\n"
01040       " Time to Hangup: %ld\n"
01041       "   Elapsed Time: %s\n"
01042       "  Direct Bridge: %s\n"
01043       "Indirect Bridge: %s\n"
01044       " --   PBX   --\n"
01045       "        Context: %s\n"
01046       "      Extension: %s\n"
01047       "       Priority: %d\n"
01048       "     Call Group: %llu\n"
01049       "   Pickup Group: %llu\n"
01050       "    Application: %s\n"
01051       "           Data: %s\n"
01052       "    Blocking in: %s\n",
01053       c->name, c->tech->type, c->uniqueid,
01054       S_OR(c->cid.cid_num, "(N/A)"),
01055       S_OR(c->cid.cid_name, "(N/A)"),
01056       S_OR(c->cid.cid_dnid, "(N/A)"), 
01057       c->language,   
01058       ast_state2str(c->_state), c->_state, c->rings, 
01059       ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats), 
01060       ast_getformatname_multiple(wf, sizeof(wf), c->writeformat), 
01061       ast_getformatname_multiple(rf, sizeof(rf), c->readformat),
01062       c->writetrans ? "Yes" : "No",
01063       c->readtrans ? "Yes" : "No",
01064       c->fds[0],
01065       c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
01066       c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
01067       (long)c->whentohangup,
01068       cdrtime, c->_bridge ? c->_bridge->name : "<none>", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "<none>", 
01069       c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ),
01070       ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),
01071       (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
01072    
01073    if (pbx_builtin_serialize_variables(c, &out))
01074       ast_cli(a->fd,"      Variables:\n%s\n", out->str);
01075    if (c->cdr && ast_cdr_serialize_variables(c->cdr, &out, '=', '\n', 1))
01076       ast_cli(a->fd,"  CDR Variables:\n%s\n", out->str);
01077 #ifdef CHANNEL_TRACE
01078    trace_enabled = ast_channel_trace_is_enabled(c);
01079    ast_cli(a->fd, "  Context Trace: %s\n", trace_enabled ? "Enabled" : "Disabled");
01080    if (trace_enabled && ast_channel_trace_serialize(c, &out))
01081       ast_cli(a->fd, "          Trace:\n%s\n", out->str);
01082 #endif
01083    ast_channel_unlock(c);
01084    return CLI_SUCCESS;
01085 }

static char* handle_showuptime ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 506 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_lastreloadtime, ast_startuptime, ast_tvnow(), ast_tvsub(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, print_uptimestr(), and ast_cli_entry::usage.

00507 {
00508    struct timeval curtime = ast_tvnow();
00509    int printsec;
00510 
00511    switch (cmd) {
00512    case CLI_INIT:
00513       e->command = "core show uptime [seconds]";
00514       e->usage =
00515          "Usage: core show uptime [seconds]\n"
00516          "       Shows Asterisk uptime information.\n"
00517          "       The seconds word returns the uptime in seconds only.\n";
00518       return NULL;
00519 
00520    case CLI_GENERATE:
00521       return NULL;
00522    }
00523    /* regular handler */
00524    if (a->argc == e->args && !strcasecmp(a->argv[e->args-1],"seconds"))
00525       printsec = 1;
00526    else if (a->argc == e->args-1)
00527       printsec = 0;
00528    else
00529       return CLI_SHOWUSAGE;
00530    if (ast_startuptime.tv_sec)
00531       print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec);
00532    if (ast_lastreloadtime.tv_sec)
00533       print_uptimestr(a->fd, ast_tvsub(curtime, ast_lastreloadtime), "Last reload", printsec);
00534    return CLI_SUCCESS;
00535 }

static char* handle_softhangup ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 753 of file cli.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_channel_unlock, ast_cli(), ast_complete_channels(), ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_channel::name, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

00754 {
00755    struct ast_channel *c=NULL;
00756 
00757    switch (cmd) {
00758    case CLI_INIT:
00759       e->command = "soft hangup";
00760       e->usage =
00761          "Usage: soft hangup <channel>\n"
00762          "       Request that a channel be hung up. The hangup takes effect\n"
00763          "       the next time the driver reads or writes from the channel\n";
00764       return NULL;
00765    case CLI_GENERATE:
00766       return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
00767    }
00768    if (a->argc != 3)
00769       return CLI_SHOWUSAGE;
00770    c = ast_get_channel_by_name_locked(a->argv[2]);
00771    if (c) {
00772       ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name);
00773       ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
00774       ast_channel_unlock(c);
00775    } else
00776       ast_cli(a->fd, "%s is not a known channel\n", a->argv[2]);
00777    return CLI_SUCCESS;
00778 }

static char* handle_unload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 384 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), AST_FORCE_FIRM, AST_FORCE_HARD, AST_FORCE_SOFT, ast_module_helper(), ast_unload_resource(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, s, ast_cli_entry::usage, and ast_cli_args::word.

Referenced by handle_unload_deprecated().

00385 {
00386    /* "module unload mod_1 [mod_2 .. mod_N]" */
00387    int x;
00388    int force = AST_FORCE_SOFT;
00389    char *s;
00390 
00391    switch (cmd) {
00392    case CLI_INIT:
00393       e->command = "module unload";
00394       e->usage =
00395          "Usage: module unload [-f|-h] <module_1> [<module_2> ... ]\n"
00396          "       Unloads the specified module from Asterisk. The -f\n"
00397          "       option causes the module to be unloaded even if it is\n"
00398          "       in use (may cause a crash) and the -h module causes the\n"
00399          "       module to be unloaded even if the module says it cannot, \n"
00400          "       which almost always will cause a crash.\n";
00401       return NULL;
00402 
00403    case CLI_GENERATE:
00404       return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0);
00405    }
00406    if (a->argc < e->args + 1)
00407       return CLI_SHOWUSAGE;
00408    x = e->args;   /* first argument */
00409    s = a->argv[x];
00410    if (s[0] == '-') {
00411       if (s[1] == 'f')
00412          force = AST_FORCE_FIRM;
00413       else if (s[1] == 'h')
00414          force = AST_FORCE_HARD;
00415       else
00416          return CLI_SHOWUSAGE;
00417       if (a->argc < e->args + 2) /* need at least one module name */
00418          return CLI_SHOWUSAGE;
00419       x++;  /* skip this argument */
00420    }
00421 
00422    for (; x < a->argc; x++) {
00423       if (ast_unload_resource(a->argv[x], force)) {
00424          ast_cli(a->fd, "Unable to unload resource %s\n", a->argv[x]);
00425          return CLI_FAILURE;
00426       }
00427    }
00428    return CLI_SUCCESS;
00429 }

static char* handle_unload_deprecated ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 431 of file cli.c.

References CLI_INIT, ast_cli_entry::command, and handle_unload().

00432 {
00433    char *res = handle_unload(e, cmd, a);
00434    if (cmd == CLI_INIT)
00435       e->command = "unload";  /* XXX override */
00436    return res;
00437 }

static char* handle_verbose ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 237 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_calloc, ast_clear_flag, ast_cli(), ast_free, AST_OPT_FLAG_DEBUG_FILE, AST_OPT_FLAG_VERBOSE_FILE, ast_options, AST_RWLIST_EMPTY, AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_set_flag, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, debug, ast_cli_args::fd, ast_debug_file::filename, find_debug_file(), ast_debug_file::level, option_debug, option_verbose, and ast_cli_entry::usage.

00238 {
00239    int oldval;
00240    int newlevel;
00241    int atleast = 0;
00242    int fd = a->fd;
00243    int argc = a->argc;
00244    char **argv = a->argv;
00245    int *dst;
00246    char *what;
00247    struct debug_file_list *dfl;
00248    struct ast_debug_file *adf;
00249    char *fn;
00250 
00251    switch (cmd) {
00252    case CLI_INIT:
00253       e->command = "core set {debug|verbose} [off|atleast]";
00254       e->usage =
00255          "Usage: core set {debug|verbose} [atleast] <level> [filename]\n"
00256          "       core set {debug|verbose} off\n"
00257          "       Sets level of debug or verbose messages to be displayed or \n"
00258          "       sets a filename to display debug messages from.\n"
00259          "  0 or off means no messages should be displayed.\n"
00260          "  Equivalent to -d[d[...]] or -v[v[v...]] on startup\n";
00261       return NULL;
00262 
00263    case CLI_GENERATE:
00264       return NULL;
00265    }
00266    /* all the above return, so we proceed with the handler.
00267     * we are guaranteed to be called with argc >= e->args;
00268     */
00269 
00270    if (argc < e->args)
00271       return CLI_SHOWUSAGE;
00272    if (!strcasecmp(argv[e->args - 2], "debug")) {
00273       dst = &option_debug;
00274       oldval = option_debug;
00275       what = "Core debug";
00276    } else {
00277       dst = &option_verbose;
00278       oldval = option_verbose;
00279       what = "Verbosity";
00280    }
00281    if (argc == e->args && !strcasecmp(argv[e->args - 1], "off")) {
00282       unsigned int debug = (*what == 'C');
00283       newlevel = 0;
00284 
00285       dfl = debug ? &debug_files : &verbose_files;
00286 
00287       AST_RWLIST_WRLOCK(dfl);
00288       while ((adf = AST_RWLIST_REMOVE_HEAD(dfl, entry)))
00289          ast_free(adf);
00290       ast_clear_flag(&ast_options, debug ? AST_OPT_FLAG_DEBUG_FILE : AST_OPT_FLAG_VERBOSE_FILE);
00291       AST_RWLIST_UNLOCK(dfl);
00292 
00293       goto done;
00294    }
00295    if (!strcasecmp(argv[e->args-1], "atleast"))
00296       atleast = 1;
00297    if (argc != e->args + atleast && argc != e->args + atleast + 1)
00298       return CLI_SHOWUSAGE;
00299    if (sscanf(argv[e->args + atleast - 1], "%30d", &newlevel) != 1)
00300       return CLI_SHOWUSAGE;
00301    if (argc == e->args + atleast + 1) {
00302       unsigned int debug = (*what == 'C');
00303       dfl = debug ? &debug_files : &verbose_files;
00304 
00305       fn = argv[e->args + atleast];
00306 
00307       AST_RWLIST_WRLOCK(dfl);
00308 
00309       if ((adf = find_debug_file(fn, debug)) && !newlevel) {
00310          AST_RWLIST_REMOVE(dfl, adf, entry);
00311          if (AST_RWLIST_EMPTY(dfl))
00312             ast_clear_flag(&ast_options, debug ? AST_OPT_FLAG_DEBUG_FILE : AST_OPT_FLAG_VERBOSE_FILE);
00313          AST_RWLIST_UNLOCK(dfl);
00314          ast_cli(fd, "%s was %d and has been set to 0 for '%s'\n", what, adf->level, fn);
00315          ast_free(adf);
00316          return CLI_SUCCESS;
00317       }
00318 
00319       if (adf) {
00320          if ((atleast && newlevel < adf->level) || adf->level == newlevel) {
00321             ast_cli(fd, "%s is %d for '%s'\n", what, adf->level, fn);
00322             AST_RWLIST_UNLOCK(dfl);
00323             return CLI_SUCCESS;
00324          }
00325       } else if (!(adf = ast_calloc(1, sizeof(*adf) + strlen(fn) + 1))) {
00326          AST_RWLIST_UNLOCK(dfl);
00327          return CLI_FAILURE;
00328       }
00329 
00330       oldval = adf->level;
00331       adf->level = newlevel;
00332       strcpy(adf->filename, fn);
00333 
00334       ast_set_flag(&ast_options, debug ? AST_OPT_FLAG_DEBUG_FILE : AST_OPT_FLAG_VERBOSE_FILE);
00335 
00336       AST_RWLIST_INSERT_TAIL(dfl, adf, entry);
00337       AST_RWLIST_UNLOCK(dfl);
00338 
00339       ast_cli(fd, "%s was %d and has been set to %d for '%s'\n", what, oldval, adf->level, adf->filename);
00340 
00341       return CLI_SUCCESS;
00342    }
00343 
00344 done:
00345    if (!atleast || newlevel > *dst)
00346       *dst = newlevel;
00347    if (oldval > 0 && *dst == 0)
00348       ast_cli(fd, "%s is now OFF\n", what);
00349    else if (*dst > 0) {
00350       if (oldval == *dst)
00351          ast_cli(fd, "%s is at least %d\n", what, *dst);
00352       else
00353          ast_cli(fd, "%s was %d and is now %d\n", what, oldval, *dst);
00354    }
00355 
00356    return CLI_SUCCESS;
00357 }

static char* help1 ( int  fd,
char *  match[],
int  locked 
) [static]

helper for final part of handle_help if locked = 1, assume the list is already locked

Definition at line 1551 of file cli.c.

References ast_cli_entry::_full_cmd, ast_cli(), ast_join(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, cli_next(), CLI_SUCCESS, ast_cli_entry::deprecated, len(), S_OR, and ast_cli_entry::summary.

Referenced by handle_help().

01552 {
01553    char matchstr[80] = "";
01554    struct ast_cli_entry *e = NULL;
01555    int len = 0;
01556    int found = 0;
01557 
01558    if (match) {
01559       ast_join(matchstr, sizeof(matchstr), match);
01560       len = strlen(matchstr);
01561    }
01562    if (!locked)
01563       AST_RWLIST_RDLOCK(&helpers);
01564    while ( (e = cli_next(e)) ) {
01565       /* Hide commands that start with '_' */
01566       if (e->_full_cmd[0] == '_')
01567          continue;
01568       /* Hide commands that are marked as deprecated. */
01569       if (e->deprecated)
01570          continue;
01571       if (match && strncasecmp(matchstr, e->_full_cmd, len))
01572          continue;
01573       ast_cli(fd, "%30.30s %s\n", e->_full_cmd, S_OR(e->summary, "<no description available>"));
01574       found++;
01575    }
01576    if (!locked)
01577       AST_RWLIST_UNLOCK(&helpers);
01578    if (!found && matchstr[0])
01579       ast_cli(fd, "No such command '%s'.\n", matchstr);
01580    return CLI_SUCCESS;
01581 }

static char* is_prefix ( const char *  word,
const char *  token,
int  pos,
int *  actual 
) [static]

if word is a valid prefix for token, returns the pos-th match as a malloced string, or NULL otherwise. Always tell in *actual how many matches we got.

Definition at line 1305 of file cli.c.

References ast_strdup, ast_strdupa, ast_strlen_zero(), cli_rsvd, s, and strsep().

Referenced by __ast_cli_generator().

01307 {
01308    int lw;
01309    char *s, *t1;
01310 
01311    *actual = 0;
01312    if (ast_strlen_zero(token))
01313       return NULL;
01314    if (ast_strlen_zero(word))
01315       word = "";  /* dummy */
01316    lw = strlen(word);
01317    if (strcspn(word, cli_rsvd) != lw)
01318       return NULL;   /* no match if word has reserved chars */
01319    if (strchr(cli_rsvd, token[0]) == NULL) { /* regular match */
01320       if (strncasecmp(token, word, lw))   /* no match */
01321          return NULL;
01322       *actual = 1;
01323       return (pos != 0) ? NULL : ast_strdup(token);
01324    }
01325    /* now handle regexp match */
01326 
01327    /* Wildcard always matches, so we never do is_prefix on them */
01328 
01329    t1 = ast_strdupa(token + 1);  /* copy, skipping first char */
01330    while (pos >= 0 && (s = strsep(&t1, cli_rsvd)) && *s) {
01331       if (*s == '%') /* wildcard */
01332          continue;
01333       if (strncasecmp(s, word, lw)) /* no match */
01334          continue;
01335       (*actual)++;
01336       if (pos-- == 0)
01337          return ast_strdup(s);
01338    }
01339    return NULL;
01340 }

static int modlist_modentry ( const char *  module,
const char *  description,
int  usecnt,
const char *  like 
) [static]

Definition at line 445 of file cli.c.

References ast_cli(), climodentryfd, MODLIST_FORMAT, and strcasestr().

Referenced by handle_modlist().

00446 {
00447    /* Comparing the like with the module */
00448    if (strcasestr(module, like) ) {
00449       ast_cli(climodentryfd, MODLIST_FORMAT, module, description, usecnt);
00450       return 1;
00451    } 
00452    return 0;
00453 }

static int more_words ( char *const *  dst  )  [static]

returns true if there are more words to match

Definition at line 1758 of file cli.c.

Referenced by __ast_cli_generator().

01759 {
01760    int i;
01761    for (i = 0; dst[i]; i++) {
01762       if (dst[i][0] != '[')
01763          return -1;
01764    }
01765    return 0;
01766 }

static char* parse_args ( const char *  s,
int *  argc,
char *  argv[],
int  max,
int *  trailingwhitespace 
) [static]

Definition at line 1627 of file cli.c.

References ast_log(), ast_strdup, dummy(), and LOG_WARNING.

Referenced by __ast_cli_generator(), agi_handle_command(), and ast_cli_command().

01628 {
01629    char *dup, *cur;
01630    int x = 0;
01631    int quoted = 0;
01632    int escaped = 0;
01633    int whitespace = 1;
01634    int dummy = 0;
01635 
01636    if (trailingwhitespace == NULL)
01637       trailingwhitespace = &dummy;
01638    *trailingwhitespace = 0;
01639    if (s == NULL) /* invalid, though! */
01640       return NULL;
01641    /* make a copy to store the parsed string */
01642    if (!(dup = ast_strdup(s)))
01643       return NULL;
01644 
01645    cur = dup;
01646    /* scan the original string copying into cur when needed */
01647    for (; *s ; s++) {
01648       if (x >= max - 1) {
01649          ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s);
01650          break;
01651       }
01652       if (*s == '"' && !escaped) {
01653          quoted = !quoted;
01654          if (quoted && whitespace) {
01655             /* start a quoted string from previous whitespace: new argument */
01656             argv[x++] = cur;
01657             whitespace = 0;
01658          }
01659       } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) {
01660          /* If we are not already in whitespace, and not in a quoted string or
01661             processing an escape sequence, and just entered whitespace, then
01662             finalize the previous argument and remember that we are in whitespace
01663          */
01664          if (!whitespace) {
01665             *cur++ = '\0';
01666             whitespace = 1;
01667          }
01668       } else if (*s == '\\' && !escaped) {
01669          escaped = 1;
01670       } else {
01671          if (whitespace) {
01672             /* we leave whitespace, and are not quoted. So it's a new argument */
01673             argv[x++] = cur;
01674             whitespace = 0;
01675          }
01676          *cur++ = *s;
01677          escaped = 0;
01678       }
01679    }
01680    /* Null terminate */
01681    *cur++ = '\0';
01682    /* XXX put a NULL in the last argument, because some functions that take
01683     * the array may want a null-terminated array.
01684     * argc still reflects the number of non-NULL entries.
01685     */
01686    argv[x] = NULL;
01687    *argc = x;
01688    *trailingwhitespace = whitespace;
01689    return dup;
01690 }

static void print_uptimestr ( int  fd,
struct timeval  timeval,
const char *  prefix,
int  printsec 
) [static]

Definition at line 455 of file cli.c.

References ast_cli(), ast_str_alloca, ast_str_append(), DAY, ESS, HOUR, MINUTE, NEEDCOMMA, ast_str::str, ast_str::used, WEEK, and YEAR.

Referenced by handle_showcalls(), and handle_showuptime().

00456 {
00457    int x; /* the main part - years, weeks, etc. */
00458    struct ast_str *out;
00459 
00460 #define SECOND (1)
00461 #define MINUTE (SECOND*60)
00462 #define HOUR (MINUTE*60)
00463 #define DAY (HOUR*24)
00464 #define WEEK (DAY*7)
00465 #define YEAR (DAY*365)
00466 #define NEEDCOMMA(x) ((x)? ",": "") /* define if we need a comma */
00467    if (timeval.tv_sec < 0) /* invalid, nothing to show */
00468       return;
00469 
00470    if (printsec)  {  /* plain seconds output */
00471       ast_cli(fd, "%s: %lu\n", prefix, (u_long)timeval.tv_sec);
00472       return;
00473    }
00474    out = ast_str_alloca(256);
00475    if (timeval.tv_sec > YEAR) {
00476       x = (timeval.tv_sec / YEAR);
00477       timeval.tv_sec -= (x * YEAR);
00478       ast_str_append(&out, 0, "%d year%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00479    }
00480    if (timeval.tv_sec > WEEK) {
00481       x = (timeval.tv_sec / WEEK);
00482       timeval.tv_sec -= (x * WEEK);
00483       ast_str_append(&out, 0, "%d week%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00484    }
00485    if (timeval.tv_sec > DAY) {
00486       x = (timeval.tv_sec / DAY);
00487       timeval.tv_sec -= (x * DAY);
00488       ast_str_append(&out, 0, "%d day%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00489    }
00490    if (timeval.tv_sec > HOUR) {
00491       x = (timeval.tv_sec / HOUR);
00492       timeval.tv_sec -= (x * HOUR);
00493       ast_str_append(&out, 0, "%d hour%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00494    }
00495    if (timeval.tv_sec > MINUTE) {
00496       x = (timeval.tv_sec / MINUTE);
00497       timeval.tv_sec -= (x * MINUTE);
00498       ast_str_append(&out, 0, "%d minute%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00499    }
00500    x = timeval.tv_sec;
00501    if (x > 0 || out->used == 0)  /* if there is nothing, print 0 seconds */
00502       ast_str_append(&out, 0, "%d second%s ", x, ESS(x));
00503    ast_cli(fd, "%s: %s\n", prefix, out->str);
00504 }

static int set_full_cmd ( struct ast_cli_entry e  )  [static]

initialize the _full_cmd string and related parameters, return 0 on success, -1 on error.

Definition at line 1232 of file cli.c.

References ast_cli_entry::_full_cmd, ast_cli_entry::args, ast_join(), ast_log(), ast_strdup, buf, cli_rsvd, ast_cli_entry::cmda, ast_cli_entry::cmdlen, and LOG_WARNING.

Referenced by __ast_cli_register().

01233 {
01234    int i;
01235    char buf[80];
01236 
01237    ast_join(buf, sizeof(buf), e->cmda);
01238    e->_full_cmd = ast_strdup(buf);
01239    if (!e->_full_cmd) {
01240       ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf);
01241       return -1;
01242    }
01243    e->cmdlen = strcspn(e->_full_cmd, cli_rsvd);
01244    for (i = 0; e->cmda[i]; i++)
01245       ;
01246    e->args = i;
01247    return 0;
01248 }

static int word_match ( const char *  cmd,
const char *  cli_word 
) [static]

match a word in the CLI entry. returns -1 on mismatch, 0 on match of an optional word, 1 on match of a full word.

The pattern can be any_word match for equal [foo|bar|baz] optionally, one of these words {foo|bar|baz} exactly, one of these words % any word

Definition at line 1276 of file cli.c.

References ast_strlen_zero(), cli_rsvd, and strcasestr().

Referenced by __ast_cli_generator(), and find_cli().

01277 {
01278    int l;
01279    char *pos;
01280 
01281    if (ast_strlen_zero(cmd) || ast_strlen_zero(cli_word))
01282       return -1;
01283    if (!strchr(cli_rsvd, cli_word[0])) /* normal match */
01284       return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1;
01285    /* regexp match, takes [foo|bar] or {foo|bar} */
01286    l = strlen(cmd);
01287    /* wildcard match - will extend in the future */
01288    if (l > 0 && cli_word[0] == '%') {
01289       return 1;   /* wildcard */
01290    }
01291    pos = strcasestr(cli_word, cmd);
01292    if (pos == NULL) /* not found, say ok if optional */
01293       return cli_word[0] == '[' ? 0 : -1;
01294    if (pos == cli_word) /* no valid match at the beginning */
01295       return -1;
01296    if (strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l]))
01297       return 1;   /* valid match */
01298    return -1;  /* not found */
01299 }


Variable Documentation

struct ast_threadstorage ast_cli_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_ast_cli_buf , .custom_init = NULL , } [static]

Definition at line 64 of file cli.c.

struct ast_cli_entry cli_cli[] [static]

Definition at line 1185 of file cli.c.

Referenced by ast_builtins_init().

struct ast_cli_entry cli_debug_channel_deprecated = AST_CLI_DEFINE(handle_debugchan_deprecated, "Enable debugging on channel") [static]

Definition at line 1178 of file cli.c.

struct ast_cli_entry cli_module_load_deprecated = AST_CLI_DEFINE(handle_load_deprecated, "Load a module") [static]

Definition at line 1179 of file cli.c.

struct ast_cli_entry cli_module_reload_deprecated = AST_CLI_DEFINE(handle_reload_deprecated, "reload modules by name") [static]

Definition at line 1180 of file cli.c.

struct ast_cli_entry cli_module_unload_deprecated = AST_CLI_DEFINE(handle_unload_deprecated, "unload modules by name") [static]

Definition at line 1181 of file cli.c.

const char cli_rsvd[] = "[]{}|*%" [static]

Some regexp characters in cli arguments are reserved and used as separators.

Definition at line 1226 of file cli.c.

Referenced by is_prefix(), set_full_cmd(), and word_match().

int climodentryfd = -1 [static]

Definition at line 443 of file cli.c.

Referenced by handle_modlist(), and modlist_modentry().

ast_mutex_t climodentrylock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 442 of file cli.c.

Referenced by handle_modlist().

struct debug_file_list debug_files [static]

list of filenames and their debug settings

Definition at line 60 of file cli.c.

struct debug_file_list verbose_files [static]

list of filenames and their verbose settings

Definition at line 62 of file cli.c.


Generated on Wed Oct 28 11:46:06 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6