Wed Apr 6 11:30:02 2011

Asterisk developer's documentation


cli.c File Reference

Standard Command Line Interface. More...

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

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\n"
#define MODLIST_FORMAT2   "%-30s %-40.40s %-10s\n"
#define NEEDCOMMA(x)   ((x)? ",": "")
#define SECOND   (1)
#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-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 __init_ast_cli_buf (void)
void ast_builtins_init (void)
 initialize the _full_cmd string in * each of the builtins.
void ast_cli (int fd, const char *fmt,...)
int ast_cli_command_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 struct ast_cli_entrycli_next (struct ast_cli_entry *e)
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_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, unsigned int debug)
 Find the debug or verbose file setting.
static char * group_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_chanlist (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_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_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 *like)
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 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 = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP }
static struct module_level_list debug_modules
static const char perms_config [] = "cli_permissions.conf"
 CLI permissions config file.
static ast_mutex_t permsconfiglock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP }
 mutex used to prevent a user from running the 'cli reload permissions' command while it is already running.
static struct module_level_list verbose_modules


Detailed Description

Standard Command Line Interface.

Author:
Mark Spencer <markster@digium.com>

Definition in file cli.c.


Define Documentation

#define AST_CLI_INITLEN   256

Initial buffer size for resulting strings in ast_cli().

Definition at line 99 of file 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"

Referenced by group_show_channels(), and handle_chanlist().

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

Referenced by handle_chanlist().

#define HOUR   (MINUTE*60)

Referenced by print_uptimestr().

#define MINUTE   (SECOND*60)

Referenced by print_uptimestr().

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

Definition at line 641 of file cli.c.

Referenced by modlist_modentry().

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

Definition at line 642 of file cli.c.

Referenced by handle_modlist().

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

Referenced by print_uptimestr().

#define SECOND   (1)

#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-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 2345 of file cli.c.

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

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

02346 {
02347    const char *argv[AST_MAX_ARGS];
02348    struct ast_cli_entry *e = NULL;
02349    int x = 0, argindex, matchlen;
02350    int matchnum=0;
02351    char *ret = NULL;
02352    char matchstr[80] = "";
02353    int tws = 0;
02354    /* Split the argument into an array of words */
02355    char *duplicate = parse_args(text, &x, argv, ARRAY_LEN(argv), &tws);
02356 
02357    if (!duplicate)   /* malloc error */
02358       return NULL;
02359 
02360    /* Compute the index of the last argument (could be an empty string) */
02361    argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x;
02362 
02363    /* rebuild the command, ignore terminating white space and flatten space */
02364    ast_join(matchstr, sizeof(matchstr)-1, argv);
02365    matchlen = strlen(matchstr);
02366    if (tws) {
02367       strcat(matchstr, " "); /* XXX */
02368       if (matchlen)
02369          matchlen++;
02370    }
02371    if (lock)
02372       AST_RWLIST_RDLOCK(&helpers);
02373    while ( (e = cli_next(e)) ) {
02374       /* XXX repeated code */
02375       int src = 0, dst = 0, n = 0;
02376 
02377       if (e->command[0] == '_')
02378          continue;
02379 
02380       /*
02381        * Try to match words, up to and excluding the last word, which
02382        * is either a blank or something that we want to extend.
02383        */
02384       for (;src < argindex; dst++, src += n) {
02385          n = word_match(argv[src], e->cmda[dst]);
02386          if (n < 0)
02387             break;
02388       }
02389 
02390       if (src != argindex && more_words(e->cmda + dst))  /* not a match */
02391          continue;
02392       ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n);
02393       matchnum += n; /* this many matches here */
02394       if (ret) {
02395          /*
02396           * argv[src] is a valid prefix of the next word in this
02397           * command. If this is also the correct entry, return it.
02398           */
02399          if (matchnum > state)
02400             break;
02401          ast_free(ret);
02402          ret = NULL;
02403       } else if (ast_strlen_zero(e->cmda[dst])) {
02404          /*
02405           * This entry is a prefix of the command string entered
02406           * (only one entry in the list should have this property).
02407           * Run the generator if one is available. In any case we are done.
02408           */
02409          if (e->handler) { /* new style command */
02410             struct ast_cli_args a = {
02411                .line = matchstr, .word = word,
02412                .pos = argindex,
02413                .n = state - matchnum,
02414                .argv = argv,
02415                .argc = x};
02416             ret = e->handler(e, CLI_GENERATE, &a);
02417          }
02418          if (ret)
02419             break;
02420       }
02421    }
02422    if (lock)
02423       AST_RWLIST_UNLOCK(&helpers);
02424    ast_free(duplicate);
02425    return ret;
02426 }

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

Definition at line 2032 of file cli.c.

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

Referenced by ast_cli_register().

02033 {
02034    struct ast_cli_entry *cur;
02035    int i, lf, ret = -1;
02036 
02037    struct ast_cli_args a;  /* fake argument */
02038    char **dst = (char **)e->cmda;   /* need to cast as the entry is readonly */
02039    char *s;
02040 
02041    memset(&a, '\0', sizeof(a));
02042    e->handler(e, CLI_INIT, &a);
02043    /* XXX check that usage and command are filled up */
02044    s = ast_skip_blanks(e->command);
02045    s = e->command = ast_strdup(s);
02046    for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) {
02047       *dst++ = s; /* store string */
02048       s = ast_skip_nonblanks(s);
02049       if (*s == '\0')   /* we are done */
02050          break;
02051       *s++ = '\0';
02052       s = ast_skip_blanks(s);
02053    }
02054    *dst++ = NULL;
02055    
02056    AST_RWLIST_WRLOCK(&helpers);
02057    
02058    if (find_cli(e->cmda, 1)) {
02059       ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", S_OR(e->_full_cmd, e->command));
02060       goto done;
02061    }
02062    if (set_full_cmd(e))
02063       goto done;
02064 
02065    lf = e->cmdlen;
02066    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
02067       int len = cur->cmdlen;
02068       if (lf < len)
02069          len = lf;
02070       if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) {
02071          AST_RWLIST_INSERT_BEFORE_CURRENT(e, list); 
02072          break;
02073       }
02074    }
02075    AST_RWLIST_TRAVERSE_SAFE_END;
02076 
02077    if (!cur)
02078       AST_RWLIST_INSERT_TAIL(&helpers, e, list); 
02079    ret = 0; /* success */
02080 
02081 done:
02082    AST_RWLIST_UNLOCK(&helpers);
02083 
02084    return ret;
02085 }

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

Definition at line 2010 of file cli.c.

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

Referenced by ast_cli_unregister().

02011 {
02012    if (e->inuse) {
02013       ast_log(LOG_WARNING, "Can't remove command that is in use\n");
02014    } else {
02015       AST_RWLIST_WRLOCK(&helpers);
02016       AST_RWLIST_REMOVE(&helpers, e, list);
02017       AST_RWLIST_UNLOCK(&helpers);
02018       ast_free(e->_full_cmd);
02019       e->_full_cmd = NULL;
02020       if (e->handler) {
02021          /* this is a new-style entry. Reset fields and free memory. */
02022          char *cmda = (char *) e->cmda;
02023          memset(cmda, '\0', sizeof(e->cmda));
02024          ast_free(e->command);
02025          e->command = NULL;
02026          e->usage = NULL;
02027       }
02028    }
02029    return 0;
02030 }

static void __init_ast_cli_buf ( void   )  [static]

Definition at line 96 of file cli.c.

00102 {

void ast_builtins_init ( void   ) 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 1853 of file cli.c.

References ARRAY_LEN, ast_cli_register_multiple(), and cli_cli.

Referenced by main().

01854 {
01855    ast_cli_register_multiple(cli_cli, ARRAY_LEN(cli_cli));
01856 }

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

Definition at line 101 of file cli.c.

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

Referenced by __iax2_show_peers(), __say_cli_init(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), agent_logoff_cmd(), agents_show(), agents_show_online(), ais_clm_show_members(), ais_evt_show_event_channels(), aji_cli_create_collection(), aji_cli_create_leafnode(), aji_cli_delete_pubsub_node(), aji_cli_list_pubsub_nodes(), aji_cli_purge_pubsub_nodes(), aji_do_reload(), aji_do_set_debug(), aji_show_buddies(), aji_show_clients(), aji_test(), alias_show(), aoc_cli_debug_enable(), ast_cli_command_full(), ast_cli_netstats(), ast_console_toggle_mute(), 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_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_realtime_destroy(), cli_realtime_load(), cli_realtime_store(), cli_realtime_update(), cli_realtime_update2(), cli_tps_ping(), cli_tps_report(), console_active(), console_answer(), console_autoanswer(), console_boost(), console_cmd(), console_dial(), console_do_answer(), console_flash(), console_hangup(), console_mute(), console_sendtext(), console_transfer(), dahdi_set_dnd(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), dahdi_show_status(), dahdi_show_version(), data_provider_print_cli(), data_result_print_cli(), data_result_print_cli_node(), dialog_dump_func(), do_print(), dump_raw_ie(), dundi_do_lookup(), dundi_do_precache(), dundi_do_query(), dundi_flush(), dundi_set_debug(), dundi_show_entityid(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), dundi_store_history(), event_dump_cache(), event_dump_cli(), group_show_channels(), gtalk_show_channels(), handle_chanlist(), handle_cli_agi_debug(), handle_cli_agi_dump_html(), handle_cli_agi_show(), handle_cli_check_permissions(), handle_cli_config_list(), handle_cli_core_show_channeltype(), handle_cli_core_show_channeltypes(), handle_cli_core_show_config_mappings(), handle_cli_core_show_file_formats(), handle_cli_core_show_translation(), handle_cli_database_del(), handle_cli_database_deltree(), handle_cli_database_get(), handle_cli_database_put(), handle_cli_database_show(), handle_cli_database_showkey(), handle_cli_devstate_change(), handle_cli_devstate_list(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_add_ignorepat(), handle_cli_dialplan_add_include(), handle_cli_dialplan_reload(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_remove_ignorepat(), handle_cli_dialplan_remove_include(), handle_cli_dialplan_save(), handle_cli_file_convert(), handle_cli_h323_set_debug(), handle_cli_h323_set_trace(), handle_cli_iax2_provision(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_set_debug_jb(), handle_cli_iax2_set_debug_trunk(), handle_cli_iax2_set_mtu(), handle_cli_iax2_show_cache(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_firmware(), handle_cli_iax2_show_netstats(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_stats(), handle_cli_iax2_show_threads(), handle_cli_iax2_show_users(), handle_cli_iax2_unregister(), handle_cli_indication_show(), handle_cli_keys_show(), handle_cli_misdn_reload(), handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_set_debug(), handle_cli_misdn_show_channels(), handle_cli_misdn_show_config(), handle_cli_misdn_show_port(), handle_cli_misdn_show_ports_stats(), handle_cli_misdn_show_stacks(), handle_cli_misdn_toggle_echocancel(), handle_cli_mixmonitor(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_cli_odbc_show(), handle_cli_osp_show(), handle_cli_realtime_pgsql_cache(), handle_cli_realtime_pgsql_status(), handle_cli_refresh(), handle_cli_rtcp_set_debug(), handle_cli_rtcp_set_stats(), handle_cli_rtp_set_debug(), handle_cli_show_permissions(), handle_cli_show_sqlite_status(), handle_cli_sqlite_show_tables(), handle_cli_status(), handle_cli_stun_set_debug(), handle_cli_submit(), 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_dialplan(), handle_feature_show(), handle_help(), handle_load(), handle_logger_reload(), handle_logger_rotate(), handle_logger_set_level(), handle_logger_show_channels(), handle_manager_show_settings(), handle_mandebug(), handle_mfcr2_set_debug(), handle_mfcr2_show_channels(), handle_mfcr2_show_variants(), handle_mfcr2_version(), 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_parkedcalls(), handle_pri_debug(), handle_pri_service_generic(), handle_pri_set_debug_file(), handle_pri_show_debug(), handle_pri_show_span(), handle_pri_version(), handle_queue_add_member(), handle_queue_pause_member(), handle_queue_remove_member(), handle_queue_rule_show(), handle_queue_set_member_penalty(), handle_redirect(), handle_reload(), handle_restart_when_convenient(), handle_set_chanvar(), handle_set_extenpatternmatchnew(), handle_set_global(), handle_show_applications(), handle_show_calendar(), handle_show_calendars(), handle_show_chanvar(), handle_show_dialplan(), handle_show_function(), handle_show_functions(), handle_show_globals(), handle_show_hint(), handle_show_hints(), handle_show_http(), handle_show_profile(), handle_show_routes(), handle_show_settings(), handle_show_switches(), handle_show_sysinfo(), handle_show_threads(), handle_show_version_files(), handle_showcalls(), handle_showchan(), handle_showmanager(), handle_showmanagers(), handle_showmancmd(), handle_showmancmds(), handle_showmanconn(), handle_showmaneventq(), handle_skinny_set_debug(), handle_skinny_show_settings(), handle_softhangup(), handle_ss7_block_cic(), handle_ss7_block_linkset(), handle_ss7_debug(), handle_ss7_show_linkset(), handle_ss7_unblock_cic(), handle_ss7_unblock_linkset(), handle_ss7_version(), handle_stop_when_convenient(), handle_unload(), handle_unset_extenpatternmatchnew(), handle_verbose(), handle_version(), handle_voicemail_reload(), handle_voicemail_show_users(), handle_voicemail_show_zones(), help1(), help_workhorse(), iax_show_provisioning(), jingle_show_channels(), locals_show(), meetme_cmd(), meetme_show_cmd(), modlist_modentry(), orig_app(), orig_exten(), peer_dump_func(), pktccops_debug(), pktccops_gatedel(), pktccops_gateset(), pktccops_show_cmtses(), pktccops_show_gates(), pktccops_show_pools(), print_app(), print_app_docs(), print_bc_info(), print_cel_sub(), print_codec_to_cli(), print_group(), print_stats_cb(), print_uptimestr(), radio_active(), radio_set_debug(), radio_set_debug_off(), radio_set_xpmr_debug(), radio_tune(), realtime_ldap_status(), rpt_do_cmd(), rpt_do_debug(), rpt_do_dump(), rpt_do_fun(), rpt_do_local_nodes(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_chanstats_cb(), show_codec_n(), show_codecs(), show_config_description(), show_debug_helper(), show_dialplan_helper(), show_license(), show_users_realtime(), show_warranty(), sig_pri_cli_show_span(), sig_pri_cli_show_spans(), 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(), timing_test(), tune_rxctcss(), tune_rxinput(), tune_rxvoice(), tune_txoutput(), unistim_do_debug(), unistim_info(), and unistim_sp().

00102 {
00103    int res;
00104    struct ast_str *buf;
00105    va_list ap;
00106 
00107    if (!(buf = ast_str_thread_get(&ast_cli_buf, AST_CLI_INITLEN)))
00108       return;
00109 
00110    va_start(ap, fmt);
00111    res = ast_str_set_va(&buf, 0, fmt, ap);
00112    va_end(ap);
00113 
00114    if (res != AST_DYNSTR_BUILD_FAILED) {
00115       ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
00116    }
00117 }

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 2433 of file 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, ast_cli_args::fd, find_best(), find_cli(), ast_cli_entry::handler, ast_cli_entry::inuse, parse_args(), S_OR, and ast_cli_entry::usage.

Referenced by ast_cli_command_multiple_full().

02434 {
02435    const char *args[AST_MAX_ARGS + 1];
02436    struct ast_cli_entry *e;
02437    int x;
02438    char *duplicate = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL);
02439    char tmp[AST_MAX_ARGS + 1];
02440    char *retval = NULL;
02441    struct ast_cli_args a = {
02442       .fd = fd, .argc = x, .argv = args+1 };
02443 
02444    if (duplicate == NULL)
02445       return -1;
02446 
02447    if (x < 1)  /* We need at least one entry, otherwise ignore */
02448       goto done;
02449 
02450    AST_RWLIST_RDLOCK(&helpers);
02451    e = find_cli(args + 1, 0);
02452    if (e)
02453       ast_atomic_fetchadd_int(&e->inuse, 1);
02454    AST_RWLIST_UNLOCK(&helpers);
02455    if (e == NULL) {
02456       ast_cli(fd, "No such command '%s' (type 'core show help %s' for other possible commands)\n", s, find_best(args + 1));
02457       goto done;
02458    }
02459 
02460    ast_join(tmp, sizeof(tmp), args + 1);
02461    /* Check if the user has rights to run this command. */
02462    if (!cli_has_permissions(uid, gid, tmp)) {
02463       ast_cli(fd, "You don't have permissions to run '%s' command\n", tmp);
02464       ast_free(duplicate);
02465       return 0;
02466    }
02467 
02468    /*
02469     * Within the handler, argv[-1] contains a pointer to the ast_cli_entry.
02470     * Remember that the array returned by parse_args is NULL-terminated.
02471     */
02472    args[0] = (char *)e;
02473 
02474    retval = e->handler(e, CLI_HANDLER, &a);
02475 
02476    if (retval == CLI_SHOWUSAGE) {
02477       ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
02478    } else {
02479       if (retval == CLI_FAILURE)
02480          ast_cli(fd, "Command '%s' failed.\n", s);
02481    }
02482    ast_atomic_fetchadd_int(&e->inuse, -1);
02483 done:
02484    ast_free(duplicate);
02485    return 0;
02486 }

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

References ast_cli_command_full().

Referenced by netconsole().

02489 {
02490    char cmd[512];
02491    int x, y = 0, count = 0;
02492 
02493    for (x = 0; x < size; x++) {
02494       cmd[y] = s[x];
02495       y++;
02496       if (s[x] == '\0') {
02497          ast_cli_command_full(uid, gid, fd, cmd);
02498          y = 0;
02499          count++;
02500       }
02501    }
02502    return count;
02503 }

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

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

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

01514 {
01515    int i, which = 0, len;
01516    len = ast_strlen_zero(word) ? 0 : strlen(word);
01517 
01518    for (i = 0; choices[i]; i++) {
01519       if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state)
01520          return ast_strdup(choices[i]);
01521    }
01522    return NULL;
01523 }

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

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

Referenced by cli_complete(), and handle_commandmatchesarray().

02285 {
02286    char **match_list = NULL, *retstr, *prevstr;
02287    size_t match_list_len, max_equal, which, i;
02288    int matches = 0;
02289 
02290    /* leave entry 0 free for the longest common substring */
02291    match_list_len = 1;
02292    while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
02293       if (matches + 1 >= match_list_len) {
02294          match_list_len <<= 1;
02295          if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(*match_list))))
02296             return NULL;
02297       }
02298       match_list[++matches] = retstr;
02299    }
02300 
02301    if (!match_list)
02302       return match_list; /* NULL */
02303 
02304    /* Find the longest substring that is common to all results
02305     * (it is a candidate for completion), and store a copy in entry 0.
02306     */
02307    prevstr = match_list[1];
02308    max_equal = strlen(prevstr);
02309    for (which = 2; which <= matches; which++) {
02310       for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
02311          continue;
02312       max_equal = i;
02313    }
02314 
02315    if (!(retstr = ast_malloc(max_equal + 1)))
02316       return NULL;
02317    
02318    ast_copy_string(retstr, match_list[1], max_equal + 1);
02319    match_list[0] = retstr;
02320 
02321    /* ensure that the array is NULL terminated */
02322    if (matches + 1 >= match_list_len) {
02323       if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list))))
02324          return NULL;
02325    }
02326    match_list[matches + 1] = NULL;
02327 
02328    return match_list;
02329 }

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

References __ast_cli_generator().

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

02429 {
02430    return __ast_cli_generator(text, word, state, 1);
02431 }

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

Return the number of unique matches for the generator.

Definition at line 2267 of file cli.c.

References ast_cli_generator(), and ast_free.

Referenced by handle_commandnummatches().

02268 {
02269    int matches = 0, i = 0;
02270    char *buf = NULL, *oldbuf = NULL;
02271 
02272    while ((buf = ast_cli_generator(text, word, i++))) {
02273       if (!oldbuf || strcmp(buf,oldbuf))
02274          matches++;
02275       if (oldbuf)
02276          ast_free(oldbuf);
02277       oldbuf = buf;
02278    }
02279    if (oldbuf)
02280       ast_free(oldbuf);
02281    return matches;
02282 }

int ast_cli_perms_init ( int  reload  ) 

Provided by cli.c

Definition at line 1730 of file cli.c.

References ast_calloc, ast_category_browse(), ast_config_load2(), ast_free, AST_LIST_TRAVERSE, ast_log(), ast_mutex_trylock, ast_mutex_unlock, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_strlen_zero(), ast_variable_browse(), CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEUNCHANGED, destroy_user_perms(), usergroup_cli_perm::gid, cli_perm::list, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, perms_config, usergroup_cli_perm::uid, and ast_variable::value.

Referenced by handle_cli_reload_permissions(), and main().

01731 {
01732    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
01733    struct ast_config *cfg;
01734    char *cat = NULL;
01735    struct ast_variable *v;
01736    struct usergroup_cli_perm *user_group, *cp_entry;
01737    struct cli_perm *perm = NULL;
01738    struct passwd *pw;
01739    struct group *gr;
01740 
01741    if (ast_mutex_trylock(&permsconfiglock)) {
01742       ast_log(LOG_NOTICE, "You must wait until last 'cli reload permissions' command finish\n");
01743       return 1;
01744    }
01745 
01746    cfg = ast_config_load2(perms_config, "" /* core, can't reload */, config_flags);
01747    if (!cfg) {
01748       ast_mutex_unlock(&permsconfiglock);
01749       return 1;
01750    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
01751       ast_mutex_unlock(&permsconfiglock);
01752       return 0;
01753    }
01754 
01755    /* free current structures. */
01756    destroy_user_perms();
01757 
01758    while ((cat = ast_category_browse(cfg, cat))) {
01759       if (!strcasecmp(cat, "general")) {
01760          /* General options */
01761          for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
01762             if (!strcasecmp(v->name, "default_perm")) {
01763                cli_default_perm = (!strcasecmp(v->value, "permit")) ? 1: 0;
01764             }
01765          }
01766          continue;
01767       }
01768 
01769       /* users or groups */
01770       gr = NULL, pw = NULL;
01771       if (cat[0] == '@') {
01772          /* This is a group */
01773          gr = getgrnam(&cat[1]);
01774          if (!gr) {
01775             ast_log (LOG_WARNING, "Unknown group '%s'\n", &cat[1]);
01776             continue;
01777          }
01778       } else {
01779          /* This is a user */
01780          pw = getpwnam(cat);
01781          if (!pw) {
01782             ast_log (LOG_WARNING, "Unknown user '%s'\n", cat);
01783             continue;
01784          }
01785       }
01786       user_group = NULL;
01787       /* Check for duplicates */
01788       AST_RWLIST_WRLOCK(&cli_perms);
01789       AST_LIST_TRAVERSE(&cli_perms, cp_entry, list) {
01790          if ((pw && cp_entry->uid == pw->pw_uid) || (gr && cp_entry->gid == gr->gr_gid)) {
01791             /* if it is duplicated, just added this new settings, to 
01792             the current list. */
01793             user_group = cp_entry;
01794             break;
01795          }
01796       }
01797       AST_RWLIST_UNLOCK(&cli_perms);
01798 
01799       if (!user_group) {
01800          /* alloc space for the new user config. */
01801          user_group = ast_calloc(1, sizeof(*user_group));
01802          if (!user_group) {
01803             continue;
01804          }
01805          user_group->uid = (pw ? pw->pw_uid : -1);
01806          user_group->gid = (gr ? gr->gr_gid : -1);
01807          user_group->perms = ast_calloc(1, sizeof(*user_group->perms));
01808          if (!user_group->perms) {
01809             ast_free(user_group);
01810             continue;
01811          }
01812       }
01813       for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
01814          if (ast_strlen_zero(v->value)) {
01815             /* we need to check this condition cause it could break security. */
01816             ast_log(LOG_WARNING, "Empty permit/deny option in user '%s'\n", cat);
01817             continue;
01818          }
01819          if (!strcasecmp(v->name, "permit")) {
01820             perm = ast_calloc(1, sizeof(*perm));
01821             if (perm) {
01822                perm->permit = 1;
01823                perm->command = ast_strdup(v->value);
01824             }
01825          } else if (!strcasecmp(v->name, "deny")) {
01826             perm = ast_calloc(1, sizeof(*perm));
01827             if (perm) {
01828                perm->permit = 0;
01829                perm->command = ast_strdup(v->value);
01830             }
01831          } else {
01832             /* up to now, only 'permit' and 'deny' are possible values. */
01833             ast_log(LOG_WARNING, "Unknown '%s' option\n", v->name);
01834             continue;
01835          }
01836          if (perm) {
01837             /* Added the permission to the user's list. */
01838             AST_LIST_INSERT_TAIL(user_group->perms, perm, list);
01839             perm = NULL;
01840          }
01841       }
01842       AST_RWLIST_WRLOCK(&cli_perms);
01843       AST_RWLIST_INSERT_TAIL(&cli_perms, user_group, list);
01844       AST_RWLIST_UNLOCK(&cli_perms);
01845    }
01846 
01847    ast_config_destroy(cfg);
01848    ast_mutex_unlock(&permsconfiglock);
01849    return 0;
01850 }

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

References __ast_cli_register().

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

02095 {
02096    return __ast_cli_register(e, NULL);
02097 }

int ast_cli_register_multiple ( struct ast_cli_entry e,
int  len 
)

Register multiple commands.

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

Definition at line 2102 of file cli.c.

References ast_cli_register().

Referenced by __ast_register_translator(), __init_manager(), ast_ais_clm_load_module(), ast_ais_evt_load_module(), ast_aoc_cli_init(), ast_builtins_init(), ast_cc_init(), ast_channels_init(), ast_data_init(), ast_event_init(), ast_features_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_stun_init(), ast_test_init(), ast_timing_init(), ast_tps_init(), ast_udptl_init(), ast_utils_init(), astdb_init(), astobj2_init(), crypto_init(), iax_provision_init(), init_framer(), init_logger(), load_module(), load_pbx(), main(), and register_config_cli().

02103 {
02104    int i, res = 0;
02105 
02106    for (i = 0; i < len; i++)
02107       res |= ast_cli_register(e + i);
02108 
02109    return res;
02110 }

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

References __ast_cli_unregister().

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

02089 {
02090    return __ast_cli_unregister(e, NULL);
02091 }

int ast_cli_unregister_multiple ( struct ast_cli_entry e,
int  len 
)

Unregister multiple commands.

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

Definition at line 2112 of file cli.c.

References ast_cli_unregister().

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

02113 {
02114    int i, res = 0;
02115 
02116    for (i = 0; i < len; i++)
02117       res |= ast_cli_unregister(e + i);
02118 
02119    return res;
02120 }

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

References ast_channel_iterator_all_new(), ast_channel_iterator_by_name_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_strdup, ast_strlen_zero(), and state::name.

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

01526 {
01527    struct ast_channel *c = NULL;
01528    int which = 0;
01529    char notfound = '\0';
01530    char *ret = &notfound; /* so NULL can break the loop */
01531    struct ast_channel_iterator *iter;
01532 
01533    if (pos != rpos) {
01534       return NULL;
01535    }
01536 
01537    if (ast_strlen_zero(word)) {
01538       iter = ast_channel_iterator_all_new();
01539    } else {
01540       iter = ast_channel_iterator_by_name_new(word, strlen(word));
01541    }
01542 
01543    if (!iter) {
01544       return NULL;
01545    }
01546 
01547    while (ret == &notfound && (c = ast_channel_iterator_next(iter))) {
01548       if (++which > state) {
01549          ast_channel_lock(c);
01550          ret = ast_strdup(c->name);
01551          ast_channel_unlock(c);
01552       }
01553       ast_channel_unref(c);
01554    }
01555 
01556    ast_channel_iterator_destroy(iter);
01557 
01558    return ret == &notfound ? NULL : ret;
01559 }

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

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

00120 {
00121    struct module_level *ml;
00122    unsigned int res = 0;
00123 
00124    AST_RWLIST_RDLOCK(&debug_modules);
00125    AST_LIST_TRAVERSE(&debug_modules, ml, entry) {
00126       if (!strcasecmp(ml->module, module)) {
00127          res = ml->level;
00128          break;
00129       }
00130    }
00131    AST_RWLIST_UNLOCK(&debug_modules);
00132 
00133    return res;
00134 }

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

Definition at line 136 of file cli.c.

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

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

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

Definition at line 1276 of file cli.c.

References args, ast_channel_lock, ast_channel_unlock, ast_cli(), DEBUGCHAN_FLAG, ast_channel::fin, ast_channel::fout, and ast_channel::name.

Referenced by handle_core_set_debug_channel().

01277 {
01278    struct ast_channel *chan = obj;
01279    struct channel_set_debug_args *args = data;
01280 
01281    ast_channel_lock(chan);
01282 
01283    if (!(chan->fin & DEBUGCHAN_FLAG) || !(chan->fout & DEBUGCHAN_FLAG)) {
01284       if (args->is_off) {
01285          chan->fin &= ~DEBUGCHAN_FLAG;
01286          chan->fout &= ~DEBUGCHAN_FLAG;
01287       } else {
01288          chan->fin |= DEBUGCHAN_FLAG;
01289          chan->fout |= DEBUGCHAN_FLAG;
01290       }
01291       ast_cli(args->fd, "Debugging %s on channel %s\n", args->is_off ? "disabled" : "enabled",
01292             chan->name);
01293    }
01294 
01295    ast_channel_unlock(chan);
01296 
01297    return 0;
01298 }

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

Definition at line 166 of file cli.c.

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

Referenced by ast_cli_command_full(), and handle_cli_check_permissions().

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

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

Definition at line 708 of file cli.c.

References AST_LIST_FIRST, AST_LIST_NEXT, and cli_perm::list.

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

00709 {
00710    if (e) {
00711       return AST_LIST_NEXT(e, list);
00712    } else {
00713       return AST_LIST_FIRST(&helpers);
00714    }
00715 }

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

Definition at line 223 of file cli.c.

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

Referenced by handle_load().

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

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

Definition at line 345 of file cli.c.

References ast_strdup, ast_strlen_zero(), and cli_perm::next.

Referenced by handle_verbose().

00346 {
00347    int i, count = 0;
00348    unsigned int prospective[2];
00349    unsigned int part = strtoul(partial, NULL, 10);
00350    char next[12];
00351 
00352    if (part < min || part > max) {
00353       return NULL;
00354    }
00355 
00356    for (i = 0; i < 21; i++) {
00357       if (i == 0) {
00358          prospective[0] = prospective[1] = part;
00359       } else if (part == 0 && !ast_strlen_zero(partial)) {
00360          break;
00361       } else if (i < 11) {
00362          prospective[0] = prospective[1] = part * 10 + (i - 1);
00363       } else {
00364          prospective[0] = (part * 10 + (i - 11)) * 10;
00365          prospective[1] = prospective[0] + 9;
00366       }
00367       if (i < 11 && (prospective[0] < min || prospective[0] > max)) {
00368          continue;
00369       } else if (prospective[1] < min || prospective[0] > max) {
00370          continue;
00371       }
00372 
00373       if (++count > n) {
00374          if (i < 11) {
00375             snprintf(next, sizeof(next), "%u", prospective[0]);
00376          } else {
00377             snprintf(next, sizeof(next), "%u...", prospective[0] / 10);
00378          }
00379          return ast_strdup(next);
00380       }
00381    }
00382    return NULL;
00383 }

static void destroy_user_perms ( void   )  [static]

cleanup (free) cli_perms linkedlist.

Definition at line 1714 of file cli.c.

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

Referenced by ast_cli_perms_init().

01715 {
01716    struct cli_perm *perm;
01717    struct usergroup_cli_perm *user_perm;
01718 
01719    AST_RWLIST_WRLOCK(&cli_perms);
01720    while ((user_perm = AST_LIST_REMOVE_HEAD(&cli_perms, list))) {
01721       while ((perm = AST_LIST_REMOVE_HEAD(user_perm->perms, list))) {
01722          ast_free(perm->command);
01723          ast_free(perm);
01724       }
01725       ast_free(user_perm);
01726    }
01727    AST_RWLIST_UNLOCK(&cli_perms);
01728 }

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

Definition at line 1992 of file cli.c.

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

01993 {
01994    static char cmdline[80];
01995    int x;
01996    /* See how close we get, then print the candidate */
01997    const char *myargv[AST_MAX_CMD_LEN] = { NULL, };
01998 
01999    AST_RWLIST_RDLOCK(&helpers);
02000    for (x = 0; argv[x]; x++) {
02001       myargv[x] = argv[x];
02002       if (!find_cli(myargv, -1))
02003          break;
02004    }
02005    AST_RWLIST_UNLOCK(&helpers);
02006    ast_join(cmdline, sizeof(cmdline), myargv);
02007    return cmdline;
02008 }

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

Definition at line 1948 of file cli.c.

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

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

01949 {
01950    int matchlen = -1;   /* length of longest match so far */
01951    struct ast_cli_entry *cand = NULL, *e=NULL;
01952 
01953    while ( (e = cli_next(e)) ) {
01954       /* word-by word regexp comparison */
01955       const char * const *src = cmds;
01956       const char * const *dst = e->cmda;
01957       int n = 0;
01958       for (;; dst++, src += n) {
01959          n = word_match(*src, *dst);
01960          if (n < 0)
01961             break;
01962       }
01963       if (ast_strlen_zero(*dst) || ((*dst)[0] == '[' && ast_strlen_zero(dst[1]))) {
01964          /* no more words in 'e' */
01965          if (ast_strlen_zero(*src)) /* exact match, cannot do better */
01966             break;
01967          /* Here, cmds has more words than the entry 'e' */
01968          if (match_type != 0) /* but we look for almost exact match... */
01969             continue;   /* so we skip this one. */
01970          /* otherwise we like it (case 0) */
01971       } else { /* still words in 'e' */
01972          if (ast_strlen_zero(*src))
01973             continue; /* cmds is shorter than 'e', not good */
01974          /* Here we have leftover words in cmds and 'e',
01975           * but there is a mismatch. We only accept this one if match_type == -1
01976           * and this is the last word for both.
01977           */
01978          if (match_type != -1 || !ast_strlen_zero(src[1]) ||
01979              !ast_strlen_zero(dst[1])) /* not the one we look for */
01980             continue;
01981          /* good, we are in case match_type == -1 and mismatch on last word */
01982       }
01983       if (src - cmds > matchlen) {  /* remember the candidate */
01984          matchlen = src - cmds;
01985          cand = e;
01986       }
01987    }
01988 
01989    return e ? e : cand;
01990 }

static struct module_level* find_module_level ( const char *  module,
unsigned int  debug 
) [static]

Find the debug or verbose file setting.

Definition at line 332 of file cli.c.

References AST_LIST_TRAVERSE, and module_level::module.

Referenced by handle_verbose().

00333 {
00334    struct module_level *ml;
00335    struct module_level_list *mll = debug ? &debug_modules : &verbose_modules;
00336 
00337    AST_LIST_TRAVERSE(mll, ml, entry) {
00338       if (!strcasecmp(ml->module, module))
00339          return ml;
00340    }
00341 
00342    return NULL;
00343 }

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

Definition at line 1561 of file cli.c.

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

01562 {
01563 #define FORMAT_STRING  "%-25s  %-20s  %-20s\n"
01564 
01565    struct ast_group_info *gi = NULL;
01566    int numchans = 0;
01567    regex_t regexbuf;
01568    int havepattern = 0;
01569 
01570    switch (cmd) {
01571    case CLI_INIT:
01572       e->command = "group show channels";
01573       e->usage = 
01574          "Usage: group show channels [pattern]\n"
01575          "       Lists all currently active channels with channel group(s) specified.\n"
01576          "       Optional regular expression pattern is matched to group names for each\n"
01577          "       channel.\n";
01578       return NULL;
01579    case CLI_GENERATE:
01580       return NULL;
01581    }
01582 
01583    if (a->argc < 3 || a->argc > 4)
01584       return CLI_SHOWUSAGE;
01585    
01586    if (a->argc == 4) {
01587       if (regcomp(&regexbuf, a->argv[3], REG_EXTENDED | REG_NOSUB))
01588          return CLI_SHOWUSAGE;
01589       havepattern = 1;
01590    }
01591 
01592    ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category");
01593 
01594    ast_app_group_list_rdlock();
01595    
01596    gi = ast_app_group_list_head();
01597    while (gi) {
01598       if (!havepattern || !regexec(&regexbuf, gi->group, 0, NULL, 0)) {
01599          ast_cli(a->fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category));
01600          numchans++;
01601       }
01602       gi = AST_LIST_NEXT(gi, group_list);
01603    }
01604    
01605    ast_app_group_list_unlock();
01606    
01607    if (havepattern)
01608       regfree(&regexbuf);
01609 
01610    ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
01611    return CLI_SUCCESS;
01612 #undef FORMAT_STRING
01613 }

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

Definition at line 842 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_active_channels(), ast_bridged_channel(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_processed_calls(), ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, CONCISE_FORMAT_STRING, ESS, ast_cli_args::fd, FORMAT_STRING, FORMAT_STRING2, option_maxcalls, S_COR, S_OR, ast_cli_entry::usage, VERBOSE_FORMAT_STRING, and VERBOSE_FORMAT_STRING2.

00843 {
00844 #define FORMAT_STRING  "%-20.20s %-20.20s %-7.7s %-30.30s\n"
00845 #define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n"
00846 #define CONCISE_FORMAT_STRING  "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
00847 #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"
00848 #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"
00849 
00850    struct ast_channel *c = NULL;
00851    int numchans = 0, concise = 0, verbose = 0, count = 0;
00852    struct ast_channel_iterator *iter = NULL;
00853 
00854    switch (cmd) {
00855    case CLI_INIT:
00856       e->command = "core show channels [concise|verbose|count]";
00857       e->usage =
00858          "Usage: core show channels [concise|verbose|count]\n"
00859          "       Lists currently defined channels and some information about them. If\n"
00860          "       'concise' is specified, the format is abridged and in a more easily\n"
00861          "       machine parsable format. If 'verbose' is specified, the output includes\n"
00862          "       more and longer fields. If 'count' is specified only the channel and call\n"
00863          "       count is output.\n"
00864          "  The 'concise' option is deprecated and will be removed from future versions\n"
00865          "  of Asterisk.\n";
00866       return NULL;
00867 
00868    case CLI_GENERATE:
00869       return NULL;
00870    }
00871 
00872    if (a->argc == e->args) {
00873       if (!strcasecmp(a->argv[e->args-1],"concise"))
00874          concise = 1;
00875       else if (!strcasecmp(a->argv[e->args-1],"verbose"))
00876          verbose = 1;
00877       else if (!strcasecmp(a->argv[e->args-1],"count"))
00878          count = 1;
00879       else
00880          return CLI_SHOWUSAGE;
00881    } else if (a->argc != e->args - 1)
00882       return CLI_SHOWUSAGE;
00883 
00884    if (!count) {
00885       if (!concise && !verbose)
00886          ast_cli(a->fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)");
00887       else if (verbose)
00888          ast_cli(a->fd, VERBOSE_FORMAT_STRING2, "Channel", "Context", "Extension", "Priority", "State", "Application", "Data", 
00889             "CallerID", "Duration", "Accountcode", "PeerAccount", "BridgedTo");
00890    }
00891 
00892    if (!count && !(iter = ast_channel_iterator_all_new())) {
00893       return CLI_FAILURE;
00894    }
00895 
00896    for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
00897       struct ast_channel *bc;
00898       char durbuf[10] = "-";
00899 
00900       ast_channel_lock(c);
00901 
00902       bc = ast_bridged_channel(c);
00903 
00904       if (!count) {
00905          if ((concise || verbose)  && c->cdr && !ast_tvzero(c->cdr->start)) {
00906             int duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
00907             if (verbose) {
00908                int durh = duration / 3600;
00909                int durm = (duration % 3600) / 60;
00910                int durs = duration % 60;
00911                snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
00912             } else {
00913                snprintf(durbuf, sizeof(durbuf), "%d", duration);
00914             }           
00915          }
00916          if (concise) {
00917             ast_cli(a->fd, CONCISE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
00918                c->appl ? c->appl : "(None)",
00919                S_OR(c->data, ""),   /* XXX different from verbose ? */
00920                S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
00921                S_OR(c->accountcode, ""),
00922                S_OR(c->peeraccount, ""),
00923                c->amaflags, 
00924                durbuf,
00925                bc ? bc->name : "(None)",
00926                c->uniqueid);
00927          } else if (verbose) {
00928             ast_cli(a->fd, VERBOSE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
00929                c->appl ? c->appl : "(None)",
00930                c->data ? S_OR(c->data, "(Empty)" ): "(None)",
00931                S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
00932                durbuf,
00933                S_OR(c->accountcode, ""),
00934                S_OR(c->peeraccount, ""),
00935                bc ? bc->name : "(None)");
00936          } else {
00937             char locbuf[40] = "(None)";
00938             char appdata[40] = "(None)";
00939             
00940             if (!ast_strlen_zero(c->context) && !ast_strlen_zero(c->exten)) 
00941                snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority);
00942             if (c->appl)
00943                snprintf(appdata, sizeof(appdata), "%s(%s)", c->appl, S_OR(c->data, ""));
00944             ast_cli(a->fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata);
00945          }
00946       }
00947       ast_channel_unlock(c);
00948    }
00949 
00950    if (iter) {
00951       ast_channel_iterator_destroy(iter);
00952    }
00953 
00954    if (!concise) {
00955       numchans = ast_active_channels();
00956       ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
00957       if (option_maxcalls)
00958          ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
00959             ast_active_calls(), option_maxcalls, ESS(ast_active_calls()),
00960             ((double)ast_active_calls() / (double)option_maxcalls) * 100.0);
00961       else
00962          ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
00963 
00964       ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
00965    }
00966 
00967    return CLI_SUCCESS;
00968    
00969 #undef FORMAT_STRING
00970 #undef FORMAT_STRING2
00971 #undef CONCISE_FORMAT_STRING
00972 #undef VERBOSE_FORMAT_STRING
00973 #undef VERBOSE_FORMAT_STRING2
00974 }

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 1088 of file 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, ast_cli_args::pos, S_OR, ast_cli_entry::summary, ast_cli_entry::usage, and ast_cli_args::word.

01089 {
01090    struct passwd *pw = NULL;
01091    struct group *gr;
01092    int gid = -1, uid = -1;
01093    char command[AST_MAX_ARGS] = "";
01094    struct ast_cli_entry *ce = NULL;
01095    int found = 0;
01096    char *group, *tmp;
01097 
01098    switch (cmd) {
01099    case CLI_INIT:
01100       e->command = "cli check permissions";
01101       e->usage =
01102          "Usage: cli check permissions {<username>|@<groupname>|<username>@<groupname>} [<command>]\n"
01103          "       Check permissions config for a user@group or list the allowed commands for the specified user.\n"
01104          "       The username or the groupname may be omitted.\n";
01105       return NULL;
01106    case CLI_GENERATE:
01107       if (a->pos >= 4) {
01108          return ast_cli_generator(a->line + strlen("cli check permissions") + strlen(a->argv[3]) + 1, a->word, a->n);
01109       }
01110       return NULL;
01111    }
01112 
01113    if (a->argc < 4) {
01114       return CLI_SHOWUSAGE;
01115    }
01116 
01117    tmp = ast_strdupa(a->argv[3]);
01118    group = strchr(tmp, '@');
01119    if (group) {
01120       gr = getgrnam(&group[1]);
01121       if (!gr) {
01122          ast_cli(a->fd, "Unknown group '%s'\n", &group[1]);
01123          return CLI_FAILURE;
01124       }
01125       group[0] = '\0';
01126       gid = gr->gr_gid;
01127    }
01128 
01129    if (!group && ast_strlen_zero(tmp)) {
01130       ast_cli(a->fd, "You didn't supply a username\n");
01131    } else if (!ast_strlen_zero(tmp) && !(pw = getpwnam(tmp))) {
01132       ast_cli(a->fd, "Unknown user '%s'\n", tmp);
01133       return CLI_FAILURE;
01134    } else if (pw) {
01135       uid = pw->pw_uid;
01136    }
01137 
01138    if (a->argc == 4) {
01139       while ((ce = cli_next(ce))) {
01140          /* Hide commands that start with '_' */
01141          if (ce->_full_cmd[0] == '_') {
01142             continue;
01143          }
01144          if (cli_has_permissions(uid, gid, ce->_full_cmd)) {
01145             ast_cli(a->fd, "%30.30s %s\n", ce->_full_cmd, S_OR(ce->summary, "<no description available>"));
01146             found++;
01147          }
01148       }
01149       if (!found) {
01150          ast_cli(a->fd, "You are not allowed to run any command on Asterisk\n");
01151       }
01152    } else {
01153       ast_join(command, sizeof(command), a->argv + 4);
01154       ast_cli(a->fd, "%s '%s%s%s' is %s to run command: '%s'\n", uid >= 0 ? "User" : "Group", tmp,
01155          group && uid >= 0 ? "@" : "",
01156          group ? &group[1] : "",
01157          cli_has_permissions(uid, gid, command) ? "allowed" : "not allowed", command);
01158    }
01159 
01160    return CLI_SUCCESS;
01161 }

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

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

01070 {
01071    switch (cmd) {
01072    case CLI_INIT:
01073       e->command = "cli reload permissions";
01074       e->usage =
01075          "Usage: cli reload permissions\n"
01076          "       Reload the 'cli_permissions.conf' file.\n";
01077       return NULL;
01078    case CLI_GENERATE:
01079       return NULL;
01080    }
01081 
01082    ast_cli_perms_init(1);
01083 
01084    return CLI_SUCCESS;
01085 }

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 1024 of file 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, cli_perm::list, cli_perm::permit, usergroup_cli_perm::perms, usergroup_cli_perm::uid, and ast_cli_entry::usage.

01025 {
01026    struct usergroup_cli_perm *cp;
01027    struct cli_perm *perm;
01028    struct passwd *pw = NULL;
01029    struct group *gr = NULL;
01030 
01031    switch (cmd) {
01032    case CLI_INIT:
01033       e->command = "cli show permissions";
01034       e->usage =
01035          "Usage: cli show permissions\n"
01036          "       Shows CLI configured permissions.\n";
01037       return NULL;
01038    case CLI_GENERATE:
01039       return NULL;
01040    }
01041 
01042    AST_RWLIST_RDLOCK(&cli_perms);
01043    AST_LIST_TRAVERSE(&cli_perms, cp, list) {
01044       if (cp->uid >= 0) {
01045          pw = getpwuid(cp->uid);
01046          if (pw) {
01047             ast_cli(a->fd, "user: %s [uid=%d]\n", pw->pw_name, cp->uid);
01048          }
01049       } else {
01050          gr = getgrgid(cp->gid);
01051          if (gr) {
01052             ast_cli(a->fd, "group: %s [gid=%d]\n", gr->gr_name, cp->gid);
01053          }
01054       }
01055       ast_cli(a->fd, "Permissions:\n");
01056       if (cp->perms) {
01057          AST_LIST_TRAVERSE(cp->perms, perm, list) {
01058             ast_cli(a->fd, "\t%s -> %s\n", perm->permit ? "permit" : "deny", perm->command);
01059          }
01060       }
01061       ast_cli(a->fd, "\n");
01062    }
01063    AST_RWLIST_UNLOCK(&cli_perms);
01064 
01065    return CLI_SUCCESS;
01066 }

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

Definition at line 1615 of file 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, and ast_cli_entry::usage.

01616 {
01617    switch (cmd) {
01618    case CLI_INIT:
01619       e->command = "core waitfullybooted";
01620       e->usage =
01621          "Usage: core waitfullybooted\n"
01622          "  Wait until Asterisk has fully booted.\n";
01623       return NULL;
01624    case CLI_GENERATE:
01625       return NULL;
01626    }
01627 
01628    while (!ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
01629       usleep(100);
01630    }
01631 
01632    ast_cli(a->fd, "Asterisk has fully booted.\n");
01633 
01634    return CLI_SUCCESS;
01635 }

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

Definition at line 1246 of file cli.c.

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

01247 {
01248    char *buf;
01249    switch (cmd) {
01250    case CLI_INIT:
01251       e->command = "_command complete";
01252       e->usage = 
01253          "Usage: _command complete \"<line>\" text state\n"
01254          "       This function is used internally to help with command completion and should.\n"
01255          "       never be called by the user directly.\n";
01256       return NULL;
01257    case CLI_GENERATE:
01258       return NULL;
01259    }
01260    if (a->argc != 5)
01261       return CLI_SHOWUSAGE;
01262    buf = __ast_cli_generator(a->argv[2], a->argv[3], atoi(a->argv[4]), 0);
01263    if (buf) {
01264       ast_cli(a->fd, "%s", buf);
01265       ast_free(buf);
01266    } else
01267       ast_cli(a->fd, "NULL\n");
01268    return CLI_SUCCESS;
01269 }

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

Definition at line 1165 of file cli.c.

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

01166 {
01167    char *buf, *obuf;
01168    int buflen = 2048;
01169    int len = 0;
01170    char **matches;
01171    int x, matchlen;
01172    
01173    switch (cmd) {
01174    case CLI_INIT:
01175       e->command = "_command matchesarray";
01176       e->usage = 
01177          "Usage: _command matchesarray \"<line>\" text \n"
01178          "       This function is used internally to help with command completion and should.\n"
01179          "       never be called by the user directly.\n";
01180       return NULL;
01181    case CLI_GENERATE:
01182       return NULL;
01183    }
01184 
01185    if (a->argc != 4)
01186       return CLI_SHOWUSAGE;
01187    if (!(buf = ast_malloc(buflen)))
01188       return CLI_FAILURE;
01189    buf[len] = '\0';
01190    matches = ast_cli_completion_matches(a->argv[2], a->argv[3]);
01191    if (matches) {
01192       for (x=0; matches[x]; x++) {
01193          matchlen = strlen(matches[x]) + 1;
01194          if (len + matchlen >= buflen) {
01195             buflen += matchlen * 3;
01196             obuf = buf;
01197             if (!(buf = ast_realloc(obuf, buflen))) 
01198                /* Memory allocation failure...  Just free old buffer and be done */
01199                ast_free(obuf);
01200          }
01201          if (buf)
01202             len += sprintf( buf + len, "%s ", matches[x]);
01203          ast_free(matches[x]);
01204          matches[x] = NULL;
01205       }
01206       ast_free(matches);
01207    }
01208 
01209    if (buf) {
01210       ast_cli(a->fd, "%s%s",buf, AST_CLI_COMPLETE_EOF);
01211       ast_free(buf);
01212    } else
01213       ast_cli(a->fd, "NULL\n");
01214 
01215    return CLI_SUCCESS;
01216 }

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

Definition at line 1220 of file cli.c.

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

01221 {
01222    int matches = 0;
01223 
01224    switch (cmd) {
01225    case CLI_INIT:
01226       e->command = "_command nummatches";
01227       e->usage = 
01228          "Usage: _command nummatches \"<line>\" text \n"
01229          "       This function is used internally to help with command completion and should.\n"
01230          "       never be called by the user directly.\n";
01231       return NULL;
01232    case CLI_GENERATE:
01233       return NULL;
01234    }
01235 
01236    if (a->argc != 4)
01237       return CLI_SHOWUSAGE;
01238 
01239    matches = ast_cli_generatornummatches(a->argv[2], a->argv[3]);
01240 
01241    ast_cli(a->fd, "%d", matches);
01242 
01243    return CLI_SUCCESS;
01244 }

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

Definition at line 306 of file 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, and ast_cli_entry::usage.

00307 {
00308    switch (cmd) {
00309    case CLI_INIT:
00310       e->command = "core reload";
00311       e->usage =
00312          "Usage: core reload\n"
00313          "       Execute a global reload.\n";
00314       return NULL;
00315 
00316    case CLI_GENERATE:
00317       return NULL;
00318    }
00319 
00320    if (a->argc != e->args) {
00321       return CLI_SHOWUSAGE;
00322    }
00323 
00324    ast_module_reload(NULL);
00325 
00326    return CLI_SUCCESS;
00327 }

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

Definition at line 1300 of file cli.c.

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

Referenced by handle_nodebugchan_deprecated().

01301 {
01302    struct ast_channel *c = NULL;
01303    struct channel_set_debug_args args = {
01304       .fd = a->fd,
01305    };
01306 
01307    switch (cmd) {
01308    case CLI_INIT:
01309       e->command = "core set debug channel";
01310       e->usage =
01311          "Usage: core set debug channel <all|channel> [off]\n"
01312          "       Enables/disables debugging on all or on a specific channel.\n";
01313       return NULL;
01314    case CLI_GENERATE:
01315       /* XXX remember to handle the optional "off" */
01316       if (a->pos != e->args)
01317          return NULL;
01318       return a->n == 0 ? ast_strdup("all") : ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
01319    }
01320 
01321    if (cmd == (CLI_HANDLER + 1000)) {
01322       /* called from handle_nodebugchan_deprecated */
01323       args.is_off = 1;
01324    } else if (a->argc == e->args + 2) {
01325       /* 'core set debug channel {all|chan_id}' */
01326       if (!strcasecmp(a->argv[e->args + 1], "off"))
01327          args.is_off = 1;
01328       else
01329          return CLI_SHOWUSAGE;
01330    } else if (a->argc != e->args + 1) {
01331       return CLI_SHOWUSAGE;
01332    }
01333 
01334    if (!strcasecmp("all", a->argv[e->args])) {
01335       if (args.is_off) {
01336          global_fin &= ~DEBUGCHAN_FLAG;
01337          global_fout &= ~DEBUGCHAN_FLAG;
01338       } else {
01339          global_fin |= DEBUGCHAN_FLAG;
01340          global_fout |= DEBUGCHAN_FLAG;
01341       }
01342       ast_channel_callback(channel_set_debug, NULL, &args, OBJ_NODATA | OBJ_MULTIPLE);
01343    } else {
01344       if ((c = ast_channel_get_by_name(a->argv[e->args]))) {
01345          channel_set_debug(c, NULL, &args, 0);
01346          ast_channel_unref(c);
01347       } else {
01348          ast_cli(a->fd, "No such channel %s\n", a->argv[e->args]);
01349       }
01350    }
01351 
01352    ast_cli(a->fd, "Debugging on new channels is %s\n", args.is_off ? "disabled" : "enabled");
01353 
01354    return CLI_SUCCESS;
01355 }

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

Definition at line 2155 of file 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, ast_cli_entry::usage, and ast_cli_args::word.

02156 {
02157    char fullcmd[80];
02158    struct ast_cli_entry *my_e;
02159    char *res = CLI_SUCCESS;
02160 
02161    if (cmd == CLI_INIT) {
02162       e->command = "core show help";
02163       e->usage =
02164          "Usage: core show help [topic]\n"
02165          "       When called with a topic as an argument, displays usage\n"
02166          "       information on the given command. If called without a\n"
02167          "       topic, it provides a list of commands.\n";
02168       return NULL;
02169 
02170    } else if (cmd == CLI_GENERATE) {
02171       /* skip first 14 or 15 chars, "core show help " */
02172       int l = strlen(a->line);
02173 
02174       if (l > 15) {
02175          l = 15;
02176       }
02177       /* XXX watch out, should stop to the non-generator parts */
02178       return __ast_cli_generator(a->line + l, a->word, a->n, 0);
02179    }
02180    if (a->argc == e->args) {
02181       return help1(a->fd, NULL, 0);
02182    }
02183 
02184    AST_RWLIST_RDLOCK(&helpers);
02185    my_e = find_cli(a->argv + 3, 1); /* try exact match first */
02186    if (!my_e) {
02187       res = help1(a->fd, a->argv + 3, 1 /* locked */);
02188       AST_RWLIST_UNLOCK(&helpers);
02189       return res;
02190    }
02191    if (my_e->usage)
02192       ast_cli(a->fd, "%s", my_e->usage);
02193    else {
02194       ast_join(fullcmd, sizeof(fullcmd), a->argv + 3);
02195       ast_cli(a->fd, "No help text available for '%s'.\n", fullcmd);
02196    }
02197    AST_RWLIST_UNLOCK(&helpers);
02198    return res;
02199 }

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

Definition at line 245 of file cli.c.

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

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

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

Definition at line 567 of file cli.c.

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

00568 {
00569    switch (cmd) {
00570    case CLI_INIT:
00571       e->command = "logger mute";
00572       e->usage = 
00573          "Usage: logger mute\n"
00574          "       Disables logging output to the current console, making it possible to\n"
00575          "       gather information without being disturbed by scrolling lines.\n";
00576       return NULL;
00577    case CLI_GENERATE:
00578       return NULL;
00579    }
00580 
00581    if (a->argc < 2 || a->argc > 3)
00582       return CLI_SHOWUSAGE;
00583 
00584    if (a->argc == 3 && !strcasecmp(a->argv[2], "silent"))
00585       ast_console_toggle_mute(a->fd, 1);
00586    else
00587       ast_console_toggle_mute(a->fd, 0);
00588 
00589    return CLI_SUCCESS;
00590 }

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

Definition at line 748 of file cli.c.

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

00749 {
00750    const char *like;
00751 
00752    switch (cmd) {
00753    case CLI_INIT:
00754       e->command = "module show [like]";
00755       e->usage =
00756          "Usage: module show [like keyword]\n"
00757          "       Shows Asterisk modules currently in use, and usage statistics.\n";
00758       return NULL;
00759 
00760    case CLI_GENERATE:
00761       if (a->pos == e->args)
00762          return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0);
00763       else
00764          return NULL;
00765    }
00766    /* all the above return, so we proceed with the handler.
00767     * we are guaranteed to have argc >= e->args
00768     */
00769    if (a->argc == e->args - 1)
00770       like = "";
00771    else if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args-1], "like") )
00772       like = a->argv[e->args];
00773    else
00774       return CLI_SHOWUSAGE;
00775       
00776    ast_mutex_lock(&climodentrylock);
00777    climodentryfd = a->fd; /* global, protected by climodentrylock */
00778    ast_cli(a->fd, MODLIST_FORMAT2, "Module", "Description", "Use Count");
00779    ast_cli(a->fd,"%d modules loaded\n", ast_update_module_list(modlist_modentry, like));
00780    climodentryfd = -1;
00781    ast_mutex_unlock(&climodentrylock);
00782    return CLI_SUCCESS;
00783 }

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

Definition at line 1357 of file cli.c.

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

01358 {
01359    char *res;
01360 
01361    switch (cmd) {
01362    case CLI_INIT:
01363       e->command = "no debug channel";
01364       return NULL;
01365    case CLI_HANDLER:
01366       /* exit out of switch statement */
01367       break;
01368    default:
01369       return NULL;
01370    }
01371 
01372    if (a->argc != e->args + 1)
01373       return CLI_SHOWUSAGE;
01374 
01375    /* add a 'magic' value to the CLI_HANDLER command so that
01376     * handle_core_set_debug_channel() will act as if 'off'
01377     * had been specified as part of the command
01378     */
01379    res = handle_core_set_debug_channel(e, CLI_HANDLER + 1000, a);
01380 
01381    return res;
01382 }

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

Definition at line 271 of file cli.c.

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

00272 {
00273    int x;
00274 
00275    switch (cmd) {
00276    case CLI_INIT:
00277       e->command = "module reload";
00278       e->usage =
00279          "Usage: module reload [module ...]\n"
00280          "       Reloads configuration files for all listed modules which support\n"
00281          "       reloading, or for all supported modules if none are listed.\n";
00282       return NULL;
00283 
00284    case CLI_GENERATE:
00285       return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 1);
00286    }
00287    if (a->argc == e->args) {
00288       ast_module_reload(NULL);
00289       return CLI_SUCCESS;
00290    }
00291    for (x = e->args; x < a->argc; x++) {
00292       int res = ast_module_reload(a->argv[x]);
00293       /* XXX reload has multiple error returns, including -1 on error and 2 on success */
00294       switch (res) {
00295       case 0:
00296          ast_cli(a->fd, "No such module '%s'\n", a->argv[x]);
00297          break;
00298       case 1:
00299          ast_cli(a->fd, "Module '%s' does not support reload\n", a->argv[x]);
00300          break;
00301       }
00302    }
00303    return CLI_SUCCESS;
00304 }

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

Definition at line 787 of file cli.c.

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

00788 {
00789    struct timeval curtime = ast_tvnow();
00790    int showuptime, printsec;
00791 
00792    switch (cmd) {
00793    case CLI_INIT:
00794       e->command = "core show calls [uptime]";
00795       e->usage =
00796          "Usage: core show calls [uptime] [seconds]\n"
00797          "       Lists number of currently active calls and total number of calls\n"
00798          "       processed through PBX since last restart. If 'uptime' is specified\n"
00799          "       the system uptime is also displayed. If 'seconds' is specified in\n"
00800          "       addition to 'uptime', the system uptime is displayed in seconds.\n";
00801       return NULL;
00802 
00803    case CLI_GENERATE:
00804       if (a->pos != e->args)
00805          return NULL;
00806       return a->n == 0  ? ast_strdup("seconds") : NULL;
00807    }
00808 
00809    /* regular handler */
00810    if (a->argc >= e->args && !strcasecmp(a->argv[e->args-1],"uptime")) {
00811       showuptime = 1;
00812 
00813       if (a->argc == e->args+1 && !strcasecmp(a->argv[e->args],"seconds"))
00814          printsec = 1;
00815       else if (a->argc == e->args)
00816          printsec = 0;
00817       else
00818          return CLI_SHOWUSAGE;
00819    } else if (a->argc == e->args-1) {
00820       showuptime = 0;
00821       printsec = 0;
00822    } else
00823       return CLI_SHOWUSAGE;
00824 
00825    if (option_maxcalls) {
00826       ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
00827          ast_active_calls(), option_maxcalls, ESS(ast_active_calls()),
00828          ((double)ast_active_calls() / (double)option_maxcalls) * 100.0);
00829    } else {
00830       ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
00831    }
00832    
00833    ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
00834 
00835    if (ast_startuptime.tv_sec && showuptime) {
00836       print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec);
00837    }
00838 
00839    return RESULT_SUCCESS;
00840 }

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

Definition at line 1384 of file cli.c.

References ast_channel::_bridge, ast_channel::_state, ast_cli_args::argc, ast_cli_args::argv, ast_bridged_channel(), ast_cdr_serialize_variables(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), AST_FLAG_BLOCKING, ast_getformatname_multiple(), ast_state2str(), ast_str_alloca, ast_str_buffer(), ast_str_thread_get(), ast_test_flag, ast_translate_path_to_str(), ast_tvnow(), ast_channel::caller, ast_channel::cdr, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEBUGCHAN_FLAG, ast_channel::dialed, ast_cli_args::fd, ast_channel::fds, ast_channel::fin, ast_channel::fout, ast_party_caller::id, ast_channel::language, ast_cli_args::line, ast_channel::linkedid, ast_cli_args::n, name, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, pbx_builtin_serialize_variables(), ast_cli_args::pos, ast_channel::readformat, ast_channel::readtrans, ast_channel::rings, S_COR, S_OR, ast_cdr::start, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech, ast_channel_tech::type, ast_channel::uniqueid, ast_cli_entry::usage, ast_party_name::valid, ast_party_number::valid, ast_channel::whentohangup, ast_cli_args::word, ast_channel::writeformat, and ast_channel::writetrans.

01385 {
01386    struct ast_channel *c=NULL;
01387    struct timeval now;
01388    struct ast_str *out = ast_str_thread_get(&ast_str_thread_global_buf, 16);
01389    char cdrtime[256];
01390    char nf[256], wf[256], rf[256];
01391    struct ast_str *write_transpath = ast_str_alloca(256);
01392    struct ast_str *read_transpath = ast_str_alloca(256);
01393    long elapsed_seconds=0;
01394    int hour=0, min=0, sec=0;
01395 #ifdef CHANNEL_TRACE
01396    int trace_enabled;
01397 #endif
01398 
01399    switch (cmd) {
01400    case CLI_INIT:
01401       e->command = "core show channel";
01402       e->usage = 
01403          "Usage: core show channel <channel>\n"
01404          "       Shows lots of information about the specified channel.\n";
01405       return NULL;
01406    case CLI_GENERATE:
01407       return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
01408    }
01409    
01410    if (a->argc != 4) {
01411       return CLI_SHOWUSAGE;
01412    }
01413 
01414    now = ast_tvnow();
01415 
01416    if (!(c = ast_channel_get_by_name(a->argv[3]))) {
01417       ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
01418       return CLI_SUCCESS;
01419    }
01420 
01421    ast_channel_lock(c);
01422 
01423    if (c->cdr) {
01424       elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
01425       hour = elapsed_seconds / 3600;
01426       min = (elapsed_seconds % 3600) / 60;
01427       sec = elapsed_seconds % 60;
01428       snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
01429    } else {
01430       strcpy(cdrtime, "N/A");
01431    }
01432 
01433    ast_cli(a->fd, 
01434       " -- General --\n"
01435       "           Name: %s\n"
01436       "           Type: %s\n"
01437       "       UniqueID: %s\n"
01438       "       LinkedID: %s\n"
01439       "      Caller ID: %s\n"
01440       " Caller ID Name: %s\n"
01441       "    DNID Digits: %s\n"
01442       "       Language: %s\n"
01443       "          State: %s (%d)\n"
01444       "          Rings: %d\n"
01445       "  NativeFormats: %s\n"
01446       "    WriteFormat: %s\n"
01447       "     ReadFormat: %s\n"
01448       " WriteTranscode: %s %s\n"
01449       "  ReadTranscode: %s %s\n"
01450       "1st File Descriptor: %d\n"
01451       "      Frames in: %d%s\n"
01452       "     Frames out: %d%s\n"
01453       " Time to Hangup: %ld\n"
01454       "   Elapsed Time: %s\n"
01455       "  Direct Bridge: %s\n"
01456       "Indirect Bridge: %s\n"
01457       " --   PBX   --\n"
01458       "        Context: %s\n"
01459       "      Extension: %s\n"
01460       "       Priority: %d\n"
01461       "     Call Group: %llu\n"
01462       "   Pickup Group: %llu\n"
01463       "    Application: %s\n"
01464       "           Data: %s\n"
01465       "    Blocking in: %s\n",
01466       c->name, c->tech->type, c->uniqueid, c->linkedid,
01467       S_COR(c->caller.id.number.valid, c->caller.id.number.str, "(N/A)"),
01468       S_COR(c->caller.id.name.valid, c->caller.id.name.str, "(N/A)"),
01469       S_OR(c->dialed.number.str, "(N/A)"),
01470       c->language,   
01471       ast_state2str(c->_state), c->_state, c->rings, 
01472       ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats), 
01473       ast_getformatname_multiple(wf, sizeof(wf), c->writeformat), 
01474       ast_getformatname_multiple(rf, sizeof(rf), c->readformat),
01475       c->writetrans ? "Yes" : "No",
01476       ast_translate_path_to_str(c->writetrans, &write_transpath),
01477       c->readtrans ? "Yes" : "No",
01478       ast_translate_path_to_str(c->readtrans, &read_transpath),
01479       c->fds[0],
01480       c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
01481       c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
01482       (long)c->whentohangup.tv_sec,
01483       cdrtime, c->_bridge ? c->_bridge->name : "<none>", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "<none>", 
01484       c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ),
01485       ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),
01486       (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
01487    
01488    if (pbx_builtin_serialize_variables(c, &out)) {
01489       ast_cli(a->fd,"      Variables:\n%s\n", ast_str_buffer(out));
01490    }
01491 
01492    if (c->cdr && ast_cdr_serialize_variables(c->cdr, &out, '=', '\n', 1)) {
01493       ast_cli(a->fd,"  CDR Variables:\n%s\n", ast_str_buffer(out));
01494    }
01495 
01496 #ifdef CHANNEL_TRACE
01497    trace_enabled = ast_channel_trace_is_enabled(c);
01498    ast_cli(a->fd, "  Context Trace: %s\n", trace_enabled ? "Enabled" : "Disabled");
01499    if (trace_enabled && ast_channel_trace_serialize(c, &out))
01500       ast_cli(a->fd, "          Trace:\n%s\n", ast_str_buffer(out));
01501 #endif
01502 
01503    ast_channel_unlock(c);
01504    c = ast_channel_unref(c);
01505 
01506    return CLI_SUCCESS;
01507 }

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

Definition at line 717 of file cli.c.

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

00718 {
00719    struct timeval curtime = ast_tvnow();
00720    int printsec;
00721 
00722    switch (cmd) {
00723    case CLI_INIT:
00724       e->command = "core show uptime [seconds]";
00725       e->usage =
00726          "Usage: core show uptime [seconds]\n"
00727          "       Shows Asterisk uptime information.\n"
00728          "       The seconds word returns the uptime in seconds only.\n";
00729       return NULL;
00730 
00731    case CLI_GENERATE:
00732       return NULL;
00733    }
00734    /* regular handler */
00735    if (a->argc == e->args && !strcasecmp(a->argv[e->args-1],"seconds"))
00736       printsec = 1;
00737    else if (a->argc == e->args-1)
00738       printsec = 0;
00739    else
00740       return CLI_SHOWUSAGE;
00741    if (ast_startuptime.tv_sec)
00742       print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec);
00743    if (ast_lastreloadtime.tv_sec)
00744       print_uptimestr(a->fd, ast_tvsub(curtime, ast_lastreloadtime), "Last reload", printsec);
00745    return CLI_SUCCESS;
00746 }

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

Definition at line 976 of file 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_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_channel::name, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

00977 {
00978    struct ast_channel *c=NULL;
00979 
00980    switch (cmd) {
00981    case CLI_INIT:
00982       e->command = "channel request hangup";
00983       e->usage =
00984          "Usage: channel request hangup <channel>|<all>\n"
00985          "       Request that a channel be hung up. The hangup takes effect\n"
00986          "       the next time the driver reads or writes from the channel.\n"
00987          "       If 'all' is specified instead of a channel name, all channels\n"
00988          "       will see the hangup request.\n";
00989       return NULL;
00990    case CLI_GENERATE:
00991       return ast_complete_channels(a->line, a->word, a->pos, a->n, e->args);
00992    }
00993 
00994    if (a->argc != 4) {
00995       return CLI_SHOWUSAGE;
00996    }
00997 
00998    if (!strcasecmp(a->argv[3], "all")) {
00999       struct ast_channel_iterator *iter = NULL;
01000       if (!(iter = ast_channel_iterator_all_new())) {
01001          return CLI_FAILURE;
01002       }
01003       for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
01004          ast_channel_lock(c);
01005          ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name);
01006          ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01007          ast_channel_unlock(c);
01008       }
01009       ast_channel_iterator_destroy(iter);
01010    } else if ((c = ast_channel_get_by_name(a->argv[3]))) {
01011       ast_channel_lock(c);
01012       ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name);
01013       ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01014       ast_channel_unlock(c);
01015       c = ast_channel_unref(c);
01016    } else {
01017       ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
01018    }
01019 
01020    return CLI_SUCCESS;
01021 }

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

Definition at line 592 of file cli.c.

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

00593 {
00594    /* "module unload mod_1 [mod_2 .. mod_N]" */
00595    int x;
00596    int force = AST_FORCE_SOFT;
00597    const char *s;
00598 
00599    switch (cmd) {
00600    case CLI_INIT:
00601       e->command = "module unload";
00602       e->usage =
00603          "Usage: module unload [-f|-h] <module_1> [<module_2> ... ]\n"
00604          "       Unloads the specified module from Asterisk. The -f\n"
00605          "       option causes the module to be unloaded even if it is\n"
00606          "       in use (may cause a crash) and the -h module causes the\n"
00607          "       module to be unloaded even if the module says it cannot, \n"
00608          "       which almost always will cause a crash.\n";
00609       return NULL;
00610 
00611    case CLI_GENERATE:
00612       return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0);
00613    }
00614    if (a->argc < e->args + 1)
00615       return CLI_SHOWUSAGE;
00616    x = e->args;   /* first argument */
00617    s = a->argv[x];
00618    if (s[0] == '-') {
00619       if (s[1] == 'f')
00620          force = AST_FORCE_FIRM;
00621       else if (s[1] == 'h')
00622          force = AST_FORCE_HARD;
00623       else
00624          return CLI_SHOWUSAGE;
00625       if (a->argc < e->args + 2) /* need at least one module name */
00626          return CLI_SHOWUSAGE;
00627       x++;  /* skip this argument */
00628    }
00629 
00630    for (; x < a->argc; x++) {
00631       if (ast_unload_resource(a->argv[x], force)) {
00632          ast_cli(a->fd, "Unable to unload resource %s\n", a->argv[x]);
00633          return CLI_FAILURE;
00634       }
00635       ast_cli(a->fd, "Unloaded %s\n", a->argv[x]);
00636    }
00637 
00638    return CLI_SUCCESS;
00639 }

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

Definition at line 385 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, args, ast_cli_args::argv, ast_calloc, ast_clear_flag, ast_cli(), ast_complete_source_filename(), ast_free, AST_OPT_FLAG_DEBUG_MODULE, AST_OPT_FLAG_VERBOSE_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(), module_level::entry, ast_cli_args::fd, find_module_level(), module_level::level, module_level::module, ast_cli_args::n, option_debug, option_verbose, ast_cli_args::pos, S_OR, and ast_cli_entry::usage.

00386 {
00387    int oldval;
00388    int newlevel;
00389    unsigned int is_debug;
00390    int atleast = 0;
00391    int fd = a->fd;
00392    int argc = a->argc;
00393    const char * const *argv = a->argv;
00394    const char *argv3 = a->argv ? S_OR(a->argv[3], "") : "";
00395    int *dst;
00396    char *what;
00397    struct module_level_list *mll;
00398    struct module_level *ml;
00399 
00400    switch (cmd) {
00401    case CLI_INIT:
00402       e->command = "core set {debug|verbose}";
00403       e->usage =
00404 #if !defined(LOW_MEMORY)
00405          "Usage: core set {debug|verbose} [atleast] <level> [module]\n"
00406 #else
00407          "Usage: core set {debug|verbose} [atleast] <level>\n"
00408 #endif
00409          "       core set {debug|verbose} off\n"
00410 #if !defined(LOW_MEMORY)
00411          "       Sets level of debug or verbose messages to be displayed or\n"
00412          "       sets a module name to display debug messages from.\n"
00413 #else
00414          "       Sets level of debug or verbose messages to be displayed.\n"
00415 #endif
00416          "  0 or off means no messages should be displayed.\n"
00417          "  Equivalent to -d[d[...]] or -v[v[v...]] on startup\n";
00418       return NULL;
00419 
00420    case CLI_GENERATE:
00421       if (a->pos == 3 || (a->pos == 4 && !strcasecmp(a->argv[3], "atleast"))) {
00422          const char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], "");
00423          int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21;
00424          if (a->n < 21 && numbermatch == 0) {
00425             return complete_number(pos, 0, 0x7fffffff, a->n);
00426          } else if (pos[0] == '0') {
00427             if (a->n == 0) {
00428                return ast_strdup("0");
00429             } else {
00430                return NULL;
00431             }
00432          } else if (a->n == (21 - numbermatch)) {
00433             if (a->pos == 3 && !strncasecmp(argv3, "off", strlen(argv3))) {
00434                return ast_strdup("off");
00435             } else if (a->pos == 3 && !strncasecmp(argv3, "atleast", strlen(argv3))) {
00436                return ast_strdup("atleast");
00437             }
00438          } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) {
00439             return ast_strdup("atleast");
00440          }
00441 #if !defined(LOW_MEMORY)
00442       } else if (a->pos == 4 || (a->pos == 5 && !strcasecmp(argv3, "atleast"))) {
00443          return ast_complete_source_filename(a->pos == 4 ? S_OR(a->argv[4], "") : S_OR(a->argv[5], ""), a->n);
00444 #endif
00445       }
00446       return NULL;
00447    }
00448    /* all the above return, so we proceed with the handler.
00449     * we are guaranteed to be called with argc >= e->args;
00450     */
00451 
00452    if (argc <= e->args)
00453       return CLI_SHOWUSAGE;
00454    if (!strcasecmp(argv[e->args - 1], "debug")) {
00455       dst = &option_debug;
00456       oldval = option_debug;
00457       what = "Core debug";
00458       is_debug = 1;
00459    } else {
00460       dst = &option_verbose;
00461       oldval = option_verbose;
00462       what = "Verbosity";
00463       is_debug = 0;
00464    }
00465    if (argc == e->args + 1 && !strcasecmp(argv[e->args], "off")) {
00466       newlevel = 0;
00467 
00468       mll = is_debug ? &debug_modules : &verbose_modules;
00469 
00470       AST_RWLIST_WRLOCK(mll);
00471       while ((ml = AST_RWLIST_REMOVE_HEAD(mll, entry))) {
00472          ast_free(ml);
00473       }
00474       ast_clear_flag(&ast_options, is_debug ? AST_OPT_FLAG_DEBUG_MODULE : AST_OPT_FLAG_VERBOSE_MODULE);
00475       AST_RWLIST_UNLOCK(mll);
00476 
00477       goto done;
00478    }
00479    if (!strcasecmp(argv[e->args], "atleast"))
00480       atleast = 1;
00481    if (argc != e->args + atleast + 1 && argc != e->args + atleast + 2)
00482       return CLI_SHOWUSAGE;
00483    if (sscanf(argv[e->args + atleast], "%30d", &newlevel) != 1)
00484       return CLI_SHOWUSAGE;
00485    if (argc == e->args + atleast + 2) {
00486       /* We have specified a module name. */
00487       char *mod = ast_strdupa(argv[e->args + atleast + 1]);
00488 
00489       if ((strlen(mod) > 3) && !strcasecmp(mod + strlen(mod) - 3, ".so")) {
00490          mod[strlen(mod) - 3] = '\0';
00491       }
00492 
00493       mll = is_debug ? &debug_modules : &verbose_modules;
00494 
00495       AST_RWLIST_WRLOCK(mll);
00496 
00497       ml = find_module_level(mod, is_debug);
00498       if (!newlevel) {
00499          if (!ml) {
00500             /* Specified off for a nonexistent entry. */
00501             AST_RWLIST_UNLOCK(mll);
00502             return CLI_SUCCESS;
00503          }
00504          AST_RWLIST_REMOVE(mll, ml, entry);
00505          if (AST_RWLIST_EMPTY(mll))
00506             ast_clear_flag(&ast_options, is_debug ? AST_OPT_FLAG_DEBUG_MODULE : AST_OPT_FLAG_VERBOSE_MODULE);
00507          AST_RWLIST_UNLOCK(mll);
00508          ast_cli(fd, "%s was %d and has been set to 0 for '%s'\n", what, ml->level, mod);
00509          ast_free(ml);
00510          return CLI_SUCCESS;
00511       }
00512 
00513       if (ml) {
00514          if ((atleast && newlevel < ml->level) || ml->level == newlevel) {
00515             ast_cli(fd, "%s is %d for '%s'\n", what, ml->level, mod);
00516             AST_RWLIST_UNLOCK(mll);
00517             return CLI_SUCCESS;
00518          }
00519          oldval = ml->level;
00520          ml->level = newlevel;
00521       } else {
00522          ml = ast_calloc(1, sizeof(*ml) + strlen(mod) + 1);
00523          if (!ml) {
00524             AST_RWLIST_UNLOCK(mll);
00525             return CLI_FAILURE;
00526          }
00527          oldval = ml->level;
00528          ml->level = newlevel;
00529          strcpy(ml->module, mod);
00530          AST_RWLIST_INSERT_TAIL(mll, ml, entry);
00531       }
00532 
00533       ast_set_flag(&ast_options, is_debug ? AST_OPT_FLAG_DEBUG_MODULE : AST_OPT_FLAG_VERBOSE_MODULE);
00534 
00535       AST_RWLIST_UNLOCK(mll);
00536 
00537       ast_cli(fd, "%s was %d and has been set to %d for '%s'\n", what, oldval, ml->level, ml->module);
00538 
00539       return CLI_SUCCESS;
00540    } else if (!newlevel) {
00541       /* Specified level as 0 instead of off. */
00542       mll = is_debug ? &debug_modules : &verbose_modules;
00543 
00544       AST_RWLIST_WRLOCK(mll);
00545       while ((ml = AST_RWLIST_REMOVE_HEAD(mll, entry))) {
00546          ast_free(ml);
00547       }
00548       ast_clear_flag(&ast_options, is_debug ? AST_OPT_FLAG_DEBUG_MODULE : AST_OPT_FLAG_VERBOSE_MODULE);
00549       AST_RWLIST_UNLOCK(mll);
00550    }
00551 
00552 done:
00553    if (!atleast || newlevel > *dst)
00554       *dst = newlevel;
00555    if (oldval > 0 && *dst == 0)
00556       ast_cli(fd, "%s is now OFF\n", what);
00557    else if (*dst > 0) {
00558       if (oldval == *dst)
00559          ast_cli(fd, "%s is at least %d\n", what, *dst);
00560       else
00561          ast_cli(fd, "%s was %d and is now %d\n", what, oldval, *dst);
00562    }
00563 
00564    return CLI_SUCCESS;
00565 }

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

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

Referenced by handle_help().

02127 {
02128    char matchstr[80] = "";
02129    struct ast_cli_entry *e = NULL;
02130    int len = 0;
02131    int found = 0;
02132 
02133    if (match) {
02134       ast_join(matchstr, sizeof(matchstr), match);
02135       len = strlen(matchstr);
02136    }
02137    if (!locked)
02138       AST_RWLIST_RDLOCK(&helpers);
02139    while ( (e = cli_next(e)) ) {
02140       /* Hide commands that start with '_' */
02141       if (e->_full_cmd[0] == '_')
02142          continue;
02143       if (match && strncasecmp(matchstr, e->_full_cmd, len))
02144          continue;
02145       ast_cli(fd, "%30.30s %s\n", e->_full_cmd, S_OR(e->summary, "<no description available>"));
02146       found++;
02147    }
02148    if (!locked)
02149       AST_RWLIST_UNLOCK(&helpers);
02150    if (!found && matchstr[0])
02151       ast_cli(fd, "No such command '%s'.\n", matchstr);
02152    return CLI_SUCCESS;
02153 }

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

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

Referenced by __ast_cli_generator().

01900 {
01901    int lw;
01902    char *s, *t1;
01903 
01904    *actual = 0;
01905    if (ast_strlen_zero(token))
01906       return NULL;
01907    if (ast_strlen_zero(word))
01908       word = "";  /* dummy */
01909    lw = strlen(word);
01910    if (strcspn(word, cli_rsvd) != lw)
01911       return NULL;   /* no match if word has reserved chars */
01912    if (strchr(cli_rsvd, token[0]) == NULL) { /* regular match */
01913       if (strncasecmp(token, word, lw))   /* no match */
01914          return NULL;
01915       *actual = 1;
01916       return (pos != 0) ? NULL : ast_strdup(token);
01917    }
01918    /* now handle regexp match */
01919 
01920    /* Wildcard always matches, so we never do is_prefix on them */
01921 
01922    t1 = ast_strdupa(token + 1);  /* copy, skipping first char */
01923    while (pos >= 0 && (s = strsep(&t1, cli_rsvd)) && *s) {
01924       if (*s == '%') /* wildcard */
01925          continue;
01926       if (strncasecmp(s, word, lw)) /* no match */
01927          continue;
01928       (*actual)++;
01929       if (pos-- == 0)
01930          return ast_strdup(s);
01931    }
01932    return NULL;
01933 }

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

Definition at line 647 of file cli.c.

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

Referenced by handle_modlist().

00648 {
00649    /* Comparing the like with the module */
00650    if (strcasestr(module, like) ) {
00651       ast_cli(climodentryfd, MODLIST_FORMAT, module, description, usecnt);
00652       return 1;
00653    } 
00654    return 0;
00655 }

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

returns true if there are more words to match

Definition at line 2332 of file cli.c.

Referenced by __ast_cli_generator().

02333 {
02334    int i;
02335    for (i = 0; dst[i]; i++) {
02336       if (dst[i][0] != '[')
02337          return -1;
02338    }
02339    return 0;
02340 }

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

Definition at line 2201 of file cli.c.

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

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

02202 {
02203    char *duplicate, *cur;
02204    int x = 0;
02205    int quoted = 0;
02206    int escaped = 0;
02207    int whitespace = 1;
02208    int dummy = 0;
02209 
02210    if (trailingwhitespace == NULL)
02211       trailingwhitespace = &dummy;
02212    *trailingwhitespace = 0;
02213    if (s == NULL) /* invalid, though! */
02214       return NULL;
02215    /* make a copy to store the parsed string */
02216    if (!(duplicate = ast_strdup(s)))
02217       return NULL;
02218 
02219    cur = duplicate;
02220    /* scan the original string copying into cur when needed */
02221    for (; *s ; s++) {
02222       if (x >= max - 1) {
02223          ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s);
02224          break;
02225       }
02226       if (*s == '"' && !escaped) {
02227          quoted = !quoted;
02228          if (quoted && whitespace) {
02229             /* start a quoted string from previous whitespace: new argument */
02230             argv[x++] = cur;
02231             whitespace = 0;
02232          }
02233       } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) {
02234          /* If we are not already in whitespace, and not in a quoted string or
02235             processing an escape sequence, and just entered whitespace, then
02236             finalize the previous argument and remember that we are in whitespace
02237          */
02238          if (!whitespace) {
02239             *cur++ = '\0';
02240             whitespace = 1;
02241          }
02242       } else if (*s == '\\' && !escaped) {
02243          escaped = 1;
02244       } else {
02245          if (whitespace) {
02246             /* we leave whitespace, and are not quoted. So it's a new argument */
02247             argv[x++] = cur;
02248             whitespace = 0;
02249          }
02250          *cur++ = *s;
02251          escaped = 0;
02252       }
02253    }
02254    /* Null terminate */
02255    *cur++ = '\0';
02256    /* XXX put a NULL in the last argument, because some functions that take
02257     * the array may want a null-terminated array.
02258     * argc still reflects the number of non-NULL entries.
02259     */
02260    argv[x] = NULL;
02261    *argc = x;
02262    *trailingwhitespace = whitespace;
02263    return duplicate;
02264 }

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

Definition at line 657 of file cli.c.

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

Referenced by handle_showcalls(), and handle_showuptime().

00658 {
00659    int x; /* the main part - years, weeks, etc. */
00660    struct ast_str *out;
00661 
00662 #define SECOND (1)
00663 #define MINUTE (SECOND*60)
00664 #define HOUR (MINUTE*60)
00665 #define DAY (HOUR*24)
00666 #define WEEK (DAY*7)
00667 #define YEAR (DAY*365)
00668 #define NEEDCOMMA(x) ((x)? ",": "") /* define if we need a comma */
00669    if (timeval.tv_sec < 0) /* invalid, nothing to show */
00670       return;
00671 
00672    if (printsec)  {  /* plain seconds output */
00673       ast_cli(fd, "%s: %lu\n", prefix, (u_long)timeval.tv_sec);
00674       return;
00675    }
00676    out = ast_str_alloca(256);
00677    if (timeval.tv_sec > YEAR) {
00678       x = (timeval.tv_sec / YEAR);
00679       timeval.tv_sec -= (x * YEAR);
00680       ast_str_append(&out, 0, "%d year%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00681    }
00682    if (timeval.tv_sec > WEEK) {
00683       x = (timeval.tv_sec / WEEK);
00684       timeval.tv_sec -= (x * WEEK);
00685       ast_str_append(&out, 0, "%d week%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00686    }
00687    if (timeval.tv_sec > DAY) {
00688       x = (timeval.tv_sec / DAY);
00689       timeval.tv_sec -= (x * DAY);
00690       ast_str_append(&out, 0, "%d day%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00691    }
00692    if (timeval.tv_sec > HOUR) {
00693       x = (timeval.tv_sec / HOUR);
00694       timeval.tv_sec -= (x * HOUR);
00695       ast_str_append(&out, 0, "%d hour%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00696    }
00697    if (timeval.tv_sec > MINUTE) {
00698       x = (timeval.tv_sec / MINUTE);
00699       timeval.tv_sec -= (x * MINUTE);
00700       ast_str_append(&out, 0, "%d minute%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
00701    }
00702    x = timeval.tv_sec;
00703    if (x > 0 || ast_str_strlen(out) == 0) /* if there is nothing, print 0 seconds */
00704       ast_str_append(&out, 0, "%d second%s ", x, ESS(x));
00705    ast_cli(fd, "%s: %s\n", prefix, ast_str_buffer(out));
00706 }

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

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

Referenced by __ast_cli_register().

01696 {
01697    int i;
01698    char buf[80];
01699 
01700    ast_join(buf, sizeof(buf), e->cmda);
01701    e->_full_cmd = ast_strdup(buf);
01702    if (!e->_full_cmd) {
01703       ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf);
01704       return -1;
01705    }
01706    e->cmdlen = strcspn(e->_full_cmd, cli_rsvd);
01707    for (i = 0; e->cmda[i]; i++)
01708       ;
01709    e->args = i;
01710    return 0;
01711 }

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

References ast_strlen_zero(), and strcasestr().

Referenced by __ast_cli_generator(), and find_cli().

01870 {
01871    int l;
01872    char *pos;
01873 
01874    if (ast_strlen_zero(cmd) || ast_strlen_zero(cli_word))
01875       return -1;
01876    if (!strchr(cli_rsvd, cli_word[0])) /* normal match */
01877       return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1;
01878    /* regexp match, takes [foo|bar] or {foo|bar} */
01879    l = strlen(cmd);
01880    /* wildcard match - will extend in the future */
01881    if (l > 0 && cli_word[0] == '%') {
01882       return 1;   /* wildcard */
01883    }
01884    pos = strcasestr(cli_word, cmd);
01885    if (pos == NULL) /* not found, say ok if optional */
01886       return cli_word[0] == '[' ? 0 : -1;
01887    if (pos == cli_word) /* no valid match at the beginning */
01888       return -1;
01889    if (strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l]))
01890       return 1;   /* valid match */
01891    return -1;  /* not found */
01892 }


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

struct ast_cli_entry cli_cli[] [static]

Definition at line 1639 of file cli.c.

Referenced by ast_builtins_init().

int cli_default_perm = 1 [static]

Default permissions value 1=Permit 0=Deny.

Definition at line 72 of file cli.c.

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

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

Definition at line 1689 of file cli.c.

int climodentryfd = -1 [static]

Definition at line 645 of file cli.c.

ast_mutex_t climodentrylock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static]

Definition at line 644 of file cli.c.

Referenced by handle_modlist().

struct module_level_list debug_modules [static]

list of module names and their debug levels

Definition at line 92 of file cli.c.

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

CLI permissions config file.

Definition at line 70 of file cli.c.

Referenced by ast_cli_perms_init().

ast_mutex_t permsconfiglock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static]

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

Definition at line 76 of file cli.c.

struct module_level_list verbose_modules [static]

list of module names and their verbose levels

Definition at line 94 of file cli.c.


Generated on Wed Apr 6 11:30:02 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7