Wed Mar 3 22:51:48 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 <readline.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 "asterisk/threadstorage.h"
Include dependency graph for cli.c:

Go to the source code of this file.

Data Structures

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

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)
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.
 AST_MUTEX_DEFINE_STATIC (climodentrylock)
 AST_RWLIST_HEAD (debug_file_list, ast_debug_file)
static AST_RWLIST_HEAD_STATIC (helpers, ast_cli_entry)
 AST_THREADSTORAGE (ast_cli_buf)
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_cli_entry cli_cli []
static struct ast_cli_entry cli_debug_channel_deprecated = AST_CLI_DEFINE(handle_debugchan_deprecated, "Enable debugging on channel")
static struct ast_cli_entry cli_module_load_deprecated = AST_CLI_DEFINE(handle_load_deprecated, "Load a module")
static struct ast_cli_entry cli_module_reload_deprecated = AST_CLI_DEFINE(handle_reload_deprecated, "reload modules by name")
static struct ast_cli_entry cli_module_unload_deprecated = AST_CLI_DEFINE(handle_unload_deprecated, "unload modules by name")
static const char cli_rsvd [] = "[]{}|*%"
static int climodentryfd = -1
static 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 68 of file cli.c.

Referenced by ast_cli().

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

Referenced by handle_chanlist().

#define DAY   (HOUR*24)

Referenced by print_uptimestr().

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

Referenced by handle_chanlist().

#define HOUR   (MINUTE*60)

Referenced by print_uptimestr().

#define MINUTE   (SECOND*60)

Referenced by print_uptimestr().

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

Definition at line 440 of file cli.c.

Referenced by modlist_modentry().

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

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

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

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

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

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

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

Definition at line 1415 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, LOG_WARNING, and ast_cli_entry::usage.

Referenced by ast_cli_unregister().

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

void ast_builtins_init ( void   ) 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 1252 of file cli.c.

References ast_cli_register_multiple(), and cli_cli.

Referenced by main().

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

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

Definition at line 70 of file cli.c.

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

Referenced by __iax2_show_peers(), __say_cli_init(), _sip_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_set_level(), 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_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_ss7_block_cic(), handle_ss7_block_linkset(), handle_ss7_debug(), handle_ss7_no_debug(), handle_ss7_show_linkset(), handle_ss7_unblock_cic(), handle_ss7_unblock_linkset(), handle_ss7_version(), 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().

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

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

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

Referenced by action_command(), ast_cli_command_multiple(), cli_activate(), consolehandler(), exit_completely(), handle_cli_config_reload(), rpt_exec(), and run_startup_commands().

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

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

References ast_cli_command().

Referenced by netconsole().

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

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

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

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

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

Referenced by cli_complete(), and handle_commandmatchesarray().

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

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

References __ast_cli_generator().

Referenced by ast_cli_completion_matches(), and ast_cli_generatornummatches().

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

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

Return the number of unique matches for the generator.

Definition at line 1694 of file cli.c.

References ast_cli_generator(), ast_free, and buf.

Referenced by handle_commandnummatches().

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

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

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

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

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

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

References __ast_cli_unregister().

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

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

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

References ast_cli_unregister().

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

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

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

References ast_channel_unlock, ast_channel_walk_locked(), and ast_strdup.

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

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

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

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

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

AST_MUTEX_DEFINE_STATIC ( climodentrylock   ) 
AST_RWLIST_HEAD ( debug_file_list  ,
ast_debug_file   
)
static AST_RWLIST_HEAD_STATIC ( helpers  ,
ast_cli_entry   
) [static]
AST_THREADSTORAGE ( ast_cli_buf   ) 
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 104 of file cli.c.

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

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

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

Definition at line 1257 of file cli.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

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

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

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

Definition at line 123 of file cli.c.

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

Referenced by handle_load().

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

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

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

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

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

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

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

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

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

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

Find the debug or verbose file setting.

  • debug 1 for debug, 0 for verbose

Definition at line 225 of file cli.c.

References AST_LIST_TRAVERSE.

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 1125 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, and ast_cli_entry::usage.

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

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

Definition at line 632 of file cli.c.

References ast_channel::_state, 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, option_maxcalls, ast_channel::priority, S_OR, ast_cdr::start, ast_cli_entry::usage, VERBOSE_FORMAT_STRING, and VERBOSE_FORMAT_STRING2.

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

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

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

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

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

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

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

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

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

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

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

Definition at line 889 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_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

Referenced by handle_debugchan_deprecated(), and handle_nodebugchan_deprecated().

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

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

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

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

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

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

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

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

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

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

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_module_helper(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_module_list(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, climodentryfd, 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.

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

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

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

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

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 577 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.

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

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

Definition at line 982 of file cli.c.

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

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

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

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

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

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

Definition at line 754 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_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

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

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, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, s, ast_cli_entry::usage, and ast_cli_args::word.

Referenced by handle_unload_deprecated().

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    }
00429    return CLI_SUCCESS;
00430 }

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

Definition at line 432 of file cli.c.

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

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

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_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 1552 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().

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

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

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

Referenced by __ast_cli_generator().

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

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

Definition at line 446 of file cli.c.

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

Referenced by handle_modlist().

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

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

returns true if there are more words to match

Definition at line 1759 of file cli.c.

Referenced by __ast_cli_generator().

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

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

Definition at line 1628 of file cli.c.

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

Referenced by __ast_cli_generator(), and ast_cli_command().

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

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

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

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

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

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

Referenced by __ast_cli_register().

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

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

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

Referenced by __ast_cli_generator(), and find_cli().

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


Variable Documentation

struct ast_cli_entry cli_cli[] [static]

Definition at line 1186 of file cli.c.

Referenced by ast_builtins_init().

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

Definition at line 1179 of file cli.c.

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

Definition at line 1180 of file cli.c.

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

Definition at line 1181 of file cli.c.

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

Definition at line 1182 of file cli.c.

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

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

Definition at line 1227 of file cli.c.

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

int climodentryfd = -1 [static]

Definition at line 444 of file cli.c.

Referenced by handle_modlist(), and modlist_modentry().

struct debug_file_list debug_files [static]

list of filenames and their debug settings

Definition at line 61 of file cli.c.

struct debug_file_list verbose_files [static]

list of filenames and their verbose settings

Definition at line 63 of file cli.c.


Generated on 3 Mar 2010 for Asterisk - the Open Source PBX by  doxygen 1.6.1