main/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 <pwd.h>
#include <grp.h>
#include <editline/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 "asterisk/translate.h"
#include "asterisk/bridge.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_bridges.h"

Include dependency graph for main/cli.c:

Go to the source code of this file.

Data Structures

struct  channel_set_debug_args
struct  cli_perm
 List of restrictions per user. More...
struct  cli_perm_head
struct  cli_perms
 List of users and permissions. More...
struct  helpers
struct  module_level
 map a debug or verbose level to a module name More...
struct  module_level_list
struct  usergroup_cli_perm
 list of users to apply restrictions. 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!%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 %-11s %13s\n"
#define MODLIST_FORMAT2   "%-30s %-40.40s %-10s %-11s %13s\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 %-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 %-11.11s %-20.20s\n"
#define WEEK   (DAY*7)
#define YEAR   (DAY*365)

Functions

static char * __ast_cli_generator (const char *text, const char *word, int state, int lock)
static int __ast_cli_register (struct ast_cli_entry *e, struct ast_cli_entry *ed)
static int __ast_cli_unregister (struct ast_cli_entry *e, struct ast_cli_entry *ed)
static void __fini_cli_perms (void)
static void __fini_helpers (void)
static void __init_ast_cli_buf (void)
static void __init_cli_perms (void)
static void __init_helpers (void)
void ast_builtins_init (void)
 initialize the _full_cmd string in * each of the builtins.
void ast_cli (int fd, const char *fmt,...)
int ast_cli_command_full (int uid, int gid, int fd, const char *s)
 Interprets a command Interpret a command s, sending output to fd if uid:gid has permissions to run this command. uid = CLI_NO_PERMS to avoid checking user permissions gid = CLI_NO_PERMS to avoid checking group permissions.
int ast_cli_command_multiple_full (int uid, int gid, 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 if uid has permissions, uid = CLI_NO_PERMS to avoid checking users permissions. gid = CLI_NO_PERMS to avoid checking group permissions.
char * ast_cli_complete (const char *word, const 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_perms_init (int reload)
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_module (const char *module)
 Get the debug level for a module.
unsigned int ast_verbose_get_by_module (const char *module)
 Get the verbose level for a module.
static int channel_set_debug (void *obj, void *arg, void *data, int flags)
static int cli_has_permissions (int uid, int gid, const char *command)
static int cli_is_registered (struct ast_cli_entry *e)
static struct ast_cli_entrycli_next (struct ast_cli_entry *e)
static void cli_shutdown (void)
static char * complete_fn (const char *word, int state)
static char * complete_number (const char *partial, unsigned int min, unsigned int max, int n)
static void destroy_match_list (char **match_list, int matches)
static void destroy_user_perms (void)
 cleanup (free) cli_perms linkedlist.
static char * find_best (const char *argv[])
static struct ast_cli_entryfind_cli (const char *const cmds[], int match_type)
static struct module_levelfind_module_level (const char *module, struct module_level_list *mll)
 Find the module level 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_cli_check_permissions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handles CLI command 'cli check permissions'
static char * handle_cli_reload_permissions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handles CLI command 'cli reload permissions'
static char * handle_cli_show_permissions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handles CLI command 'cli show permissions'
static char * handle_cli_wait_fullybooted (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_reload (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_debug (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_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_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_verbose (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * help1 (int fd, const char *const 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 *status, const char *like, enum ast_module_support_level support_level)
static int more_words (const char *const *dst)
 returns true if there are more words to match
static char * parse_args (const char *s, int *argc, const 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 void status_debug_verbose (struct ast_cli_args *a, const char *what, int old_val, int cur_val)
static int word_match (const char *cmd, const char *cli_word)

Variables

static struct ast_threadstorage ast_cli_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ast_cli_buf , .custom_init = NULL , }
static struct ast_cli_entry cli_cli []
static int cli_default_perm = 1
 Default permissions value 1=Permit 0=Deny.
static const char cli_rsvd [] = "[]{}|*%"
static int climodentryfd = -1
static ast_mutex_t climodentrylock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct module_level_list debug_modules = AST_RWLIST_HEAD_INIT_VALUE
static const char perms_config [] = "cli_permissions.conf"
 CLI permissions config file.
static ast_mutex_t permsconfiglock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
 mutex used to prevent a user from running the 'cli reload permissions' command while it is already running.


Detailed Description

Standard Command Line Interface.

Author:
Mark Spencer <markster@digium.com>

Definition in file main/cli.c.


Define Documentation

#define AST_CLI_INITLEN   256

Initial buffer size for resulting strings in ast_cli().

Definition at line 113 of file main/cli.c.

Referenced by ast_cli().

#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%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 %-11s %13s\n"

Definition at line 775 of file main/cli.c.

Referenced by modlist_modentry().

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

Definition at line 776 of file main/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 %-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 %-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 2589 of file main/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, e, ast_cli_entry::handler, is_prefix(), ast_cli_args::line, more_words(), NULL, parse_args(), and word_match().

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

02590 {
02591    const char *argv[AST_MAX_ARGS];
02592    struct ast_cli_entry *e = NULL;
02593    int x = 0, argindex, matchlen;
02594    int matchnum=0;
02595    char *ret = NULL;
02596    char matchstr[80] = "";
02597    int tws = 0;
02598    /* Split the argument into an array of words */
02599    char *duplicate = parse_args(text, &x, argv, ARRAY_LEN(argv), &tws);
02600 
02601    if (!duplicate)   /* malloc error */
02602       return NULL;
02603 
02604    /* Compute the index of the last argument (could be an empty string) */
02605    argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x;
02606 
02607    /* rebuild the command, ignore terminating white space and flatten space */
02608    ast_join(matchstr, sizeof(matchstr)-1, argv);
02609    matchlen = strlen(matchstr);
02610    if (tws) {
02611       strcat(matchstr, " "); /* XXX */
02612       if (matchlen)
02613          matchlen++;
02614    }
02615    if (lock)
02616       AST_RWLIST_RDLOCK(&helpers);
02617    while ( (e = cli_next(e)) ) {
02618       /* XXX repeated code */
02619       int src = 0, dst = 0, n = 0;
02620 
02621       if (e->command[0] == '_')
02622          continue;
02623 
02624       /*
02625        * Try to match words, up to and excluding the last word, which
02626        * is either a blank or something that we want to extend.
02627        */
02628       for (;src < argindex; dst++, src += n) {
02629          n = word_match(argv[src], e->cmda[dst]);
02630          if (n < 0)
02631             break;
02632       }
02633 
02634       if (src != argindex && more_words(e->cmda + dst))  /* not a match */
02635          continue;
02636       ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n);
02637       matchnum += n; /* this many matches here */
02638       if (ret) {
02639          /*
02640           * argv[src] is a valid prefix of the next word in this
02641           * command. If this is also the correct entry, return it.
02642           */
02643          if (matchnum > state)
02644             break;
02645          ast_free(ret);
02646          ret = NULL;
02647       } else if (ast_strlen_zero(e->cmda[dst])) {
02648          /*
02649           * This entry is a prefix of the command string entered
02650           * (only one entry in the list should have this property).
02651           * Run the generator if one is available. In any case we are done.
02652           */
02653          if (e->handler) { /* new style command */
02654             struct ast_cli_args a = {
02655                .line = matchstr, .word = word,
02656                .pos = argindex,
02657                .n = state - matchnum,
02658                .argv = argv,
02659                .argc = x};
02660             ret = e->handler(e, CLI_GENERATE, &a);
02661          }
02662          if (ret)
02663             break;
02664       }
02665    }
02666    if (lock)
02667       AST_RWLIST_UNLOCK(&helpers);
02668    ast_free(duplicate);
02669    return ret;
02670 }

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

Definition at line 2228 of file main/cli.c.

References ast_cli_entry::_full_cmd, ast_free, 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, cli_is_registered(), ast_cli_entry::cmda, ast_cli_entry::cmdlen, ast_cli_entry::command, find_cli(), ast_cli_entry::handler, len(), LOG_WARNING, NULL, S_OR, and set_full_cmd().

Referenced by ast_cli_register().

02229 {
02230    struct ast_cli_entry *cur;
02231    int i, lf, ret = -1;
02232 
02233    struct ast_cli_args a;  /* fake argument */
02234    char **dst = (char **)e->cmda;   /* need to cast as the entry is readonly */
02235    char *s;
02236 
02237    AST_RWLIST_WRLOCK(&helpers);
02238 
02239    if (cli_is_registered(e)) {
02240       ast_log(LOG_WARNING, "Command '%s' already registered (the same ast_cli_entry)\n",
02241          S_OR(e->_full_cmd, e->command));
02242       ret = 0;  /* report success */
02243       goto done;
02244    }
02245 
02246    memset(&a, '\0', sizeof(a));
02247    e->handler(e, CLI_INIT, &a);
02248    /* XXX check that usage and command are filled up */
02249    s = ast_skip_blanks(e->command);
02250    s = e->command = ast_strdup(s);
02251    for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) {
02252       *dst++ = s; /* store string */
02253       s = ast_skip_nonblanks(s);
02254       if (*s == '\0')   /* we are done */
02255          break;
02256       *s++ = '\0';
02257       s = ast_skip_blanks(s);
02258    }
02259    *dst++ = NULL;
02260 
02261    if (find_cli(e->cmda, 1)) {
02262       ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n",
02263          S_OR(e->_full_cmd, e->command));
02264       goto done;
02265    }
02266    if (set_full_cmd(e)) {
02267       ast_log(LOG_WARNING, "Error registering CLI Command '%s'\n",
02268          S_OR(e->_full_cmd, e->command));
02269       goto done;
02270    }
02271 
02272    lf = e->cmdlen;
02273    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
02274       int len = cur->cmdlen;
02275       if (lf < len)
02276          len = lf;
02277       if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) {
02278          AST_RWLIST_INSERT_BEFORE_CURRENT(e, list);
02279          break;
02280       }
02281    }
02282    AST_RWLIST_TRAVERSE_SAFE_END;
02283 
02284    if (!cur)
02285       AST_RWLIST_INSERT_TAIL(&helpers, e, list);
02286    ret = 0; /* success */
02287 
02288 done:
02289    AST_RWLIST_UNLOCK(&helpers);
02290    if (ret) {
02291       ast_free(e->command);
02292       e->command = NULL;
02293    }
02294 
02295    return ret;
02296 }

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

Definition at line 2206 of file main/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::handler, ast_cli_entry::inuse, LOG_WARNING, NULL, and ast_cli_entry::usage.

Referenced by ast_cli_unregister().

02207 {
02208    if (e->inuse) {
02209       ast_log(LOG_WARNING, "Can't remove command that is in use\n");
02210    } else {
02211       AST_RWLIST_WRLOCK(&helpers);
02212       AST_RWLIST_REMOVE(&helpers, e, list);
02213       AST_RWLIST_UNLOCK(&helpers);
02214       ast_free(e->_full_cmd);
02215       e->_full_cmd = NULL;
02216       if (e->handler) {
02217          /* this is a new-style entry. Reset fields and free memory. */
02218          char *cmda = (char *) e->cmda;
02219          memset(cmda, '\0', sizeof(e->cmda));
02220          ast_free(e->command);
02221          e->command = NULL;
02222          e->usage = NULL;
02223       }
02224    }
02225    return 0;
02226 }

static void __fini_cli_perms ( void   )  [static]

Definition at line 94 of file main/cli.c.

00099 {

static void __fini_helpers ( void   )  [static]

Definition at line 223 of file main/cli.c.

00226 {

static void __init_ast_cli_buf ( void   )  [static]

Definition at line 110 of file main/cli.c.

00116 {

static void __init_cli_perms ( void   )  [static]

Definition at line 94 of file main/cli.c.

00099 {

static void __init_helpers ( void   )  [static]

Definition at line 223 of file main/cli.c.

00226 {

void ast_builtins_init ( void   ) 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 2026 of file main/cli.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_register_cleanup(), and cli_shutdown().

Referenced by main().

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

Definition at line 115 of file main/cli.c.

References ast_carefulwrite(), AST_CLI_INITLEN, AST_DYNSTR_BUILD_FAILED, ast_str_buffer(), ast_str_set_va(), ast_str_strlen(), ast_str_thread_get(), and buf.

Referenced by __iax2_show_peers(), __say_cli_init(), _iax2_show_peers_one(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), _sip_show_peers_one(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), _stun_show_status(), agent_handle_logoff_cmd(), agent_handle_show_specific(), agent_show_requested(), alias_show(), aoc_cli_debug_enable(), ari_mkpasswd(), ari_show(), ari_show_user(), ari_show_users(), ast_cli_command_full(), ast_cli_netstats(), ast_console_toggle_mute(), ast_pbx_hangup_handler_headers(), ast_pbx_hangup_handler_show(), ast_sip_cli_traverse_objects(), bridge_show_specific_print_channel(), cc_cli_output_status(), cc_cli_print_monitor_stats(), channel_set_debug(), 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_display_named_acl(), cli_display_named_acl_list(), cli_display_parking_global(), cli_display_parking_lot(), cli_display_parking_lot_list(), cli_fax_set_debug(), cli_fax_show_capabilities(), cli_fax_show_session(), cli_fax_show_sessions(), cli_fax_show_settings(), cli_fax_show_stats(), cli_fax_show_version(), cli_list_available(), cli_list_devices(), cli_match_char_tree(), cli_mute_unmute_helper(), cli_notify(), cli_odbc_read(), cli_odbc_write(), cli_on_contact(), cli_qualify(), cli_qualify_contacts(), cli_realtime_destroy(), cli_realtime_load(), cli_realtime_store(), cli_realtime_update(), cli_realtime_update2(), cli_register(), cli_show_channel(), cli_show_channels(), cli_show_endpoint_identifiers(), cli_show_settings(), cli_tps_ping(), cli_tps_report(), cli_unregister(), complete_ari_user(), 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(), corosync_show_config(), corosync_show_members(), dahdi_create_channels(), dahdi_destroy_channels(), dahdi_set_dnd(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), dahdi_show_status(), dahdi_show_version(), data_provider_print_cli(), data_result_print_cli(), data_result_print_cli_node(), dialog_dump_func(), display_parked_call(), display_parking_lot(), display_results(), do_print(), dump_str_and_free(), dundi_do_lookup(), dundi_do_precache(), dundi_do_query(), dundi_flush(), dundi_set_debug(), dundi_show_cache(), dundi_show_entityid(), dundi_show_hints(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), dundi_store_history(), firmware_show_callback(), gen_events(), group_show_channels(), handle_bridge_kick_channel(), handle_bridge_show_all(), handle_bridge_show_specific(), handle_bridge_technology_show(), handle_bridge_technology_suspend(), handle_cdr_pgsql_status(), handle_chanlist(), handle_cli_agi_add_cmd(), handle_cli_agi_debug(), handle_cli_agi_dump_html(), handle_cli_agi_show(), handle_cli_cdr_mysql_status(), handle_cli_check_permissions(), handle_cli_confbridge_kick(), handle_cli_confbridge_list(), handle_cli_confbridge_list_item(), handle_cli_confbridge_lock(), handle_cli_confbridge_show_bridge_profile(), handle_cli_confbridge_show_bridge_profiles(), handle_cli_confbridge_show_menu(), handle_cli_confbridge_show_menus(), handle_cli_confbridge_show_user_profile(), handle_cli_confbridge_show_user_profiles(), handle_cli_confbridge_start_record(), handle_cli_confbridge_stop_record(), handle_cli_confbridge_unlock(), 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_debug(), 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_context(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_remove_ignorepat(), handle_cli_dialplan_remove_include(), handle_cli_dialplan_save(), handle_cli_dynamic_level_test(), handle_cli_file_convert(), 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_mobile_cusd(), handle_cli_mobile_rfcomm(), handle_cli_mobile_search(), handle_cli_mobile_show_devices(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_cli_odbc_show(), handle_cli_ooh323_set_debug(), handle_cli_ooh323_show_config(), handle_cli_ooh323_show_gk(), handle_cli_ooh323_show_peer(), handle_cli_ooh323_show_peers(), handle_cli_ooh323_show_user(), handle_cli_ooh323_show_users(), handle_cli_osp_show(), handle_cli_performance_test(), handle_cli_presencestate_change(), handle_cli_presencestate_list(), handle_cli_realtime_mysql_cache(), handle_cli_realtime_mysql_status(), handle_cli_realtime_pgsql_cache(), handle_cli_realtime_pgsql_status(), handle_cli_recalc(), handle_cli_refresh(), handle_cli_rtcp_set_debug(), handle_cli_rtcp_set_stats(), handle_cli_rtp_set_debug(), handle_cli_sched_bench(), handle_cli_show_config(), handle_cli_show_permissions(), handle_cli_show_sqlite_status(), handle_cli_sound_show(), handle_cli_sounds_show(), handle_cli_sqlite_show_tables(), handle_cli_status(), handle_cli_stun_set_debug(), handle_cli_submit(), handle_cli_test_locales(), handle_cli_transcoder_show(), handle_cli_udptl_set_debug(), handle_cli_ulimit(), handle_cli_wait_fullybooted(), handle_commandcomplete(), handle_commandmatchesarray(), handle_commandnummatches(), handle_core_set_debug_channel(), handle_core_show_image_formats(), handle_dahdi_show_cadences(), handle_debug(), handle_debug_dialplan(), handle_feature_show(), handle_help(), handle_load(), handle_logger_add_channel(), handle_logger_reload(), handle_logger_remove_channel(), handle_logger_rotate(), handle_logger_set_level(), handle_logger_show_channels(), handle_manager_show_settings(), handle_mandebug(), handle_mgcp_audit_endpoint(), handle_mgcp_set_debug(), 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_pjsip_list_ciphers(), handle_pjsip_show_version(), handle_queue_add_member(), handle_queue_pause_member(), handle_queue_remove_member(), handle_queue_rule_show(), handle_queue_set_member_penalty(), handle_queue_set_member_ringinuse(), handle_redirect(), handle_reload(), handle_restart_when_convenient(), handle_set_chanvar(), handle_set_extenpatternmatchnew(), handle_set_global(), handle_show_application(), handle_show_applications(), handle_show_calendar(), handle_show_calendars(), handle_show_calendars_types(), handle_show_chanvar(), handle_show_dialplan(), handle_show_function(), handle_show_functions(), handle_show_globals(), handle_show_hangup_channel(), handle_show_hint(), handle_show_hints(), handle_show_http(), handle_show_parking_lot_cmd(), handle_show_profile(), handle_show_routes(), handle_show_settings(), handle_show_switches(), handle_show_threads(), handle_show_translation_path(), handle_show_translation_table(), handle_show_version_files(), handle_showcalls(), handle_showchan(), handle_showmanager(), handle_showmanagers(), handle_showmancmd(), handle_showmancmds(), handle_showmanconn(), handle_showmaneventq(), handle_skel_show_config(), handle_skel_show_games(), handle_skel_show_levels(), handle_skinny_show_settings(), handle_softhangup(), handle_stop_when_convenient(), handle_unload(), handle_unset_extenpatternmatchnew(), handle_version(), handle_voicemail_reload(), handle_voicemail_show_users(), handle_voicemail_show_zones(), help1(), help_workhorse(), iax_show_provisioning(), locals_show(), meetme_show_cmd(), modlist_modentry(), orig_app(), orig_exten(), output_tests(), peer_dump_func(), pjsip_enable_logger_host(), pjsip_set_logger(), pktccops_debug(), pktccops_gatedel(), pktccops_gateset(), pktccops_show_cmtses(), pktccops_show_gates(), pktccops_show_pools(), print_app_docs(), print_applicationmap(), print_bc_info(), print_featuregroup(), print_featuregroups(), print_group(), print_named_groups(), print_stats_cb(), print_uptimestr(), realtime_ldap_status(), route_list_cb(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_chanstats_cb(), show_codec(), show_codecs(), show_config_description(), show_debug_helper(), show_dialplan_helper(), show_license(), show_sound_info_cb(), show_sounds_cb(), show_users_cb(), show_users_realtime(), show_warranty(), sip_cli_notify(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), 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_mwi(), 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(), spandsp_fax_cli_show_capabilities(), spandsp_fax_cli_show_session(), spandsp_fax_cli_show_stats(), status_debug_verbose(), timing_test(), unistim_do_debug(), unistim_show_devices(), unistim_show_info(), unistim_sp(), xmpp_cli_create_collection(), xmpp_cli_create_leafnode(), xmpp_cli_delete_pubsub_node(), xmpp_cli_list_pubsub_nodes(), xmpp_cli_purge_pubsub_nodes(), xmpp_do_set_debug(), xmpp_show_buddies(), and xmpp_show_clients().

00116 {
00117    int res;
00118    struct ast_str *buf;
00119    va_list ap;
00120 
00121    if (!(buf = ast_str_thread_get(&ast_cli_buf, AST_CLI_INITLEN)))
00122       return;
00123 
00124    va_start(ap, fmt);
00125    res = ast_str_set_va(&buf, 0, fmt, ap);
00126    va_end(ap);
00127 
00128    if (res != AST_DYNSTR_BUILD_FAILED) {
00129       ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
00130    }
00131 }

int ast_cli_command_full ( int  uid,
int  gid,
int  fd,
const char *  s 
)

Interprets a command Interpret a command s, sending output to fd if uid:gid has permissions to run this command. uid = CLI_NO_PERMS to avoid checking user permissions gid = CLI_NO_PERMS to avoid checking group permissions.

Parameters:
uid User ID that is trying to run the command.
gid Group ID that is trying to run the command.
fd pipe
s incoming string
Return values:
0 on success
-1 on failure

Definition at line 2677 of file main/cli.c.

References args, ast_atomic_fetchadd_int(), ast_cli(), ast_free, ast_join, AST_MAX_ARGS, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_FAILURE, CLI_HANDLER, cli_has_permissions(), CLI_SHOWUSAGE, e, ast_cli_args::fd, find_best(), find_cli(), ast_cli_entry::handler, ast_cli_entry::inuse, NULL, parse_args(), retval, S_OR, tmp(), and ast_cli_entry::usage.

Referenced by ast_cli_command_multiple_full().

02678 {
02679    const char *args[AST_MAX_ARGS + 1];
02680    struct ast_cli_entry *e;
02681    int x;
02682    char *duplicate = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL);
02683    char tmp[AST_MAX_ARGS + 1];
02684    char *retval = NULL;
02685    struct ast_cli_args a = {
02686       .fd = fd, .argc = x, .argv = args+1 };
02687 
02688    if (duplicate == NULL)
02689       return -1;
02690 
02691    if (x < 1)  /* We need at least one entry, otherwise ignore */
02692       goto done;
02693 
02694    AST_RWLIST_RDLOCK(&helpers);
02695    e = find_cli(args + 1, 0);
02696    if (e)
02697       ast_atomic_fetchadd_int(&e->inuse, 1);
02698    AST_RWLIST_UNLOCK(&helpers);
02699    if (e == NULL) {
02700       ast_cli(fd, "No such command '%s' (type 'core show help %s' for other possible commands)\n", s, find_best(args + 1));
02701       goto done;
02702    }
02703 
02704    ast_join(tmp, sizeof(tmp), args + 1);
02705    /* Check if the user has rights to run this command. */
02706    if (!cli_has_permissions(uid, gid, tmp)) {
02707       ast_cli(fd, "You don't have permissions to run '%s' command\n", tmp);
02708       ast_free(duplicate);
02709       return 0;
02710    }
02711 
02712    /*
02713     * Within the handler, argv[-1] contains a pointer to the ast_cli_entry.
02714     * Remember that the array returned by parse_args is NULL-terminated.
02715     */
02716    args[0] = (char *)e;
02717 
02718    retval = e->handler(e, CLI_HANDLER, &a);
02719 
02720    if (retval == CLI_SHOWUSAGE) {
02721       ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
02722    } else {
02723       if (retval == CLI_FAILURE)
02724          ast_cli(fd, "Command '%s' failed.\n", s);
02725    }
02726    ast_atomic_fetchadd_int(&e->inuse, -1);
02727 done:
02728    ast_free(duplicate);
02729    return 0;
02730 }

int ast_cli_command_multiple_full ( int  uid,
int  gid,
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 if uid has permissions, uid = CLI_NO_PERMS to avoid checking users permissions. gid = CLI_NO_PERMS to avoid checking group permissions.

Parameters:
uid User ID that is trying to run the command.
gid Group ID that is trying to run the command.
fd pipe
size is the total size of the string
s incoming string
Return values:
number of commands executed

Definition at line 2732 of file main/cli.c.

References ast_cli_command_full().

Referenced by netconsole().

02733 {
02734    char cmd[512];
02735    int x, y = 0, count = 0;
02736 
02737    for (x = 0; x < size; x++) {
02738       cmd[y] = s[x];
02739       y++;
02740       if (s[x] == '\0') {
02741          ast_cli_command_full(uid, gid, fd, cmd);
02742          y = 0;
02743          count++;
02744       }
02745    }
02746    return count;
02747 }

char* ast_cli_complete ( const char *  word,
const 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 const char * const choices[] = { "one", "two", "three", NULL };
   if (pos == 2)
         return ast_cli_complete(word, choices, n);
   else
      return NULL;
    }

Definition at line 1685 of file main/cli.c.

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

Referenced by handle_cc_kill(), handle_cli_core_show_translation(), handle_cli_devstate_change(), handle_cli_iax2_prune_realtime(), handle_cli_presencestate_change(), handle_orig(), handle_show_applications(), and sip_prune_realtime().

01686 {
01687    int i, which = 0, len;
01688    len = ast_strlen_zero(word) ? 0 : strlen(word);
01689 
01690    for (i = 0; choices[i]; i++) {
01691       if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state)
01692          return ast_strdup(choices[i]);
01693    }
01694    return NULL;
01695 }

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 2515 of file main/cli.c.

References ast_cli_generator(), ast_copy_string(), ast_free, ast_malloc, ast_realloc, destroy_match_list(), and NULL.

Referenced by cli_complete(), and handle_commandmatchesarray().

02516 {
02517    char **match_list = NULL, *retstr, *prevstr;
02518    char **new_list;
02519    size_t match_list_len, max_equal, which, i;
02520    int matches = 0;
02521 
02522    /* leave entry 0 free for the longest common substring */
02523    match_list_len = 1;
02524    while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
02525       if (matches + 1 >= match_list_len) {
02526          match_list_len <<= 1;
02527          new_list = ast_realloc(match_list, match_list_len * sizeof(*match_list));
02528          if (!new_list) {
02529             destroy_match_list(match_list, matches);
02530             return NULL;
02531          }
02532          match_list = new_list;
02533       }
02534       match_list[++matches] = retstr;
02535    }
02536 
02537    if (!match_list) {
02538       return match_list; /* NULL */
02539    }
02540 
02541    /* Find the longest substring that is common to all results
02542     * (it is a candidate for completion), and store a copy in entry 0.
02543     */
02544    prevstr = match_list[1];
02545    max_equal = strlen(prevstr);
02546    for (which = 2; which <= matches; which++) {
02547       for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
02548          continue;
02549       max_equal = i;
02550    }
02551 
02552    retstr = ast_malloc(max_equal + 1);
02553    if (!retstr) {
02554       destroy_match_list(match_list, matches);
02555       return NULL;
02556    }
02557    ast_copy_string(retstr, match_list[1], max_equal + 1);
02558    match_list[0] = retstr;
02559 
02560    /* ensure that the array is NULL terminated */
02561    if (matches + 1 >= match_list_len) {
02562       new_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list));
02563       if (!new_list) {
02564          ast_free(retstr);
02565          destroy_match_list(match_list, matches);
02566          return NULL;
02567       }
02568       match_list = new_list;
02569    }
02570    match_list[matches + 1] = NULL;
02571 
02572    return match_list;
02573 }

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 2672 of file main/cli.c.

References __ast_cli_generator().

Referenced by ast_cli_completion_matches(), ast_cli_generatornummatches(), AST_TEST_DEFINE(), cli_alias_passthrough(), and handle_cli_check_permissions().

02673 {
02674    return __ast_cli_generator(text, word, state, 1);
02675 }

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

Return the number of unique matches for the generator.

Definition at line 2486 of file main/cli.c.

References ast_cli_generator(), ast_free, buf, and NULL.

Referenced by handle_commandnummatches().

02487 {
02488    int matches = 0, i = 0;
02489    char *buf = NULL, *oldbuf = NULL;
02490 
02491    while ((buf = ast_cli_generator(text, word, i++))) {
02492       if (!oldbuf || strcmp(buf,oldbuf))
02493          matches++;
02494       if (oldbuf)
02495          ast_free(oldbuf);
02496       oldbuf = buf;
02497    }
02498    if (oldbuf)
02499       ast_free(oldbuf);
02500    return matches;
02501 }

int ast_cli_perms_init ( int  reload  ) 

Provided by cli.c

Definition at line 1898 of file main/cli.c.

References ast_calloc, ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log, ast_mutex_trylock, ast_mutex_unlock, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_strlen_zero, ast_variable_browse(), cli_perm::command, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, destroy_user_perms(), usergroup_cli_perm::gid, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, cli_perm::permit, usergroup_cli_perm::perms, perms_config, usergroup_cli_perm::uid, and ast_variable::value.

Referenced by handle_cli_reload_permissions(), and main().

01899 {
01900    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
01901    struct ast_config *cfg;
01902    char *cat = NULL;
01903    struct ast_variable *v;
01904    struct usergroup_cli_perm *user_group, *cp_entry;
01905    struct cli_perm *perm = NULL;
01906    struct passwd *pw;
01907    struct group *gr;
01908 
01909    if (ast_mutex_trylock(&permsconfiglock)) {
01910       ast_log(LOG_NOTICE, "You must wait until last 'cli reload permissions' command finish\n");
01911       return 1;
01912    }
01913 
01914    cfg = ast_config_load2(perms_config, "" /* core, can't reload */, config_flags);
01915    if (!cfg) {
01916       ast_mutex_unlock(&permsconfiglock);
01917       return 1;
01918    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
01919       ast_mutex_unlock(&permsconfiglock);
01920       return 0;
01921    }
01922 
01923    /* free current structures. */
01924    destroy_user_perms();
01925 
01926    while ((cat = ast_category_browse(cfg, cat))) {
01927       if (!strcasecmp(cat, "general")) {
01928          /* General options */
01929          for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
01930             if (!strcasecmp(v->name, "default_perm")) {
01931                cli_default_perm = (!strcasecmp(v->value, "permit")) ? 1: 0;
01932             }
01933          }
01934          continue;
01935       }
01936 
01937       /* users or groups */
01938       gr = NULL, pw = NULL;
01939       if (cat[0] == '@') {
01940          /* This is a group */
01941          gr = getgrnam(&cat[1]);
01942          if (!gr) {
01943             ast_log (LOG_WARNING, "Unknown group '%s'\n", &cat[1]);
01944             continue;
01945          }
01946       } else {
01947          /* This is a user */
01948          pw = getpwnam(cat);
01949          if (!pw) {
01950             ast_log (LOG_WARNING, "Unknown user '%s'\n", cat);
01951             continue;
01952          }
01953       }
01954       user_group = NULL;
01955       /* Check for duplicates */
01956       AST_RWLIST_WRLOCK(&cli_perms);
01957       AST_LIST_TRAVERSE(&cli_perms, cp_entry, list) {
01958          if ((pw && cp_entry->uid == pw->pw_uid) || (gr && cp_entry->gid == gr->gr_gid)) {
01959             /* if it is duplicated, just added this new settings, to
01960             the current list. */
01961             user_group = cp_entry;
01962             break;
01963          }
01964       }
01965       AST_RWLIST_UNLOCK(&cli_perms);
01966 
01967       if (!user_group) {
01968          /* alloc space for the new user config. */
01969          user_group = ast_calloc(1, sizeof(*user_group));
01970          if (!user_group) {
01971             continue;
01972          }
01973          user_group->uid = (pw ? pw->pw_uid : -1);
01974          user_group->gid = (gr ? gr->gr_gid : -1);
01975          user_group->perms = ast_calloc(1, sizeof(*user_group->perms));
01976          if (!user_group->perms) {
01977             ast_free(user_group);
01978             continue;
01979          }
01980       }
01981       for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
01982          if (ast_strlen_zero(v->value)) {
01983             /* we need to check this condition cause it could break security. */
01984             ast_log(LOG_WARNING, "Empty permit/deny option in user '%s'\n", cat);
01985             continue;
01986          }
01987          if (!strcasecmp(v->name, "permit")) {
01988             perm = ast_calloc(1, sizeof(*perm));
01989             if (perm) {
01990                perm->permit = 1;
01991                perm->command = ast_strdup(v->value);
01992             }
01993          } else if (!strcasecmp(v->name, "deny")) {
01994             perm = ast_calloc(1, sizeof(*perm));
01995             if (perm) {
01996                perm->permit = 0;
01997                perm->command = ast_strdup(v->value);
01998             }
01999          } else {
02000             /* up to now, only 'permit' and 'deny' are possible values. */
02001             ast_log(LOG_WARNING, "Unknown '%s' option\n", v->name);
02002             continue;
02003          }
02004          if (perm) {
02005             /* Added the permission to the user's list. */
02006             AST_LIST_INSERT_TAIL(user_group->perms, perm, list);
02007             perm = NULL;
02008          }
02009       }
02010       AST_RWLIST_WRLOCK(&cli_perms);
02011       AST_RWLIST_INSERT_TAIL(&cli_perms, user_group, list);
02012       AST_RWLIST_UNLOCK(&cli_perms);
02013    }
02014 
02015    ast_config_destroy(cfg);
02016    ast_mutex_unlock(&permsconfiglock);
02017    return 0;
02018 }

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 2305 of file main/cli.c.

References __ast_cli_register(), and NULL.

Referenced by ast_cel_engine_init(), ast_cli_register_multiple(), dnsmgr_init(), load_config(), and load_module().

02306 {
02307    return __ast_cli_register(e, NULL);
02308 }

int ast_cli_register_multiple ( struct ast_cli_entry e,
int  len 
)

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 2299 of file main/cli.c.

References __ast_cli_unregister(), and NULL.

Referenced by alias_unregister_cb(), ast_cli_unregister_multiple(), cel_engine_cleanup(), dnsmgr_shutdown(), and unload_module().

02300 {
02301    return __ast_cli_unregister(e, NULL);
02302 }

int ast_cli_unregister_multiple ( struct ast_cli_entry e,
int  len 
)

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 1697 of file main/cli.c.

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_cache(), ast_channel_snapshot_type(), ast_strdup, ast_channel_snapshot::name, NULL, RAII_VAR, stasis_cache_dump(), and stasis_message_data().

Referenced by complete_ch(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_core_set_debug_channel(), handle_redirect(), handle_set_chanvar(), handle_show_chanvar(), handle_show_hangup_all(), handle_show_hangup_channel(), handle_showchan(), and handle_softhangup().

01698 {
01699    int wordlen = strlen(word), which = 0;
01700    RAII_VAR(struct ao2_container *, cached_channels, NULL, ao2_cleanup);
01701    char *ret = NULL;
01702    struct ao2_iterator iter;
01703    struct stasis_message *msg;
01704 
01705    if (pos != rpos) {
01706       return NULL;
01707    }
01708 
01709    if (!(cached_channels = stasis_cache_dump(ast_channel_cache(), ast_channel_snapshot_type()))) {
01710       return NULL;
01711    }
01712 
01713    iter = ao2_iterator_init(cached_channels, 0);
01714    for (; (msg = ao2_iterator_next(&iter)); ao2_ref(msg, -1)) {
01715       struct ast_channel_snapshot *snapshot = stasis_message_data(msg);
01716 
01717       if (!strncasecmp(word, snapshot->name, wordlen) && (++which > state)) {
01718          ret = ast_strdup(snapshot->name);
01719          ao2_ref(msg, -1);
01720          break;
01721       }
01722    }
01723    ao2_iterator_destroy(&iter);
01724 
01725    return ret;
01726 }

unsigned int ast_debug_get_by_module ( const char *  module  ) 

Get the debug level for a module.

Parameters:
module the name of module
Returns:
the debug level

Definition at line 133 of file main/cli.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, debug_modules, module_level::level, and module_level::module.

Referenced by log_cb().

00134 {
00135    struct module_level *ml;
00136    unsigned int res = 0;
00137 
00138    AST_RWLIST_RDLOCK(&debug_modules);
00139    AST_LIST_TRAVERSE(&debug_modules, ml, entry) {
00140       if (!strcasecmp(ml->module, module)) {
00141          res = ml->level;
00142          break;
00143       }
00144    }
00145    AST_RWLIST_UNLOCK(&debug_modules);
00146 
00147    return res;
00148 }

unsigned int ast_verbose_get_by_module ( const char *  module  ) 

Get the verbose level for a module.

Parameters:
module the name of module
Returns:
the verbose level
Version:
11.0.0 deprecated

Definition at line 150 of file main/cli.c.

00151 {
00152    return 0;
00153 }

static int channel_set_debug ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 1409 of file main/cli.c.

References args, ast_channel_fin(), ast_channel_fin_set(), ast_channel_fout(), ast_channel_fout_set(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_cli(), DEBUGCHAN_FLAG, channel_set_debug_args::fd, and channel_set_debug_args::is_off.

Referenced by handle_core_set_debug_channel().

01410 {
01411    struct ast_channel *chan = obj;
01412    struct channel_set_debug_args *args = data;
01413 
01414    ast_channel_lock(chan);
01415 
01416    if (!(ast_channel_fin(chan) & DEBUGCHAN_FLAG) || !(ast_channel_fout(chan) & DEBUGCHAN_FLAG)) {
01417       if (args->is_off) {
01418          ast_channel_fin_set(chan, ast_channel_fin(chan) & ~DEBUGCHAN_FLAG);
01419          ast_channel_fout_set(chan, ast_channel_fout(chan) & ~DEBUGCHAN_FLAG);
01420       } else {
01421          ast_channel_fin_set(chan, ast_channel_fin(chan) | DEBUGCHAN_FLAG);
01422          ast_channel_fout_set(chan, ast_channel_fout(chan) | DEBUGCHAN_FLAG);
01423       }
01424       ast_cli(args->fd, "Debugging %s on channel %s\n", args->is_off ? "disabled" : "enabled",
01425             ast_channel_name(chan));
01426    }
01427 
01428    ast_channel_unlock(chan);
01429 
01430    return 0;
01431 }

static int cli_has_permissions ( int  uid,
int  gid,
const char *  command 
) [static]

Definition at line 168 of file main/cli.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_NO_PERMS, cli_perm::command, usergroup_cli_perm::gid, NULL, cli_perm::permit, usergroup_cli_perm::perms, and usergroup_cli_perm::uid.

Referenced by ast_cli_command_full(), and handle_cli_check_permissions().

00169 {
00170    struct usergroup_cli_perm *user_perm;
00171    struct cli_perm *perm;
00172    /* set to the default permissions general option. */
00173    int isallowg = cli_default_perm, isallowu = -1, ispattern;
00174    regex_t regexbuf;
00175 
00176    /* if uid == -1 or gid == -1 do not check permissions.
00177       if uid == -2 and gid == -2 is because rasterisk client didn't send
00178       the credentials, so the cli_default_perm will be applied. */
00179    if ((uid == CLI_NO_PERMS && gid == CLI_NO_PERMS) || command[0] == '_') {
00180       return 1;
00181    }
00182 
00183    if (gid < 0 && uid < 0) {
00184       return cli_default_perm;
00185    }
00186 
00187    AST_RWLIST_RDLOCK(&cli_perms);
00188    AST_LIST_TRAVERSE(&cli_perms, user_perm, list) {
00189       if (user_perm->gid != gid && user_perm->uid != uid) {
00190          continue;
00191       }
00192       AST_LIST_TRAVERSE(user_perm->perms, perm, list) {
00193          if (strcasecmp(perm->command, "all") && strncasecmp(perm->command, command, strlen(perm->command))) {
00194             /* if the perm->command is a pattern, check it against command. */
00195             ispattern = !regcomp(&regexbuf, perm->command, REG_EXTENDED | REG_NOSUB | REG_ICASE);
00196             if (ispattern && regexec(&regexbuf, command, 0, NULL, 0)) {
00197                regfree(&regexbuf);
00198                continue;
00199             }
00200             if (!ispattern) {
00201                continue;
00202             }
00203             regfree(&regexbuf);
00204          }
00205          if (user_perm->uid == uid) {
00206             /* this is a user definition. */
00207             isallowu = perm->permit;
00208          } else {
00209             /* otherwise is a group definition. */
00210             isallowg = perm->permit;
00211          }
00212       }
00213    }
00214    AST_RWLIST_UNLOCK(&cli_perms);
00215    if (isallowu > -1) {
00216       /* user definition override group definition. */
00217       isallowg = isallowu;
00218    }
00219 
00220    return isallowg;
00221 }

static int cli_is_registered ( struct ast_cli_entry e  )  [static]

Definition at line 2194 of file main/cli.c.

References cli_next(), and NULL.

Referenced by __ast_cli_register().

02195 {
02196    struct ast_cli_entry *cur = NULL;
02197 
02198    while ((cur = cli_next(cur))) {
02199       if (cur == e) {
02200          return 1;
02201       }
02202    }
02203    return 0;
02204 }

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

Definition at line 845 of file main/cli.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

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

00846 {
00847    if (e) {
00848       return AST_LIST_NEXT(e, list);
00849    } else {
00850       return AST_LIST_FIRST(&helpers);
00851    }
00852 }

static void cli_shutdown ( void   )  [static]

Definition at line 2020 of file main/cli.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by ast_builtins_init().

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

Definition at line 225 of file main/cli.c.

References ast_config_AST_MODULE_DIR, ast_copy_string(), ast_std_free, ast_strdup, c, d, and filename_completion_function().

Referenced by handle_load().

00226 {
00227    char *c, *d;
00228    char filename[PATH_MAX];
00229 
00230    if (word[0] == '/')
00231       ast_copy_string(filename, word, sizeof(filename));
00232    else
00233       snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word);
00234 
00235    c = d = filename_completion_function(filename, state);
00236 
00237    if (c && word[0] != '/')
00238       c += (strlen(ast_config_AST_MODULE_DIR) + 1);
00239    if (c)
00240       c = ast_strdup(c);
00241 
00242    ast_std_free(d);
00243 
00244    return c;
00245 }

static char* complete_number ( const char *  partial,
unsigned int  min,
unsigned int  max,
int  n 
) [static]

Definition at line 368 of file main/cli.c.

References ast_strdup, ast_strlen_zero, cli_perm::next, and NULL.

Referenced by handle_debug(), and handle_verbose().

00369 {
00370    int i, count = 0;
00371    unsigned int prospective[2];
00372    unsigned int part = strtoul(partial, NULL, 10);
00373    char next[12];
00374 
00375    if (part < min || part > max) {
00376       return NULL;
00377    }
00378 
00379    for (i = 0; i < 21; i++) {
00380       if (i == 0) {
00381          prospective[0] = prospective[1] = part;
00382       } else if (part == 0 && !ast_strlen_zero(partial)) {
00383          break;
00384       } else if (i < 11) {
00385          prospective[0] = prospective[1] = part * 10 + (i - 1);
00386       } else {
00387          prospective[0] = (part * 10 + (i - 11)) * 10;
00388          prospective[1] = prospective[0] + 9;
00389       }
00390       if (i < 11 && (prospective[0] < min || prospective[0] > max)) {
00391          continue;
00392       } else if (prospective[1] < min || prospective[0] > max) {
00393          continue;
00394       }
00395 
00396       if (++count > n) {
00397          if (i < 11) {
00398             snprintf(next, sizeof(next), "%u", prospective[0]);
00399          } else {
00400             snprintf(next, sizeof(next), "%u...", prospective[0] / 10);
00401          }
00402          return ast_strdup(next);
00403       }
00404    }
00405    return NULL;
00406 }

static void destroy_match_list ( char **  match_list,
int  matches 
) [static]

Definition at line 2503 of file main/cli.c.

References ast_free.

02504 {
02505    if (match_list) {
02506       int idx;
02507 
02508       for (idx = 1; idx < matches; ++idx) {
02509          ast_free(match_list[idx]);
02510       }
02511       ast_free(match_list);
02512    }
02513 }

static void destroy_user_perms ( void   )  [static]

cleanup (free) cli_perms linkedlist.

Definition at line 1882 of file main/cli.c.

References ast_free, AST_LIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cli_perm::command, and usergroup_cli_perm::perms.

Referenced by ast_cli_perms_init().

01883 {
01884    struct cli_perm *perm;
01885    struct usergroup_cli_perm *user_perm;
01886 
01887    AST_RWLIST_WRLOCK(&cli_perms);
01888    while ((user_perm = AST_LIST_REMOVE_HEAD(&cli_perms, list))) {
01889       while ((perm = AST_LIST_REMOVE_HEAD(user_perm->perms, list))) {
01890          ast_free(perm->command);
01891          ast_free(perm);
01892       }
01893       ast_free(user_perm);
01894    }
01895    AST_RWLIST_UNLOCK(&cli_perms);
01896 }

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

Definition at line 2176 of file main/cli.c.

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

02177 {
02178    static char cmdline[80];
02179    int x;
02180    /* See how close we get, then print the candidate */
02181    const char *myargv[AST_MAX_CMD_LEN] = { NULL, };
02182 
02183    AST_RWLIST_RDLOCK(&helpers);
02184    for (x = 0; argv[x]; x++) {
02185       myargv[x] = argv[x];
02186       if (!find_cli(myargv, -1))
02187          break;
02188    }
02189    AST_RWLIST_UNLOCK(&helpers);
02190    ast_join(cmdline, sizeof(cmdline), myargv);
02191    return cmdline;
02192 }

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

Definition at line 2132 of file main/cli.c.

References ast_strlen_zero, cli_next(), e, NULL, and word_match().

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

02133 {
02134    int matchlen = -1;   /* length of longest match so far */
02135    struct ast_cli_entry *cand = NULL, *e=NULL;
02136 
02137    while ( (e = cli_next(e)) ) {
02138       /* word-by word regexp comparison */
02139       const char * const *src = cmds;
02140       const char * const *dst = e->cmda;
02141       int n = 0;
02142       for (;; dst++, src += n) {
02143          n = word_match(*src, *dst);
02144          if (n < 0)
02145             break;
02146       }
02147       if (ast_strlen_zero(*dst) || ((*dst)[0] == '[' && ast_strlen_zero(dst[1]))) {
02148          /* no more words in 'e' */
02149          if (ast_strlen_zero(*src)) /* exact match, cannot do better */
02150             break;
02151          /* Here, cmds has more words than the entry 'e' */
02152          if (match_type != 0) /* but we look for almost exact match... */
02153             continue;   /* so we skip this one. */
02154          /* otherwise we like it (case 0) */
02155       } else { /* still words in 'e' */
02156          if (ast_strlen_zero(*src))
02157             continue; /* cmds is shorter than 'e', not good */
02158          /* Here we have leftover words in cmds and 'e',
02159           * but there is a mismatch. We only accept this one if match_type == -1
02160           * and this is the last word for both.
02161           */
02162          if (match_type != -1 || !ast_strlen_zero(src[1]) ||
02163              !ast_strlen_zero(dst[1])) /* not the one we look for */
02164             continue;
02165          /* good, we are in case match_type == -1 and mismatch on last word */
02166       }
02167       if (src - cmds > matchlen) {  /* remember the candidate */
02168          matchlen = src - cmds;
02169          cand = e;
02170       }
02171    }
02172 
02173    return e ? e : cand;
02174 }

static struct module_level* find_module_level ( const char *  module,
struct module_level_list mll 
) [static, read]

Find the module level setting.

Parameters:
module Module name to look for.
mll List to search.
Return values:
level struct found on success.
NULL not found.

Definition at line 356 of file main/cli.c.

References AST_LIST_TRAVERSE, module_level::module, and NULL.

Referenced by handle_debug().

00357 {
00358    struct module_level *ml;
00359 
00360    AST_LIST_TRAVERSE(mll, ml, entry) {
00361       if (!strcasecmp(ml->module, module))
00362          return ml;
00363    }
00364 
00365    return NULL;
00366 }

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

Definition at line 1728 of file main/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_channel_name(), ast_cli(), AST_LIST_NEXT, ast_strlen_zero, ast_group_info::category, ast_group_info::chan, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ESS, ast_cli_args::fd, FORMAT_STRING, ast_group_info::group, ast_group_info::group_list, NULL, and ast_cli_entry::usage.

01729 {
01730 #define FORMAT_STRING  "%-25s  %-20s  %-20s\n"
01731 
01732    struct ast_group_info *gi = NULL;
01733    int numchans = 0;
01734    regex_t regexbuf;
01735    int havepattern = 0;
01736 
01737    switch (cmd) {
01738    case CLI_INIT:
01739       e->command = "group show channels";
01740       e->usage =
01741          "Usage: group show channels [pattern]\n"
01742          "       Lists all currently active channels with channel group(s) specified.\n"
01743          "       Optional regular expression pattern is matched to group names for each\n"
01744          "       channel.\n";
01745       return NULL;
01746    case CLI_GENERATE:
01747       return NULL;
01748    }
01749 
01750    if (a->argc < 3 || a->argc > 4)
01751       return CLI_SHOWUSAGE;
01752 
01753    if (a->argc == 4) {
01754       if (regcomp(&regexbuf, a->argv[3], REG_EXTENDED | REG_NOSUB))
01755          return CLI_SHOWUSAGE;
01756       havepattern = 1;
01757    }
01758 
01759    ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category");
01760 
01761    ast_app_group_list_rdlock();
01762 
01763    gi = ast_app_group_list_head();
01764    while (gi) {
01765       if (!havepattern || !regexec(&regexbuf, gi->group, 0, NULL, 0)) {
01766          ast_cli(a->fd, FORMAT_STRING, ast_channel_name(gi->chan), gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category));
01767          numchans++;
01768       }
01769       gi = AST_LIST_NEXT(gi, group_list);
01770    }
01771 
01772    ast_app_group_list_unlock();
01773 
01774    if (havepattern)
01775       regfree(&regexbuf);
01776 
01777    ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
01778    return CLI_SUCCESS;
01779 #undef FORMAT_STRING
01780 }

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

Definition at line 979 of file main/cli.c.

References ast_channel_snapshot::accountcode, ast_channel_snapshot::amaflags, ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_snapshot::appl, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_active_channels(), ast_channel_cache_by_name(), ast_channel_snapshot_type(), ast_cli(), ast_option_maxcalls, ast_processed_calls(), ast_state2str(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_channel_snapshot::bridgeid, ast_channel_snapshot::caller_number, channels, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, CONCISE_FORMAT_STRING, ast_channel_snapshot::context, ast_channel_snapshot::creationtime, ast_channel_snapshot::data, ESS, ast_channel_snapshot::exten, ast_cli_args::fd, FORMAT_STRING, FORMAT_STRING2, ast_channel_snapshot::name, NULL, ast_channel_snapshot::peeraccount, ast_channel_snapshot::priority, RAII_VAR, S_OR, stasis_cache_dump(), stasis_message_data(), ast_channel_snapshot::state, ast_channel_snapshot::uniqueid, ast_cli_entry::usage, VERBOSE_FORMAT_STRING, and VERBOSE_FORMAT_STRING2.

00980 {
00981 #define FORMAT_STRING  "%-20.20s %-20.20s %-7.7s %-30.30s\n"
00982 #define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n"
00983 #define CONCISE_FORMAT_STRING  "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
00984 #define VERBOSE_FORMAT_STRING  "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
00985 #define VERBOSE_FORMAT_STRING2 "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
00986 
00987    RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);
00988    struct ao2_iterator it_chans;
00989    struct stasis_message *msg;
00990    int numchans = 0, concise = 0, verbose = 0, count = 0;
00991 
00992    switch (cmd) {
00993    case CLI_INIT:
00994       e->command = "core show channels [concise|verbose|count]";
00995       e->usage =
00996          "Usage: core show channels [concise|verbose|count]\n"
00997          "       Lists currently defined channels and some information about them. If\n"
00998          "       'concise' is specified, the format is abridged and in a more easily\n"
00999          "       machine parsable format. If 'verbose' is specified, the output includes\n"
01000          "       more and longer fields. If 'count' is specified only the channel and call\n"
01001          "       count is output.\n"
01002          "  The 'concise' option is deprecated and will be removed from future versions\n"
01003          "  of Asterisk.\n";
01004       return NULL;
01005 
01006    case CLI_GENERATE:
01007       return NULL;
01008    }
01009 
01010    if (a->argc == e->args) {
01011       if (!strcasecmp(a->argv[e->args-1],"concise"))
01012          concise = 1;
01013       else if (!strcasecmp(a->argv[e->args-1],"verbose"))
01014          verbose = 1;
01015       else if (!strcasecmp(a->argv[e->args-1],"count"))
01016          count = 1;
01017       else
01018          return CLI_SHOWUSAGE;
01019    } else if (a->argc != e->args - 1)
01020       return CLI_SHOWUSAGE;
01021 
01022 
01023    if (!(channels = stasis_cache_dump(ast_channel_cache_by_name(), ast_channel_snapshot_type()))) {
01024       ast_cli(a->fd, "Failed to retrieve cached channels\n");
01025       return CLI_SUCCESS;
01026    }
01027 
01028    if (!count) {
01029       if (!concise && !verbose)
01030          ast_cli(a->fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)");
01031       else if (verbose)
01032          ast_cli(a->fd, VERBOSE_FORMAT_STRING2, "Channel", "Context", "Extension", "Priority", "State", "Application", "Data",
01033             "CallerID", "Duration", "Accountcode", "PeerAccount", "BridgeID");
01034    }
01035 
01036    it_chans = ao2_iterator_init(channels, 0);
01037    for (; (msg = ao2_iterator_next(&it_chans)); ao2_ref(msg, -1)) {
01038       struct ast_channel_snapshot *cs = stasis_message_data(msg);
01039       char durbuf[10] = "-";
01040 
01041       if (!count) {
01042          if ((concise || verbose)  && !ast_tvzero(cs->creationtime)) {
01043             int duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->creationtime) / 1000);
01044             if (verbose) {
01045                int durh = duration / 3600;
01046                int durm = (duration % 3600) / 60;
01047                int durs = duration % 60;
01048                snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
01049             } else {
01050                snprintf(durbuf, sizeof(durbuf), "%d", duration);
01051             }
01052          }
01053          if (concise) {
01054             ast_cli(a->fd, CONCISE_FORMAT_STRING, cs->name, cs->context, cs->exten, cs->priority, ast_state2str(cs->state),
01055                S_OR(cs->appl, "(None)"),
01056                cs->data,
01057                cs->caller_number,
01058                cs->accountcode,
01059                cs->peeraccount,
01060                cs->amaflags,
01061                durbuf,
01062                cs->bridgeid,
01063                cs->uniqueid);
01064          } else if (verbose) {
01065             ast_cli(a->fd, VERBOSE_FORMAT_STRING, cs->name, cs->context, cs->exten, cs->priority, ast_state2str(cs->state),
01066                S_OR(cs->appl, "(None)"),
01067                S_OR(cs->data, "(Empty)"),
01068                cs->caller_number,
01069                durbuf,
01070                cs->accountcode,
01071                cs->peeraccount,
01072                cs->bridgeid);
01073          } else {
01074             char locbuf[40] = "(None)";
01075             char appdata[40] = "(None)";
01076 
01077             if (!cs->context && !cs->exten)
01078                snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", cs->exten, cs->context, cs->priority);
01079             if (cs->appl)
01080                snprintf(appdata, sizeof(appdata), "%s(%s)", cs->appl, S_OR(cs->data, ""));
01081             ast_cli(a->fd, FORMAT_STRING, cs->name, locbuf, ast_state2str(cs->state), appdata);
01082          }
01083       }
01084    }
01085    ao2_iterator_destroy(&it_chans);
01086 
01087    if (!concise) {
01088       numchans = ast_active_channels();
01089       ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
01090       if (ast_option_maxcalls)
01091          ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
01092             ast_active_calls(), ast_option_maxcalls, ESS(ast_active_calls()),
01093             ((double)ast_active_calls() / (double)ast_option_maxcalls) * 100.0);
01094       else
01095          ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
01096 
01097       ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
01098    }
01099 
01100    return CLI_SUCCESS;
01101 
01102 #undef FORMAT_STRING
01103 #undef FORMAT_STRING2
01104 #undef CONCISE_FORMAT_STRING
01105 #undef VERBOSE_FORMAT_STRING
01106 #undef VERBOSE_FORMAT_STRING2
01107 }

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

handles CLI command 'cli check permissions'

Definition at line 1221 of file main/cli.c.

References ast_cli_entry::_full_cmd, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_generator(), ast_join, AST_MAX_ARGS, ast_strdupa, ast_strlen_zero, CLI_FAILURE, CLI_GENERATE, cli_has_permissions(), CLI_INIT, cli_next(), CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, cli_perm::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, S_OR, ast_cli_entry::summary, tmp(), ast_cli_entry::usage, and ast_cli_args::word.

01222 {
01223    struct passwd *pw = NULL;
01224    struct group *gr;
01225    int gid = -1, uid = -1;
01226    char command[AST_MAX_ARGS] = "";
01227    struct ast_cli_entry *ce = NULL;
01228    int found = 0;
01229    char *group, *tmp;
01230 
01231    switch (cmd) {
01232    case CLI_INIT:
01233       e->command = "cli check permissions";
01234       e->usage =
01235          "Usage: cli check permissions {<username>|@<groupname>|<username>@<groupname>} [<command>]\n"
01236          "       Check permissions config for a user@group or list the allowed commands for the specified user.\n"
01237          "       The username or the groupname may be omitted.\n";
01238       return NULL;
01239    case CLI_GENERATE:
01240       if (a->pos >= 4) {
01241          return ast_cli_generator(a->line + strlen("cli check permissions") + strlen(a->argv[3]) + 1, a->word, a->n);
01242       }
01243       return NULL;
01244    }
01245 
01246    if (a->argc < 4) {
01247       return CLI_SHOWUSAGE;
01248    }
01249 
01250    tmp = ast_strdupa(a->argv[3]);
01251    group = strchr(tmp, '@');
01252    if (group) {
01253       gr = getgrnam(&group[1]);
01254       if (!gr) {
01255          ast_cli(a->fd, "Unknown group '%s'\n", &group[1]);
01256          return CLI_FAILURE;
01257       }
01258       group[0] = '\0';
01259       gid = gr->gr_gid;
01260    }
01261 
01262    if (!group && ast_strlen_zero(tmp)) {
01263       ast_cli(a->fd, "You didn't supply a username\n");
01264    } else if (!ast_strlen_zero(tmp) && !(pw = getpwnam(tmp))) {
01265       ast_cli(a->fd, "Unknown user '%s'\n", tmp);
01266       return CLI_FAILURE;
01267    } else if (pw) {
01268       uid = pw->pw_uid;
01269    }
01270 
01271    if (a->argc == 4) {
01272       while ((ce = cli_next(ce))) {
01273          /* Hide commands that start with '_' */
01274          if (ce->_full_cmd[0] == '_') {
01275             continue;
01276          }
01277          if (cli_has_permissions(uid, gid, ce->_full_cmd)) {
01278             ast_cli(a->fd, "%30.30s %s\n", ce->_full_cmd, S_OR(ce->summary, "<no description available>"));
01279             found++;
01280          }
01281       }
01282       if (!found) {
01283          ast_cli(a->fd, "You are not allowed to run any command on Asterisk\n");
01284       }
01285    } else {
01286       ast_join(command, sizeof(command), a->argv + 4);
01287       ast_cli(a->fd, "%s '%s%s%s' is %s to run command: '%s'\n", uid >= 0 ? "User" : "Group", tmp,
01288          group && uid >= 0 ? "@" : "",
01289          group ? &group[1] : "",
01290          cli_has_permissions(uid, gid, command) ? "allowed" : "not allowed", command);
01291    }
01292 
01293    return CLI_SUCCESS;
01294 }

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

handles CLI command 'cli reload permissions'

Definition at line 1202 of file main/cli.c.

References ast_cli_perms_init(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

01203 {
01204    switch (cmd) {
01205    case CLI_INIT:
01206       e->command = "cli reload permissions";
01207       e->usage =
01208          "Usage: cli reload permissions\n"
01209          "       Reload the 'cli_permissions.conf' file.\n";
01210       return NULL;
01211    case CLI_GENERATE:
01212       return NULL;
01213    }
01214 
01215    ast_cli_perms_init(1);
01216 
01217    return CLI_SUCCESS;
01218 }

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

handles CLI command 'cli show permissions'

Definition at line 1157 of file main/cli.c.

References ast_cli(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, cli_perm::command, ast_cli_entry::command, ast_cli_args::fd, usergroup_cli_perm::gid, NULL, cli_perm::permit, usergroup_cli_perm::perms, usergroup_cli_perm::uid, and ast_cli_entry::usage.

01158 {
01159    struct usergroup_cli_perm *cp;
01160    struct cli_perm *perm;
01161    struct passwd *pw = NULL;
01162    struct group *gr = NULL;
01163 
01164    switch (cmd) {
01165    case CLI_INIT:
01166       e->command = "cli show permissions";
01167       e->usage =
01168          "Usage: cli show permissions\n"
01169          "       Shows CLI configured permissions.\n";
01170       return NULL;
01171    case CLI_GENERATE:
01172       return NULL;
01173    }
01174 
01175    AST_RWLIST_RDLOCK(&cli_perms);
01176    AST_LIST_TRAVERSE(&cli_perms, cp, list) {
01177       if (cp->uid >= 0) {
01178          pw = getpwuid(cp->uid);
01179          if (pw) {
01180             ast_cli(a->fd, "user: %s [uid=%d]\n", pw->pw_name, cp->uid);
01181          }
01182       } else {
01183          gr = getgrgid(cp->gid);
01184          if (gr) {
01185             ast_cli(a->fd, "group: %s [gid=%d]\n", gr->gr_name, cp->gid);
01186          }
01187       }
01188       ast_cli(a->fd, "Permissions:\n");
01189       if (cp->perms) {
01190          AST_LIST_TRAVERSE(cp->perms, perm, list) {
01191             ast_cli(a->fd, "\t%s -> %s\n", perm->permit ? "permit" : "deny", perm->command);
01192          }
01193       }
01194       ast_cli(a->fd, "\n");
01195    }
01196    AST_RWLIST_UNLOCK(&cli_perms);
01197 
01198    return CLI_SUCCESS;
01199 }

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

Definition at line 1782 of file main/cli.c.

References ast_cli(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

01783 {
01784    switch (cmd) {
01785    case CLI_INIT:
01786       e->command = "core waitfullybooted";
01787       e->usage =
01788          "Usage: core waitfullybooted\n"
01789          "  Wait until Asterisk has fully booted.\n";
01790       return NULL;
01791    case CLI_GENERATE:
01792       return NULL;
01793    }
01794 
01795    while (!ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
01796       usleep(100);
01797    }
01798 
01799    ast_cli(a->fd, "Asterisk has fully booted.\n");
01800 
01801    return CLI_SUCCESS;
01802 }

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

Definition at line 1379 of file main/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, NULL, and ast_cli_entry::usage.

01380 {
01381    char *buf;
01382    switch (cmd) {
01383    case CLI_INIT:
01384       e->command = "_command complete";
01385       e->usage =
01386          "Usage: _command complete \"<line>\" text state\n"
01387          "       This function is used internally to help with command completion and should.\n"
01388          "       never be called by the user directly.\n";
01389       return NULL;
01390    case CLI_GENERATE:
01391       return NULL;
01392    }
01393    if (a->argc != 5)
01394       return CLI_SHOWUSAGE;
01395    buf = __ast_cli_generator(a->argv[2], a->argv[3], atoi(a->argv[4]), 0);
01396    if (buf) {
01397       ast_cli(a->fd, "%s", buf);
01398       ast_free(buf);
01399    } else
01400       ast_cli(a->fd, "NULL\n");
01401    return CLI_SUCCESS;
01402 }

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

Definition at line 1298 of file main/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(), NULL, and ast_cli_entry::usage.

01299 {
01300    char *buf, *obuf;
01301    int buflen = 2048;
01302    int len = 0;
01303    char **matches;
01304    int x, matchlen;
01305 
01306    switch (cmd) {
01307    case CLI_INIT:
01308       e->command = "_command matchesarray";
01309       e->usage =
01310          "Usage: _command matchesarray \"<line>\" text \n"
01311          "       This function is used internally to help with command completion and should.\n"
01312          "       never be called by the user directly.\n";
01313       return NULL;
01314    case CLI_GENERATE:
01315       return NULL;
01316    }
01317 
01318    if (a->argc != 4)
01319       return CLI_SHOWUSAGE;
01320    if (!(buf = ast_malloc(buflen)))
01321       return CLI_FAILURE;
01322    buf[len] = '\0';
01323    matches = ast_cli_completion_matches(a->argv[2], a->argv[3]);
01324    if (matches) {
01325       for (x=0; matches[x]; x++) {
01326          matchlen = strlen(matches[x]) + 1;
01327          if (len + matchlen >= buflen) {
01328             buflen += matchlen * 3;
01329             obuf = buf;
01330             if (!(buf = ast_realloc(obuf, buflen)))
01331                /* Memory allocation failure...  Just free old buffer and be done */
01332                ast_free(obuf);
01333          }
01334          if (buf)
01335             len += sprintf( buf + len, "%s ", matches[x]);
01336          ast_free(matches[x]);
01337          matches[x] = NULL;
01338       }
01339       ast_free(matches);
01340    }
01341 
01342    if (buf) {
01343       ast_cli(a->fd, "%s%s",buf, AST_CLI_COMPLETE_EOF);
01344       ast_free(buf);
01345    } else
01346       ast_cli(a->fd, "NULL\n");
01347 
01348    return CLI_SUCCESS;
01349 }

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

Definition at line 1353 of file main/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, NULL, and ast_cli_entry::usage.

01354 {
01355    int matches = 0;
01356 
01357    switch (cmd) {
01358    case CLI_INIT:
01359       e->command = "_command nummatches";
01360       e->usage =
01361          "Usage: _command nummatches \"<line>\" text \n"
01362          "       This function is used internally to help with command completion and should.\n"
01363          "       never be called by the user directly.\n";
01364       return NULL;
01365    case CLI_GENERATE:
01366       return NULL;
01367    }
01368 
01369    if (a->argc != 4)
01370       return CLI_SHOWUSAGE;
01371 
01372    matches = ast_cli_generatornummatches(a->argv[2], a->argv[3]);
01373 
01374    ast_cli(a->fd, "%d", matches);
01375 
01376    return CLI_SUCCESS;
01377 }

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

Definition at line 324 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_module_reload(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

00325 {
00326    switch (cmd) {
00327    case CLI_INIT:
00328       e->command = "core reload";
00329       e->usage =
00330          "Usage: core reload\n"
00331          "       Execute a global reload.\n";
00332       return NULL;
00333 
00334    case CLI_GENERATE:
00335       return NULL;
00336    }
00337 
00338    if (a->argc != e->args) {
00339       return CLI_SHOWUSAGE;
00340    }
00341 
00342    ast_module_reload(NULL);
00343 
00344    return CLI_SUCCESS;
00345 }

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

Definition at line 1433 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_callback(), ast_channel_get_by_name(), ast_channel_unref, ast_cli(), ast_complete_channels(), ast_strdup, c, channel_set_debug(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEBUGCHAN_FLAG, ast_cli_args::fd, channel_set_debug_args::fd, global_fin, global_fout, channel_set_debug_args::is_off, ast_cli_args::line, ast_cli_args::n, NULL, OBJ_MULTIPLE, OBJ_NODATA, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

Referenced by handle_nodebugchan_deprecated().

01434 {
01435    struct ast_channel *c = NULL;
01436    struct channel_set_debug_args args = {
01437       .fd = a->fd,
01438    };
01439 
01440    switch (cmd) {
01441    case CLI_INIT:
01442       e->command = "core set debug channel";
01443       e->usage =
01444          "Usage: core set debug channel <all|channel> [off]\n"
01445          "       Enables/disables debugging on all or on a specific channel.\n";
01446       return NULL;
01447    case CLI_GENERATE:
01448       /* XXX remember to handle the optional "off" */
01449       if (a->pos != e->args)
01450          return NULL;
01451       return a->n == 0 ? ast_strdup("all") : ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
01452    }
01453 
01454    if (cmd == (CLI_HANDLER + 1000)) {
01455       /* called from handle_nodebugchan_deprecated */
01456       args.is_off = 1;
01457    } else if (a->argc == e->args + 2) {
01458       /* 'core set debug channel {all|chan_id}' */
01459       if (!strcasecmp(a->argv[e->args + 1], "off"))
01460          args.is_off = 1;
01461       else
01462          return CLI_SHOWUSAGE;
01463    } else if (a->argc != e->args + 1) {
01464       return CLI_SHOWUSAGE;
01465    }
01466 
01467    if (!strcasecmp("all", a->argv[e->args])) {
01468       if (args.is_off) {
01469          global_fin &= ~DEBUGCHAN_FLAG;
01470          global_fout &= ~DEBUGCHAN_FLAG;
01471       } else {
01472          global_fin |= DEBUGCHAN_FLAG;
01473          global_fout |= DEBUGCHAN_FLAG;
01474       }
01475       ast_channel_callback(channel_set_debug, NULL, &args, OBJ_NODATA | OBJ_MULTIPLE);
01476    } else {
01477       if ((c = ast_channel_get_by_name(a->argv[e->args]))) {
01478          channel_set_debug(c, NULL, &args, 0);
01479          ast_channel_unref(c);
01480       } else {
01481          ast_cli(a->fd, "No such channel %s\n", a->argv[e->args]);
01482       }
01483    }
01484 
01485    ast_cli(a->fd, "Debugging on new channels is %s\n", args.is_off ? "disabled" : "enabled");
01486 
01487    return CLI_SUCCESS;
01488 }

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

Definition at line 437 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_calloc, ast_clear_flag, ast_cli(), ast_complete_source_filename(), ast_free, AST_OPT_FLAG_DEBUG_MODULE, 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, ast_strdup, ast_strdupa, ast_strlen_zero, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_number(), debug_modules, ast_cli_args::fd, find_module_level(), module_level::level, module_level::module, ast_cli_args::n, NULL, option_debug, ast_cli_args::pos, S_OR, status_debug_verbose(), and ast_cli_entry::usage.

00438 {
00439    int oldval;
00440    int newlevel;
00441    int atleast = 0;
00442    const char *argv3 = a->argv ? S_OR(a->argv[3], "") : "";
00443    struct module_level *ml;
00444 
00445    switch (cmd) {
00446    case CLI_INIT:
00447       e->command = "core set debug";
00448       e->usage =
00449 #if !defined(LOW_MEMORY)
00450          "Usage: core set debug [atleast] <level> [module]\n"
00451 #else
00452          "Usage: core set debug [atleast] <level>\n"
00453 #endif
00454          "       core set debug off\n"
00455          "\n"
00456 #if !defined(LOW_MEMORY)
00457          "       Sets level of debug messages to be displayed or\n"
00458          "       sets a module name to display debug messages from.\n"
00459 #else
00460          "       Sets level of debug messages to be displayed.\n"
00461 #endif
00462          "       0 or off means no messages should be displayed.\n"
00463          "       Equivalent to -d[d[...]] on startup\n";
00464       return NULL;
00465 
00466    case CLI_GENERATE:
00467       if (!strcasecmp(argv3, "atleast")) {
00468          atleast = 1;
00469       }
00470       if (a->pos == 3 || (a->pos == 4 && atleast)) {
00471          const char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], "");
00472          int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21;
00473 
00474          if (a->n < 21 && numbermatch == 0) {
00475             return complete_number(pos, 0, 0x7fffffff, a->n);
00476          } else if (pos[0] == '0') {
00477             if (a->n == 0) {
00478                return ast_strdup("0");
00479             }
00480          } else if (a->n == (21 - numbermatch)) {
00481             if (a->pos == 3 && !strncasecmp(argv3, "off", strlen(argv3))) {
00482                return ast_strdup("off");
00483             } else if (a->pos == 3 && !strncasecmp(argv3, "atleast", strlen(argv3))) {
00484                return ast_strdup("atleast");
00485             }
00486          } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) {
00487             return ast_strdup("atleast");
00488          }
00489 #if !defined(LOW_MEMORY)
00490       } else if ((a->pos == 4 && !atleast && strcasecmp(argv3, "off") && strcasecmp(argv3, "channel"))
00491          || (a->pos == 5 && atleast)) {
00492          const char *pos = S_OR(a->argv[a->pos], "");
00493 
00494          return ast_complete_source_filename(pos, a->n);
00495 #endif
00496       }
00497       return NULL;
00498    }
00499    /* all the above return, so we proceed with the handler.
00500     * we are guaranteed to be called with argc >= e->args;
00501     */
00502 
00503    if (a->argc <= e->args) {
00504       return CLI_SHOWUSAGE;
00505    }
00506 
00507    if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args], "off")) {
00508       newlevel = 0;
00509    } else {
00510       if (!strcasecmp(a->argv[e->args], "atleast")) {
00511          atleast = 1;
00512       }
00513       if (a->argc != e->args + atleast + 1 && a->argc != e->args + atleast + 2) {
00514          return CLI_SHOWUSAGE;
00515       }
00516       if (sscanf(a->argv[e->args + atleast], "%30d", &newlevel) != 1) {
00517          return CLI_SHOWUSAGE;
00518       }
00519 
00520       if (a->argc == e->args + atleast + 2) {
00521          /* We have specified a module name. */
00522          char *mod = ast_strdupa(a->argv[e->args + atleast + 1]);
00523          int mod_len = strlen(mod);
00524 
00525          if (3 < mod_len && !strcasecmp(mod + mod_len - 3, ".so")) {
00526             mod[mod_len - 3] = '\0';
00527          }
00528 
00529          AST_RWLIST_WRLOCK(&debug_modules);
00530 
00531          ml = find_module_level(mod, &debug_modules);
00532          if (!newlevel) {
00533             if (!ml) {
00534                /* Specified off for a nonexistent entry. */
00535                AST_RWLIST_UNLOCK(&debug_modules);
00536                ast_cli(a->fd, "Core debug is still 0 for '%s'.\n", mod);
00537                return CLI_SUCCESS;
00538             }
00539             AST_RWLIST_REMOVE(&debug_modules, ml, entry);
00540             if (AST_RWLIST_EMPTY(&debug_modules)) {
00541                ast_clear_flag(&ast_options, AST_OPT_FLAG_DEBUG_MODULE);
00542             }
00543             AST_RWLIST_UNLOCK(&debug_modules);
00544             ast_cli(a->fd, "Core debug was %u and has been set to 0 for '%s'.\n",
00545                ml->level, mod);
00546             ast_free(ml);
00547             return CLI_SUCCESS;
00548          }
00549 
00550          if (ml) {
00551             if ((atleast && newlevel < ml->level) || ml->level == newlevel) {
00552                ast_cli(a->fd, "Core debug is still %u for '%s'.\n", ml->level, mod);
00553                AST_RWLIST_UNLOCK(&debug_modules);
00554                return CLI_SUCCESS;
00555             }
00556             oldval = ml->level;
00557             ml->level = newlevel;
00558          } else {
00559             ml = ast_calloc(1, sizeof(*ml) + strlen(mod) + 1);
00560             if (!ml) {
00561                AST_RWLIST_UNLOCK(&debug_modules);
00562                return CLI_FAILURE;
00563             }
00564             oldval = ml->level;
00565             ml->level = newlevel;
00566             strcpy(ml->module, mod);
00567             AST_RWLIST_INSERT_TAIL(&debug_modules, ml, entry);
00568          }
00569          ast_set_flag(&ast_options, AST_OPT_FLAG_DEBUG_MODULE);
00570 
00571          ast_cli(a->fd, "Core debug was %d and has been set to %u for '%s'.\n",
00572             oldval, ml->level, ml->module);
00573 
00574          AST_RWLIST_UNLOCK(&debug_modules);
00575 
00576          return CLI_SUCCESS;
00577       }
00578    }
00579 
00580    /* Update global debug level */
00581    if (!newlevel) {
00582       /* Specified level was 0 or off. */
00583       AST_RWLIST_WRLOCK(&debug_modules);
00584       while ((ml = AST_RWLIST_REMOVE_HEAD(&debug_modules, entry))) {
00585          ast_free(ml);
00586       }
00587       ast_clear_flag(&ast_options, AST_OPT_FLAG_DEBUG_MODULE);
00588       AST_RWLIST_UNLOCK(&debug_modules);
00589    }
00590    oldval = option_debug;
00591    if (!atleast || newlevel > option_debug) {
00592       option_debug = newlevel;
00593    }
00594 
00595    /* Report debug level status */
00596    status_debug_verbose(a, "Core debug", oldval, option_debug);
00597 
00598    return CLI_SUCCESS;
00599 }

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

Definition at line 2367 of file main/cli.c.

References __ast_cli_generator(), ast_cli_args::argc, ast_cli_entry::args, 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, NULL, ast_cli_entry::usage, and ast_cli_args::word.

02368 {
02369    char fullcmd[80];
02370    struct ast_cli_entry *my_e;
02371    char *res = CLI_SUCCESS;
02372 
02373    if (cmd == CLI_INIT) {
02374       e->command = "core show help";
02375       e->usage =
02376          "Usage: core show help [topic]\n"
02377          "       When called with a topic as an argument, displays usage\n"
02378          "       information on the given command. If called without a\n"
02379          "       topic, it provides a list of commands.\n";
02380       return NULL;
02381 
02382    } else if (cmd == CLI_GENERATE) {
02383       /* skip first 14 or 15 chars, "core show help " */
02384       int l = strlen(a->line);
02385 
02386       if (l > 15) {
02387          l = 15;
02388       }
02389       /* XXX watch out, should stop to the non-generator parts */
02390       return __ast_cli_generator(a->line + l, a->word, a->n, 0);
02391    }
02392    if (a->argc == e->args) {
02393       return help1(a->fd, NULL, 0);
02394    }
02395 
02396    AST_RWLIST_RDLOCK(&helpers);
02397    my_e = find_cli(a->argv + 3, 1); /* try exact match first */
02398    if (!my_e) {
02399       res = help1(a->fd, a->argv + 3, 1 /* locked */);
02400       AST_RWLIST_UNLOCK(&helpers);
02401       return res;
02402    }
02403    if (my_e->usage)
02404       ast_cli(a->fd, "%s", my_e->usage);
02405    else {
02406       ast_join(fullcmd, sizeof(fullcmd), a->argv + 3);
02407       ast_cli(a->fd, "No help text available for '%s'.\n", fullcmd);
02408    }
02409    AST_RWLIST_UNLOCK(&helpers);
02410    return res;
02411 }

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

Definition at line 247 of file main/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, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

00248 {
00249    /* "module load <mod>" */
00250    switch (cmd) {
00251    case CLI_INIT:
00252       e->command = "module load";
00253       e->usage =
00254          "Usage: module load <module name>\n"
00255          "       Loads the specified module into Asterisk.\n";
00256       return NULL;
00257 
00258    case CLI_GENERATE:
00259       if (a->pos != e->args)
00260          return NULL;
00261       return complete_fn(a->word, a->n);
00262    }
00263    if (a->argc != e->args + 1)
00264       return CLI_SHOWUSAGE;
00265    if (ast_load_resource(a->argv[e->args])) {
00266       ast_cli(a->fd, "Unable to load module %s\n", a->argv[e->args]);
00267       return CLI_FAILURE;
00268    }
00269    ast_cli(a->fd, "Loaded %s\n", a->argv[e->args]);
00270    return CLI_SUCCESS;
00271 }

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

Definition at line 701 of file main/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, NULL, and ast_cli_entry::usage.

00702 {
00703    switch (cmd) {
00704    case CLI_INIT:
00705       e->command = "logger mute";
00706       e->usage =
00707          "Usage: logger mute\n"
00708          "       Disables logging output to the current console, making it possible to\n"
00709          "       gather information without being disturbed by scrolling lines.\n";
00710       return NULL;
00711    case CLI_GENERATE:
00712       return NULL;
00713    }
00714 
00715    if (a->argc < 2 || a->argc > 3)
00716       return CLI_SHOWUSAGE;
00717 
00718    if (a->argc == 3 && !strcasecmp(a->argv[2], "silent"))
00719       ast_console_toggle_mute(a->fd, 1);
00720    else
00721       ast_console_toggle_mute(a->fd, 0);
00722 
00723    return CLI_SUCCESS;
00724 }

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

Definition at line 885 of file main/cli.c.

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

00886 {
00887    const char *like;
00888 
00889    switch (cmd) {
00890    case CLI_INIT:
00891       e->command = "module show [like]";
00892       e->usage =
00893          "Usage: module show [like keyword]\n"
00894          "       Shows Asterisk modules currently in use, and usage statistics.\n";
00895       return NULL;
00896 
00897    case CLI_GENERATE:
00898       if (a->pos == e->args)
00899          return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0);
00900       else
00901          return NULL;
00902    }
00903    /* all the above return, so we proceed with the handler.
00904     * we are guaranteed to have argc >= e->args
00905     */
00906    if (a->argc == e->args - 1)
00907       like = "";
00908    else if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args-1], "like") )
00909       like = a->argv[e->args];
00910    else
00911       return CLI_SHOWUSAGE;
00912 
00913    ast_mutex_lock(&climodentrylock);
00914    climodentryfd = a->fd; /* global, protected by climodentrylock */
00915    ast_cli(a->fd, MODLIST_FORMAT2, "Module", "Description", "Use Count", "Status", "Support Level");
00916    ast_cli(a->fd,"%d modules loaded\n", ast_update_module_list(modlist_modentry, like));
00917    climodentryfd = -1;
00918    ast_mutex_unlock(&climodentrylock);
00919    return CLI_SUCCESS;
00920 }

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

Definition at line 1490 of file main/cli.c.

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

01491 {
01492    char *res;
01493 
01494    switch (cmd) {
01495    case CLI_INIT:
01496       e->command = "no debug channel";
01497       return NULL;
01498    case CLI_HANDLER:
01499       /* exit out of switch statement */
01500       break;
01501    default:
01502       return NULL;
01503    }
01504 
01505    if (a->argc != e->args + 1)
01506       return CLI_SHOWUSAGE;
01507 
01508    /* add a 'magic' value to the CLI_HANDLER command so that
01509     * handle_core_set_debug_channel() will act as if 'off'
01510     * had been specified as part of the command
01511     */
01512    res = handle_core_set_debug_channel(e, CLI_HANDLER + 1000, a);
01513 
01514    return res;
01515 }

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

Definition at line 273 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_module_helper(), ast_module_reload(), AST_MODULE_RELOAD_ERROR, AST_MODULE_RELOAD_IN_PROGRESS, AST_MODULE_RELOAD_NOT_FOUND, AST_MODULE_RELOAD_NOT_IMPLEMENTED, AST_MODULE_RELOAD_QUEUED, AST_MODULE_RELOAD_SUCCESS, AST_MODULE_RELOAD_UNINITIALIZED, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

00274 {
00275    int x;
00276 
00277    switch (cmd) {
00278    case CLI_INIT:
00279       e->command = "module reload";
00280       e->usage =
00281          "Usage: module reload [module ...]\n"
00282          "       Reloads configuration files for all listed modules which support\n"
00283          "       reloading, or for all supported modules if none are listed.\n";
00284       return NULL;
00285 
00286    case CLI_GENERATE:
00287       return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 1);
00288    }
00289    if (a->argc == e->args) {
00290       ast_module_reload(NULL);
00291       return CLI_SUCCESS;
00292    }
00293    for (x = e->args; x < a->argc; x++) {
00294       enum ast_module_reload_result res = ast_module_reload(a->argv[x]);
00295       switch (res) {
00296       case AST_MODULE_RELOAD_NOT_FOUND:
00297          ast_cli(a->fd, "No such module '%s'\n", a->argv[x]);
00298          break;
00299       case AST_MODULE_RELOAD_NOT_IMPLEMENTED:
00300          ast_cli(a->fd, "The module '%s' does not support reloads\n", a->argv[x]);
00301          break;
00302       case AST_MODULE_RELOAD_QUEUED:
00303          ast_cli(a->fd, "Asterisk cannot reload a module yet; request queued\n");
00304          break;
00305       case AST_MODULE_RELOAD_ERROR:
00306          ast_cli(a->fd, "The module '%s' reported a reload failure\n", a->argv[x]);
00307          break;
00308       case AST_MODULE_RELOAD_IN_PROGRESS:
00309          ast_cli(a->fd, "A module reload request is already in progress; please be patient\n");
00310          break;
00311       case AST_MODULE_RELOAD_UNINITIALIZED:
00312          ast_cli(a->fd, "The module '%s' was not properly initialized. Before reloading"
00313                " the module, you must run \"module load %s\" and fix whatever is"
00314                " preventing the module from being initialized.\n", a->argv[x], a->argv[x]);
00315          break;
00316       case AST_MODULE_RELOAD_SUCCESS:
00317          ast_cli(a->fd, "Module '%s' reloaded successfully.\n", a->argv[x]);
00318          break;
00319       }
00320    }
00321    return CLI_SUCCESS;
00322 }

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

Definition at line 924 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_cli(), ast_option_maxcalls, 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, NULL, ast_cli_args::pos, print_uptimestr(), RESULT_SUCCESS, and ast_cli_entry::usage.

00925 {
00926    struct timeval curtime = ast_tvnow();
00927    int showuptime, printsec;
00928 
00929    switch (cmd) {
00930    case CLI_INIT:
00931       e->command = "core show calls [uptime]";
00932       e->usage =
00933          "Usage: core show calls [uptime] [seconds]\n"
00934          "       Lists number of currently active calls and total number of calls\n"
00935          "       processed through PBX since last restart. If 'uptime' is specified\n"
00936          "       the system uptime is also displayed. If 'seconds' is specified in\n"
00937          "       addition to 'uptime', the system uptime is displayed in seconds.\n";
00938       return NULL;
00939 
00940    case CLI_GENERATE:
00941       if (a->pos != e->args)
00942          return NULL;
00943       return a->n == 0  ? ast_strdup("seconds") : NULL;
00944    }
00945 
00946    /* regular handler */
00947    if (a->argc >= e->args && !strcasecmp(a->argv[e->args-1],"uptime")) {
00948       showuptime = 1;
00949 
00950       if (a->argc == e->args+1 && !strcasecmp(a->argv[e->args],"seconds"))
00951          printsec = 1;
00952       else if (a->argc == e->args)
00953          printsec = 0;
00954       else
00955          return CLI_SHOWUSAGE;
00956    } else if (a->argc == e->args-1) {
00957       showuptime = 0;
00958       printsec = 0;
00959    } else
00960       return CLI_SHOWUSAGE;
00961 
00962    if (ast_option_maxcalls) {
00963       ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
00964          ast_active_calls(), ast_option_maxcalls, ESS(ast_active_calls()),
00965          ((double)ast_active_calls() / (double)ast_option_maxcalls) * 100.0);
00966    } else {
00967       ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
00968    }
00969 
00970    ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
00971 
00972    if (ast_startuptime.tv_sec && showuptime) {
00973       print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec);
00974    }
00975 
00976    return RESULT_SUCCESS;
00977 }

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

< Buffer for CDR variables.

< Accumulation buffer for all output.

Definition at line 1517 of file main/cli.c.

References ao2_cleanup, ast_cli_args::argc, ast_cli_args::argv, ast_callid_strnprint(), ast_cdr_serialize_variables(), AST_CHAN_TP_INTERNAL, ast_channel_appl(), ast_channel_caller(), ast_channel_callgroup(), ast_channel_callid(), ast_channel_connected(), ast_channel_connected_effective_id(), ast_channel_context(), ast_channel_creationtime(), ast_channel_data(), ast_channel_dialed(), ast_channel_exten(), ast_channel_get_bridge(), ast_channel_get_by_name(), ast_channel_language(), ast_channel_linkedid(), ast_channel_lock, ast_channel_name(), ast_channel_nativeformats(), ast_channel_pickupgroup(), ast_channel_priority(), ast_channel_readformat(), ast_channel_readtrans(), ast_channel_tech(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_channel_varshead(), ast_channel_whentohangup(), ast_channel_writeformat(), ast_channel_writetrans(), ast_cli(), ast_complete_channels(), ast_format_cap_get_names(), ast_format_get_name(), ast_free, AST_LIST_TRAVERSE, ast_state2str(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_strlen(), ast_str_thread_get(), ast_translate_path_to_str(), ast_tvnow(), ast_tvzero(), ast_var_name(), ast_var_value(), ast_bridge::callid, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, min, ast_cli_args::n, name, NULL, ast_cli_args::pos, S_COR, S_OR, ast_party_dialed::str, type, ast_bridge::uniqueid, ast_cli_entry::usage, var, and ast_cli_args::word.

01518 {
01519    struct ast_channel *chan;
01520    struct timeval now;
01521    char cdrtime[256];
01522    struct ast_str *obuf;/*!< Buffer for CDR variables. */
01523    struct ast_str *output;/*!< Accumulation buffer for all output. */
01524    long elapsed_seconds=0;
01525    int hour=0, min=0, sec=0;
01526    struct ast_var_t *var;
01527    struct ast_str *write_transpath = ast_str_alloca(256);
01528    struct ast_str *read_transpath = ast_str_alloca(256);
01529    struct ast_str *codec_buf = ast_str_alloca(64);
01530    struct ast_bridge *bridge;
01531    ast_callid callid;
01532    char callid_buf[32];
01533 
01534    switch (cmd) {
01535    case CLI_INIT:
01536       e->command = "core show channel";
01537       e->usage =
01538          "Usage: core show channel <channel>\n"
01539          "       Shows lots of information about the specified channel.\n";
01540       return NULL;
01541    case CLI_GENERATE:
01542       return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
01543    }
01544 
01545    if (a->argc != 4) {
01546       return CLI_SHOWUSAGE;
01547    }
01548 
01549    obuf = ast_str_thread_get(&ast_str_thread_global_buf, 16);
01550    if (!obuf) {
01551       return CLI_FAILURE;
01552    }
01553 
01554    output = ast_str_create(8192);
01555    if (!output) {
01556       return CLI_FAILURE;
01557    }
01558 
01559    chan = ast_channel_get_by_name(a->argv[3]);
01560    if (!chan) {
01561       ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
01562       return CLI_SUCCESS;
01563    }
01564 
01565    now = ast_tvnow();
01566    ast_channel_lock(chan);
01567 
01568    if (!ast_tvzero(ast_channel_creationtime(chan))) {
01569       elapsed_seconds = now.tv_sec - ast_channel_creationtime(chan).tv_sec;
01570       hour = elapsed_seconds / 3600;
01571       min = (elapsed_seconds % 3600) / 60;
01572       sec = elapsed_seconds % 60;
01573       snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
01574    } else {
01575       strcpy(cdrtime, "N/A");
01576    }
01577 
01578    ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath);
01579    ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath);
01580 
01581    bridge = ast_channel_get_bridge(chan);
01582    callid_buf[0] = '\0';
01583    callid = ast_channel_callid(chan);
01584    if (callid) {
01585       ast_callid_strnprint(callid_buf, sizeof(callid_buf), callid);
01586    }
01587 
01588    ast_str_append(&output, 0,
01589       " -- General --\n"
01590       "           Name: %s\n"
01591       "           Type: %s\n"
01592       "       UniqueID: %s\n"
01593       "       LinkedID: %s\n"
01594       "      Caller ID: %s\n"
01595       " Caller ID Name: %s\n"
01596       "Connected Line ID: %s\n"
01597       "Connected Line ID Name: %s\n"
01598       "Eff. Connected Line ID: %s\n"
01599       "Eff. Connected Line ID Name: %s\n"
01600       "    DNID Digits: %s\n"
01601       "       Language: %s\n"
01602       "          State: %s (%u)\n"
01603       "  NativeFormats: %s\n"
01604       "    WriteFormat: %s\n"
01605       "     ReadFormat: %s\n"
01606       " WriteTranscode: %s %s\n"
01607       "  ReadTranscode: %s %s\n"
01608       " Time to Hangup: %ld\n"
01609       "   Elapsed Time: %s\n"
01610       "      Bridge ID: %s\n"
01611       " --   PBX   --\n"
01612       "        Context: %s\n"
01613       "      Extension: %s\n"
01614       "       Priority: %d\n"
01615       "     Call Group: %llu\n"
01616       "   Pickup Group: %llu\n"
01617       "    Application: %s\n"
01618       "           Data: %s\n"
01619       " Call Identifer: %s\n",
01620       ast_channel_name(chan),
01621       ast_channel_tech(chan)->type,
01622       ast_channel_uniqueid(chan),
01623       ast_channel_linkedid(chan),
01624       S_COR(ast_channel_caller(chan)->id.number.valid,
01625             ast_channel_caller(chan)->id.number.str, "(N/A)"),
01626       S_COR(ast_channel_caller(chan)->id.name.valid,
01627             ast_channel_caller(chan)->id.name.str, "(N/A)"),
01628       S_COR(ast_channel_connected(chan)->id.number.valid,
01629             ast_channel_connected(chan)->id.number.str, "(N/A)"),
01630       S_COR(ast_channel_connected(chan)->id.name.valid,
01631             ast_channel_connected(chan)->id.name.str, "(N/A)"),
01632       S_COR(ast_channel_connected_effective_id(chan).number.valid,
01633             ast_channel_connected_effective_id(chan).number.str, "(N/A)"),
01634       S_COR(ast_channel_connected_effective_id(chan).name.valid,
01635             ast_channel_connected_effective_id(chan).name.str, "(N/A)"),
01636       S_OR(ast_channel_dialed(chan)->number.str, "(N/A)"),
01637       ast_channel_language(chan),
01638       ast_state2str(ast_channel_state(chan)),
01639       ast_channel_state(chan),
01640       ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf),
01641       ast_format_get_name(ast_channel_writeformat(chan)),
01642       ast_format_get_name(ast_channel_readformat(chan)),
01643       ast_str_strlen(write_transpath) ? "Yes" : "No",
01644       ast_str_buffer(write_transpath),
01645       ast_str_strlen(read_transpath) ? "Yes" : "No",
01646       ast_str_buffer(read_transpath),
01647       (long)ast_channel_whentohangup(chan)->tv_sec,
01648       cdrtime,
01649       bridge ? bridge->uniqueid : "(Not bridged)",
01650       ast_channel_context(chan),
01651       ast_channel_exten(chan),
01652       ast_channel_priority(chan),
01653       ast_channel_callgroup(chan),
01654       ast_channel_pickupgroup(chan),
01655       S_OR(ast_channel_appl(chan), "(N/A)"),
01656       S_OR(ast_channel_data(chan), "(Empty)"),
01657       S_OR(callid_buf, "(None)")
01658       );
01659    ast_str_append(&output, 0, "      Variables:\n");
01660 
01661    AST_LIST_TRAVERSE(ast_channel_varshead(chan), var, entries) {
01662       ast_str_append(&output, 0, "%s=%s\n", ast_var_name(var), ast_var_value(var));
01663    }
01664 
01665    if (!(ast_channel_tech(chan)->properties & AST_CHAN_TP_INTERNAL)
01666       && ast_cdr_serialize_variables(ast_channel_name(chan), &obuf, '=', '\n')) {
01667       ast_str_append(&output, 0, "  CDR Variables:\n%s\n", ast_str_buffer(obuf));
01668    }
01669 
01670    ast_channel_unlock(chan);
01671 
01672    ast_cli(a->fd, "%s", ast_str_buffer(output));
01673    ast_free(output);
01674 
01675    ao2_cleanup(bridge);
01676    ast_channel_unref(chan);
01677 
01678    return CLI_SUCCESS;
01679 }

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

Definition at line 854 of file main/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, NULL, print_uptimestr(), and ast_cli_entry::usage.

00855 {
00856    struct timeval curtime = ast_tvnow();
00857    int printsec;
00858 
00859    switch (cmd) {
00860    case CLI_INIT:
00861       e->command = "core show uptime [seconds]";
00862       e->usage =
00863          "Usage: core show uptime [seconds]\n"
00864          "       Shows Asterisk uptime information.\n"
00865          "       The seconds word returns the uptime in seconds only.\n";
00866       return NULL;
00867 
00868    case CLI_GENERATE:
00869       return NULL;
00870    }
00871    /* regular handler */
00872    if (a->argc == e->args && !strcasecmp(a->argv[e->args-1],"seconds"))
00873       printsec = 1;
00874    else if (a->argc == e->args-1)
00875       printsec = 0;
00876    else
00877       return CLI_SHOWUSAGE;
00878    if (ast_startuptime.tv_sec)
00879       print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec);
00880    if (ast_lastreloadtime.tv_sec)
00881       print_uptimestr(a->fd, ast_tvsub(curtime, ast_lastreloadtime), "Last reload", printsec);
00882    return CLI_SUCCESS;
00883 }

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

Definition at line 1109 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, c, 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, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

01110 {
01111    struct ast_channel *c=NULL;
01112 
01113    switch (cmd) {
01114    case CLI_INIT:
01115       e->command = "channel request hangup";
01116       e->usage =
01117          "Usage: channel request hangup <channel>|<all>\n"
01118          "       Request that a channel be hung up. The hangup takes effect\n"
01119          "       the next time the driver reads or writes from the channel.\n"
01120          "       If 'all' is specified instead of a channel name, all channels\n"
01121          "       will see the hangup request.\n";
01122       return NULL;
01123    case CLI_GENERATE:
01124       return ast_complete_channels(a->line, a->word, a->pos, a->n, e->args);
01125    }
01126 
01127    if (a->argc != 4) {
01128       return CLI_SHOWUSAGE;
01129    }
01130 
01131    if (!strcasecmp(a->argv[3], "all")) {
01132       struct ast_channel_iterator *iter = NULL;
01133       if (!(iter = ast_channel_iterator_all_new())) {
01134          return CLI_FAILURE;
01135       }
01136       for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
01137          ast_channel_lock(c);
01138          ast_cli(a->fd, "Requested Hangup on channel '%s'\n", ast_channel_name(c));
01139          ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01140          ast_channel_unlock(c);
01141       }
01142       ast_channel_iterator_destroy(iter);
01143    } else if ((c = ast_channel_get_by_name(a->argv[3]))) {
01144       ast_channel_lock(c);
01145       ast_cli(a->fd, "Requested Hangup on channel '%s'\n", ast_channel_name(c));
01146       ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01147       ast_channel_unlock(c);
01148       c = ast_channel_unref(c);
01149    } else {
01150       ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
01151    }
01152 
01153    return CLI_SUCCESS;
01154 }

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

Definition at line 726 of file main/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, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

00727 {
00728    /* "module unload mod_1 [mod_2 .. mod_N]" */
00729    int x;
00730    int force = AST_FORCE_SOFT;
00731    const char *s;
00732 
00733    switch (cmd) {
00734    case CLI_INIT:
00735       e->command = "module unload";
00736       e->usage =
00737          "Usage: module unload [-f|-h] <module_1> [<module_2> ... ]\n"
00738          "       Unloads the specified module from Asterisk. The -f\n"
00739          "       option causes the module to be unloaded even if it is\n"
00740          "       in use (may cause a crash) and the -h module causes the\n"
00741          "       module to be unloaded even if the module says it cannot, \n"
00742          "       which almost always will cause a crash.\n";
00743       return NULL;
00744 
00745    case CLI_GENERATE:
00746       return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0);
00747    }
00748    if (a->argc < e->args + 1)
00749       return CLI_SHOWUSAGE;
00750    x = e->args;   /* first argument */
00751    s = a->argv[x];
00752    if (s[0] == '-') {
00753       if (s[1] == 'f')
00754          force = AST_FORCE_FIRM;
00755       else if (s[1] == 'h')
00756          force = AST_FORCE_HARD;
00757       else
00758          return CLI_SHOWUSAGE;
00759       if (a->argc < e->args + 2) /* need at least one module name */
00760          return CLI_SHOWUSAGE;
00761       x++;  /* skip this argument */
00762    }
00763 
00764    for (; x < a->argc; x++) {
00765       if (ast_unload_resource(a->argv[x], force)) {
00766          ast_cli(a->fd, "Unable to unload resource %s\n", a->argv[x]);
00767          return CLI_FAILURE;
00768       }
00769       ast_cli(a->fd, "Unloaded %s\n", a->argv[x]);
00770    }
00771 
00772    return CLI_SUCCESS;
00773 }

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

Definition at line 601 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_strdup, ast_strlen_zero, ast_verb_console_get(), ast_verb_console_set(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_number(), ast_cli_args::n, NULL, ast_cli_args::pos, S_OR, status_debug_verbose(), and ast_cli_entry::usage.

00602 {
00603    int oldval;
00604    int newlevel;
00605    int atleast = 0;
00606    int silent = 0;
00607    const char *argv3 = a->argv ? S_OR(a->argv[3], "") : "";
00608 
00609    switch (cmd) {
00610    case CLI_INIT:
00611       e->command = "core set verbose";
00612       e->usage =
00613          "Usage: core set verbose [atleast] <level> [silent]\n"
00614          "       core set verbose off\n"
00615          "\n"
00616          "       Sets level of verbose messages to be displayed.\n"
00617          "       0 or off means no verbose messages should be displayed.\n"
00618          "       The silent option means the command does not report what\n"
00619          "       happened to the verbose level.\n"
00620          "       Equivalent to -v[v[...]] on startup\n";
00621       return NULL;
00622 
00623    case CLI_GENERATE:
00624       if (!strcasecmp(argv3, "atleast")) {
00625          atleast = 1;
00626       }
00627       if (a->pos == 3 || (a->pos == 4 && atleast)) {
00628          const char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], "");
00629          int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21;
00630 
00631          if (a->n < 21 && numbermatch == 0) {
00632             return complete_number(pos, 0, 0x7fffffff, a->n);
00633          } else if (pos[0] == '0') {
00634             if (a->n == 0) {
00635                return ast_strdup("0");
00636             }
00637          } else if (a->n == (21 - numbermatch)) {
00638             if (a->pos == 3 && !strncasecmp(argv3, "off", strlen(argv3))) {
00639                return ast_strdup("off");
00640             } else if (a->pos == 3 && !strncasecmp(argv3, "atleast", strlen(argv3))) {
00641                return ast_strdup("atleast");
00642             }
00643          } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) {
00644             return ast_strdup("atleast");
00645          }
00646       } else if ((a->pos == 4 && !atleast && strcasecmp(argv3, "off"))
00647          || (a->pos == 5 && atleast)) {
00648          const char *pos = S_OR(a->argv[a->pos], "");
00649 
00650          if (a->n == 0 && !strncasecmp(pos, "silent", strlen(pos))) {
00651             return ast_strdup("silent");
00652          }
00653       }
00654       return NULL;
00655    }
00656    /* all the above return, so we proceed with the handler.
00657     * we are guaranteed to be called with argc >= e->args;
00658     */
00659 
00660    if (a->argc <= e->args) {
00661       return CLI_SHOWUSAGE;
00662    }
00663 
00664    if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args], "off")) {
00665       newlevel = 0;
00666    } else {
00667       if (!strcasecmp(a->argv[e->args], "atleast")) {
00668          atleast = 1;
00669       }
00670       if (a->argc == e->args + atleast + 2
00671          && !strcasecmp(a->argv[e->args + atleast + 1], "silent")) {
00672          silent = 1;
00673       }
00674       if (a->argc != e->args + atleast + silent + 1) {
00675          return CLI_SHOWUSAGE;
00676       }
00677       if (sscanf(a->argv[e->args + atleast], "%30d", &newlevel) != 1) {
00678          return CLI_SHOWUSAGE;
00679       }
00680    }
00681 
00682    /* Update verbose level */
00683    oldval = ast_verb_console_get();
00684    if (!atleast || newlevel > oldval) {
00685       ast_verb_console_set(newlevel);
00686    } else {
00687       newlevel = oldval;
00688    }
00689 
00690    if (silent) {
00691       /* Be silent after setting the level. */
00692       return CLI_SUCCESS;
00693    }
00694 
00695    /* Report verbose level status */
00696    status_debug_verbose(a, "Console verbose", oldval, newlevel);
00697 
00698    return CLI_SUCCESS;
00699 }

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

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

Definition at line 2337 of file main/cli.c.

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

Referenced by handle_help().

02338 {
02339    char matchstr[80] = "";
02340    struct ast_cli_entry *e = NULL;
02341    int len = 0;
02342    int found = 0;
02343 
02344    if (match) {
02345       ast_join(matchstr, sizeof(matchstr), match);
02346       len = strlen(matchstr);
02347    }
02348    if (!locked)
02349       AST_RWLIST_RDLOCK(&helpers);
02350    while ( (e = cli_next(e)) ) {
02351       /* Hide commands that start with '_' */
02352       if (e->_full_cmd[0] == '_')
02353          continue;
02354       if (match && strncasecmp(matchstr, e->_full_cmd, len))
02355          continue;
02356       ast_cli(fd, "%-30s -- %s\n", e->_full_cmd,
02357          S_OR(e->summary, "<no description available>"));
02358       found++;
02359    }
02360    if (!locked)
02361       AST_RWLIST_UNLOCK(&helpers);
02362    if (!found && matchstr[0])
02363       ast_cli(fd, "No such command '%s'.\n", matchstr);
02364    return CLI_SUCCESS;
02365 }

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 2082 of file main/cli.c.

References ast_strdup, ast_strdupa, ast_strlen_zero, NULL, strsep(), and t1.

Referenced by __ast_cli_generator().

02084 {
02085    int lw;
02086    char *s, *t1;
02087 
02088    *actual = 0;
02089    if (ast_strlen_zero(token))
02090       return NULL;
02091    if (ast_strlen_zero(word))
02092       word = "";  /* dummy */
02093    lw = strlen(word);
02094    if (strcspn(word, cli_rsvd) != lw)
02095       return NULL;   /* no match if word has reserved chars */
02096    if (strchr(cli_rsvd, token[0]) == NULL) { /* regular match */
02097       if (strncasecmp(token, word, lw))   /* no match */
02098          return NULL;
02099       *actual = 1;
02100       return (pos != 0) ? NULL : ast_strdup(token);
02101    }
02102    /* now handle regexp match */
02103 
02104    /* Wildcard always matches, so we never do is_prefix on them */
02105 
02106    t1 = ast_strdupa(token + 1);  /* copy, skipping first char */
02107    while (pos >= 0 && (s = strsep(&t1, cli_rsvd)) && *s) {
02108       if (*s == '%') /* wildcard */
02109          continue;
02110       if (strncasecmp(s, word, lw)) /* no match */
02111          continue;
02112       (*actual)++;
02113       if (pos-- == 0)
02114          return ast_strdup(s);
02115    }
02116    return NULL;
02117 }

static int modlist_modentry ( const char *  module,
const char *  description,
int  usecnt,
const char *  status,
const char *  like,
enum ast_module_support_level  support_level 
) [static]

Definition at line 781 of file main/cli.c.

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

Referenced by handle_modlist().

00784 {
00785    /* Comparing the like with the module */
00786    if (strcasestr(module, like) ) {
00787       ast_cli(climodentryfd, MODLIST_FORMAT, module, description, usecnt,
00788             status, ast_module_support_level_to_string(support_level));
00789       return 1;
00790    }
00791    return 0;
00792 }

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

returns true if there are more words to match

Definition at line 2576 of file main/cli.c.

Referenced by __ast_cli_generator().

02577 {
02578    int i;
02579    for (i = 0; dst[i]; i++) {
02580       if (dst[i][0] != '[')
02581          return -1;
02582    }
02583    return 0;
02584 }

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

Definition at line 2413 of file main/cli.c.

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

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

02414 {
02415    char *duplicate, *cur;
02416    int x = 0;
02417    int quoted = 0;
02418    int escaped = 0;
02419    int whitespace = 1;
02420    int dummy = 0;
02421 
02422    if (trailingwhitespace == NULL)
02423       trailingwhitespace = &dummy;
02424    *trailingwhitespace = 0;
02425    if (s == NULL) /* invalid, though! */
02426       return NULL;
02427    /* make a copy to store the parsed string */
02428    if (!(duplicate = ast_strdup(s)))
02429       return NULL;
02430 
02431    cur = duplicate;
02432 
02433    /* Remove leading spaces from the command */
02434    while (isspace(*s)) {
02435       cur++;
02436       s++;
02437    }
02438 
02439    /* scan the original string copying into cur when needed */
02440    for (; *s ; s++) {
02441       if (x >= max - 1) {
02442          ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s);
02443          break;
02444       }
02445       if (*s == '"' && !escaped) {
02446          quoted = !quoted;
02447          if (quoted && whitespace) {
02448             /* start a quoted string from previous whitespace: new argument */
02449             argv[x++] = cur;
02450             whitespace = 0;
02451          }
02452       } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) {
02453          /* If we are not already in whitespace, and not in a quoted string or
02454             processing an escape sequence, and just entered whitespace, then
02455             finalize the previous argument and remember that we are in whitespace
02456          */
02457          if (!whitespace) {
02458             *cur++ = '\0';
02459             whitespace = 1;
02460          }
02461       } else if (*s == '\\' && !escaped) {
02462          escaped = 1;
02463       } else {
02464          if (whitespace) {
02465             /* we leave whitespace, and are not quoted. So it's a new argument */
02466             argv[x++] = cur;
02467             whitespace = 0;
02468          }
02469          *cur++ = *s;
02470          escaped = 0;
02471       }
02472    }
02473    /* Null terminate */
02474    *cur++ = '\0';
02475    /* XXX put a NULL in the last argument, because some functions that take
02476     * the array may want a null-terminated array.
02477     * argc still reflects the number of non-NULL entries.
02478     */
02479    argv[x] = NULL;
02480    *argc = x;
02481    *trailingwhitespace = whitespace;
02482    return duplicate;
02483 }

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

Definition at line 794 of file main/cli.c.

References ast_cli(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_strlen(), DAY, ESS, HOUR, MINUTE, NEEDCOMMA, out, WEEK, and YEAR.

Referenced by handle_showcalls(), and handle_showuptime().

00795 {
00796    int x; /* the main part - years, weeks, etc. */
00797    struct ast_str *out;
00798 
00799 #define SECOND (1)
00800 #define MINUTE (SECOND*60)
00801 #define HOUR (MINUTE*60)
00802 #define DAY (HOUR*24)
00803 #define WEEK (DAY*7)
00804 #define YEAR (DAY*365)
00805 #define NEEDCOMMA(x) ((x)? ",": "") /* define if we need a comma */
00806    if (timeval.tv_sec < 0) /* invalid, nothing to show */
00807       return;
00808 
00809    if (printsec)  {  /* plain seconds output */
00810       ast_cli(fd, "%s: %lu\n", prefix, (u_long)timeval.tv_sec);
00811       return;
00812    }
00813    out = ast_str_alloca(256);
00814    if (timeval.tv_sec > YEAR) {
00815       x = (timeval.tv_sec / YEAR);
00816       timeval.tv_sec -= (x * YEAR);
00817       ast_str_append(&out, 0, "%d year%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00818    }
00819    if (timeval.tv_sec > WEEK) {
00820       x = (timeval.tv_sec / WEEK);
00821       timeval.tv_sec -= (x * WEEK);
00822       ast_str_append(&out, 0, "%d week%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00823    }
00824    if (timeval.tv_sec > DAY) {
00825       x = (timeval.tv_sec / DAY);
00826       timeval.tv_sec -= (x * DAY);
00827       ast_str_append(&out, 0, "%d day%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00828    }
00829    if (timeval.tv_sec > HOUR) {
00830       x = (timeval.tv_sec / HOUR);
00831       timeval.tv_sec -= (x * HOUR);
00832       ast_str_append(&out, 0, "%d hour%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00833    }
00834    if (timeval.tv_sec > MINUTE) {
00835       x = (timeval.tv_sec / MINUTE);
00836       timeval.tv_sec -= (x * MINUTE);
00837       ast_str_append(&out, 0, "%d minute%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00838    }
00839    x = timeval.tv_sec;
00840    if (x > 0 || ast_str_strlen(out) == 0) /* if there is nothing, print 0 seconds */
00841       ast_str_append(&out, 0, "%d second%s ", x, ESS(x));
00842    ast_cli(fd, "%s: %s\n", prefix, ast_str_buffer(out));
00843 }

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 1863 of file main/cli.c.

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

Referenced by __ast_cli_register().

01864 {
01865    int i;
01866    char buf[80];
01867 
01868    ast_join(buf, sizeof(buf), e->cmda);
01869    e->_full_cmd = ast_strdup(buf);
01870    if (!e->_full_cmd) {
01871       ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf);
01872       return -1;
01873    }
01874    e->cmdlen = strcspn(e->_full_cmd, cli_rsvd);
01875    for (i = 0; e->cmda[i]; i++)
01876       ;
01877    e->args = i;
01878    return 0;
01879 }

static void status_debug_verbose ( struct ast_cli_args a,
const char *  what,
int  old_val,
int  cur_val 
) [static]

Definition at line 408 of file main/cli.c.

References ast_cli(), and ast_cli_args::fd.

Referenced by handle_debug(), and handle_verbose().

00409 {
00410    char was_buf[30];
00411    const char *was;
00412 
00413    if (old_val) {
00414       snprintf(was_buf, sizeof(was_buf), "%d", old_val);
00415       was = was_buf;
00416    } else {
00417       was = "OFF";
00418    }
00419 
00420    if (old_val == cur_val) {
00421       ast_cli(a->fd, "%s is still %s.\n", what, was);
00422    } else {
00423       char now_buf[30];
00424       const char *now;
00425 
00426       if (cur_val) {
00427          snprintf(now_buf, sizeof(now_buf), "%d", cur_val);
00428          now = now_buf;
00429       } else {
00430          now = "OFF";
00431       }
00432 
00433       ast_cli(a->fd, "%s was %s and is now %s.\n", what, was, now);
00434    }
00435 }

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 2043 of file main/cli.c.

References ast_strlen_zero, and strcasestr().

Referenced by __ast_cli_generator(), and find_cli().

02044 {
02045    int l;
02046    char *pos;
02047 
02048    if (ast_strlen_zero(cmd) || ast_strlen_zero(cli_word))
02049       return -1;
02050    if (!strchr(cli_rsvd, cli_word[0])) /* normal match */
02051       return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1;
02052    l = strlen(cmd);
02053    /* wildcard match - will extend in the future */
02054    if (l > 0 && cli_word[0] == '%') {
02055       return 1;   /* wildcard */
02056    }
02057 
02058    /* Start a search for the command entered against the cli word in question */
02059    pos = strcasestr(cli_word, cmd);
02060    while (pos) {
02061 
02062       /*
02063        *Check if the word matched with is surrounded by reserved characters on both sides
02064        * and isn't at the beginning of the cli_word since that would make it check in a location we shouldn't know about.
02065        * If it is surrounded by reserved chars and isn't at the beginning, it's a match.
02066        */
02067       if (pos != cli_word && strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) {
02068          return 1;   /* valid match */
02069       }
02070 
02071       /* Ok, that one didn't match, strcasestr to the next appearance of the command and start over.*/
02072       pos = strcasestr(pos + 1, cmd);
02073    }
02074    /* If no matches were found over the course of the while loop, we hit the end of the string. It's a mismatch. */
02075    return -1;
02076 }


Variable Documentation

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

Definition at line 110 of file main/cli.c.

struct ast_cli_entry cli_cli[] [static]

Definition at line 1806 of file main/cli.c.

int cli_default_perm = 1 [static]

Default permissions value 1=Permit 0=Deny.

Definition at line 88 of file main/cli.c.

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

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

Definition at line 1857 of file main/cli.c.

int climodentryfd = -1 [static]

Definition at line 779 of file main/cli.c.

ast_mutex_t climodentrylock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

Definition at line 778 of file main/cli.c.

Referenced by handle_modlist().

struct module_level_list debug_modules = AST_RWLIST_HEAD_INIT_VALUE [static]

list of module names and their debug levels

Definition at line 108 of file main/cli.c.

Referenced by ast_debug_get_by_module(), and handle_debug().

const char perms_config[] = "cli_permissions.conf" [static]

CLI permissions config file.

Definition at line 86 of file main/cli.c.

Referenced by ast_cli_perms_init().

ast_mutex_t permsconfiglock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

mutex used to prevent a user from running the 'cli reload permissions' command while it is already running.

Definition at line 92 of file main/cli.c.


Generated on Thu Apr 16 06:30:12 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6