Wed Aug 18 22:34:20 2010

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"

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 __init_ast_cli_buf (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 = { .handler = handle_debugchan_deprecated , .summary = "Enable debugging on channel" ,__VA_ARGS__ }
static struct ast_cli_entry cli_module_load_deprecated = { .handler = handle_load_deprecated , .summary = "Load a module" ,__VA_ARGS__ }
static struct ast_cli_entry cli_module_reload_deprecated = { .handler = handle_reload_deprecated , .summary = "reload modules by name" ,__VA_ARGS__ }
static struct ast_cli_entry cli_module_unload_deprecated = { .handler = handle_unload_deprecated , .summary = "unload modules by name" ,__VA_ARGS__ }
static const char cli_rsvd [] = "[]{}|*%"
static int climodentryfd = -1
static ast_mutex_t climodentrylock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
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"

Referenced by group_show_channels(), and handle_chanlist().

#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 442 of file cli.c.

Referenced by modlist_modentry().

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

Definition at line 443 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 1774 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().

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

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

Definition at line 1442 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().

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

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

Definition at line 1417 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().

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

static void __init_ast_cli_buf ( void   )  [static]

Definition at line 64 of file cli.c.

00070 {

void ast_builtins_init ( void   ) 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 1254 of file cli.c.

References ast_cli_register_multiple(), and cli_cli.

Referenced by main().

01255 {
01256    ast_cli_register_multiple(cli_cli, sizeof(cli_cli) / sizeof(struct ast_cli_entry));
01257 }

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(), and buf.

Referenced by __iax2_show_peers(), __say_cli_init(), _sip_qualify_peer(), _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(), cli_tps_ping(), cli_tps_report(), console_active(), console_answer(), console_autoanswer(), console_boost(), console_cmd(), console_dial(), console_do_answer(), console_flash(), console_hangup(), console_mute(), 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(), dialog_dump_func(), 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(), 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_config_list(), 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_jb(), handle_cli_iax2_set_debug_trunk(), 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_realtime_pgsql_cache(), handle_cli_realtime_pgsql_status(), handle_cli_refresh(), 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_sqlite_show_tables(), 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_debug_dialplan(), 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_pri_debug(), handle_pri_no_debug(), handle_pri_really_debug(), handle_pri_set_debug_file(), handle_pri_show_debug(), handle_pri_show_span(), handle_pri_show_spans(), handle_pri_unset_debug_file(), handle_pri_version(), 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_chanvar(), 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_sysinfo(), 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(), peer_dump_func(), print_bc_info(), print_codec_to_cli(), print_group(), print_uptimestr(), radio_active(), radio_set_debug(), radio_set_debug_off(), radio_set_xpmr_debug(), radio_tune(), realtime_ldap_status(), rpt_do_cmd(), rpt_do_debug(), rpt_do_dump(), rpt_do_fun(), rpt_do_local_nodes(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_chanstats_cb(), show_codec_n(), show_codecs(), show_config_description(), show_debug_helper(), show_dialplan_helper(), show_license(), show_users_realtime(), show_warranty(), sip_cli_notify(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_do_history_deprecated(), sip_prune_realtime(), sip_set_history(), sip_show_channel(), sip_show_channels(), sip_show_channelstats(), sip_show_domains(), sip_show_history(), sip_show_inuse(), sip_show_objects(), sip_show_registry(), sip_show_sched(), sip_show_settings(), sip_show_tcp(), sip_show_user(), sip_show_users(), sip_unregister(), sla_show_stations(), sla_show_trunks(), timing_test(), tune_rxctcss(), tune_rxinput(), tune_rxvoice(), tune_txoutput(), 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 1860 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(), eventhandler(), exit_completely(), handle_cli_config_reload(), keypad_pick_up(), keypad_toggle(), and run_startup_commands().

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

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 1915 of file cli.c.

References ast_cli_command().

Referenced by netconsole().

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

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 1094 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().

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

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 1713 of file cli.c.

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

Referenced by cli_complete(), and handle_commandmatchesarray().

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

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 1855 of file cli.c.

References __ast_cli_generator().

Referenced by ast_cli_completion_matches(), and ast_cli_generatornummatches().

01856 {
01857    return __ast_cli_generator(text, word, state, 1);
01858 }

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

Return the number of unique matches for the generator.

Definition at line 1696 of file cli.c.

References ast_cli_generator(), ast_free, and buf.

Referenced by handle_commandnummatches().

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

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 1522 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().

01523 {
01524    return __ast_cli_register(e, NULL);
01525 }

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 1530 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_timing_init(), ast_tps_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().

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

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 1516 of file cli.c.

References __ast_cli_unregister().

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

01517 {
01518    return __ast_cli_unregister(e, NULL);
01519 }

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 1540 of file cli.c.

References ast_cli_unregister().

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

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

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 1106 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_show_chanvar(), handle_showchan(), and handle_softhangup().

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

unsigned int ast_debug_get_by_file ( const char *  file  ) 

Get the debug level for a file.

Parameters:
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::entry, 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.

Parameters:
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::entry, 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]

Definition at line 1259 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().

01260 {
01261    if (e) {
01262       return AST_LIST_NEXT(e, list);
01263    } else {
01264       return AST_LIST_FIRST(&helpers);
01265    }
01266 }

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 1398 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().

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

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

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 1355 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().

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

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

Find the debug or verbose file setting.

Definition at line 225 of file cli.c.

References AST_LIST_TRAVERSE, ast_debug_file::entry, and ast_debug_file::filename.

Referenced by handle_verbose().

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

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

Definition at line 1127 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.

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

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

Definition at line 634 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.

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

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

Definition at line 866 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.

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

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

Definition at line 785 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.

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

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

Definition at line 840 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.

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

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

Definition at line 891 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().

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

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

Definition at line 954 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().

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

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

Definition at line 1586 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.

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

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    ast_cli(a->fd, "Loaded %s\n", a->argv[e->args]);
00167    return CLI_SUCCESS;
00168 }

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

Definition at line 170 of file cli.c.

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

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

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

Definition at line 360 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.

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

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

Definition at line 540 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, 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.

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

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

Definition at line 966 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().

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

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

Definition at line 178 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().

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

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

Definition at line 213 of file cli.c.

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

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

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

Definition at line 579 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.

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

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

Definition at line 984 of file cli.c.

References ast_channel::_bridge, ast_channel::_state, 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::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, DEBUGCHAN_FLAG, 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_cli_args::pos, 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.

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

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

Definition at line 509 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.

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

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

Definition at line 756 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.

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

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

Definition at line 385 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, 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().

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

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

Definition at line 434 of file cli.c.

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

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

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

Definition at line 238 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_debug_file::entry, ast_cli_args::fd, find_debug_file(), ast_debug_file::level, option_debug, option_verbose, and ast_cli_entry::usage.

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

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 1554 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().

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

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 1308 of file cli.c.

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

Referenced by __ast_cli_generator().

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

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

Definition at line 448 of file cli.c.

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

Referenced by handle_modlist().

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

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

returns true if there are more words to match

Definition at line 1761 of file cli.c.

Referenced by __ast_cli_generator().

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

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

Definition at line 1630 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().

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

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

Definition at line 458 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().

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

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 1235 of file cli.c.

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

Referenced by __ast_cli_register().

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

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 1279 of file cli.c.

References ast_strlen_zero(), and strcasestr().

Referenced by __ast_cli_generator(), and find_cli().

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


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 1188 of file cli.c.

Referenced by ast_builtins_init().

struct ast_cli_entry cli_debug_channel_deprecated = { .handler = handle_debugchan_deprecated , .summary = "Enable debugging on channel" ,__VA_ARGS__ } [static]

Definition at line 1181 of file cli.c.

struct ast_cli_entry cli_module_load_deprecated = { .handler = handle_load_deprecated , .summary = "Load a module" ,__VA_ARGS__ } [static]

Definition at line 1182 of file cli.c.

struct ast_cli_entry cli_module_reload_deprecated = { .handler = handle_reload_deprecated , .summary = "reload modules by name" ,__VA_ARGS__ } [static]

Definition at line 1183 of file cli.c.

struct ast_cli_entry cli_module_unload_deprecated = { .handler = handle_unload_deprecated , .summary = "unload modules by name" ,__VA_ARGS__ } [static]

Definition at line 1184 of file cli.c.

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

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

Definition at line 1229 of file cli.c.

int climodentryfd = -1 [static]

Definition at line 446 of file cli.c.

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

Definition at line 445 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 Aug 18 22:34:20 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7