Wed Aug 7 17:16:02 2019

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 int cli_is_registered (struct ast_cli_entry *e)
static struct ast_cli_entrycli_next (struct ast_cli_entry *e)
static void cli_shutdown (void)
static char * complete_fn (const char *word, int state)
static char * complete_number (const char *partial, unsigned int min, unsigned int max, int n)
static void destroy_match_list (char **match_list, int matches)
static void destroy_user_perms (void)
 cleanup (free) cli_perms linkedlist.
static char * find_best (const char *argv[])
static struct ast_cli_entryfind_cli (const char *const cmds[], int match_type)
static struct module_levelfind_module_level (const char *module, 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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static struct module_level_list debug_modules = AST_RWLIST_HEAD_INIT_VALUE
static const char perms_config [] = "cli_permissions.conf"
 CLI permissions config file.
static ast_mutex_t permsconfiglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 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 = AST_RWLIST_HEAD_INIT_VALUE

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 103 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"
#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 645 of file cli.c.

Referenced by modlist_modentry().

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

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

02443 {
02444    const char *argv[AST_MAX_ARGS];
02445    struct ast_cli_entry *e = NULL;
02446    int x = 0, argindex, matchlen;
02447    int matchnum=0;
02448    char *ret = NULL;
02449    char matchstr[80] = "";
02450    int tws = 0;
02451    /* Split the argument into an array of words */
02452    char *duplicate = parse_args(text, &x, argv, ARRAY_LEN(argv), &tws);
02453 
02454    if (!duplicate)   /* malloc error */
02455       return NULL;
02456 
02457    /* Compute the index of the last argument (could be an empty string) */
02458    argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x;
02459 
02460    /* rebuild the command, ignore terminating white space and flatten space */
02461    ast_join(matchstr, sizeof(matchstr)-1, argv);
02462    matchlen = strlen(matchstr);
02463    if (tws) {
02464       strcat(matchstr, " "); /* XXX */
02465       if (matchlen)
02466          matchlen++;
02467    }
02468    if (lock)
02469       AST_RWLIST_RDLOCK(&helpers);
02470    while ( (e = cli_next(e)) ) {
02471       /* XXX repeated code */
02472       int src = 0, dst = 0, n = 0;
02473 
02474       if (e->command[0] == '_')
02475          continue;
02476 
02477       /*
02478        * Try to match words, up to and excluding the last word, which
02479        * is either a blank or something that we want to extend.
02480        */
02481       for (;src < argindex; dst++, src += n) {
02482          n = word_match(argv[src], e->cmda[dst]);
02483          if (n < 0)
02484             break;
02485       }
02486 
02487       if (src != argindex && more_words(e->cmda + dst))  /* not a match */
02488          continue;
02489       ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n);
02490       matchnum += n; /* this many matches here */
02491       if (ret) {
02492          /*
02493           * argv[src] is a valid prefix of the next word in this
02494           * command. If this is also the correct entry, return it.
02495           */
02496          if (matchnum > state)
02497             break;
02498          ast_free(ret);
02499          ret = NULL;
02500       } else if (ast_strlen_zero(e->cmda[dst])) {
02501          /*
02502           * This entry is a prefix of the command string entered
02503           * (only one entry in the list should have this property).
02504           * Run the generator if one is available. In any case we are done.
02505           */
02506          if (e->handler) { /* new style command */
02507             struct ast_cli_args a = {
02508                .line = matchstr, .word = word,
02509                .pos = argindex,
02510                .n = state - matchnum,
02511                .argv = argv,
02512                .argc = x};
02513             ret = e->handler(e, CLI_GENERATE, &a);
02514          }
02515          if (ret)
02516             break;
02517       }
02518    }
02519    if (lock)
02520       AST_RWLIST_UNLOCK(&helpers);
02521    ast_free(duplicate);
02522    return ret;
02523 }

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

Definition at line 2082 of file cli.c.

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

Referenced by ast_cli_register().

02083 {
02084    struct ast_cli_entry *cur;
02085    int i, lf, ret = -1;
02086 
02087    struct ast_cli_args a;  /* fake argument */
02088    char **dst = (char **)e->cmda;   /* need to cast as the entry is readonly */
02089    char *s;
02090 
02091    AST_RWLIST_WRLOCK(&helpers);
02092 
02093    if (cli_is_registered(e)) {
02094       ast_log(LOG_WARNING, "Command '%s' already registered (the same ast_cli_entry)\n",
02095          S_OR(e->_full_cmd, e->command));
02096       ret = 0;  /* report success */
02097       goto done;
02098    }
02099 
02100    memset(&a, '\0', sizeof(a));
02101    e->handler(e, CLI_INIT, &a);
02102    /* XXX check that usage and command are filled up */
02103    s = ast_skip_blanks(e->command);
02104    s = e->command = ast_strdup(s);
02105    for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) {
02106       *dst++ = s; /* store string */
02107       s = ast_skip_nonblanks(s);
02108       if (*s == '\0')   /* we are done */
02109          break;
02110       *s++ = '\0';
02111       s = ast_skip_blanks(s);
02112    }
02113    *dst++ = NULL;
02114 
02115    if (find_cli(e->cmda, 1)) {
02116       ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n",
02117          S_OR(e->_full_cmd, e->command));
02118       goto done;
02119    }
02120    if (set_full_cmd(e)) {
02121       ast_log(LOG_WARNING, "Error registering CLI Command '%s'\n",
02122          S_OR(e->_full_cmd, e->command));
02123       goto done;
02124    }
02125 
02126    lf = e->cmdlen;
02127    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
02128       int len = cur->cmdlen;
02129       if (lf < len)
02130          len = lf;
02131       if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) {
02132          AST_RWLIST_INSERT_BEFORE_CURRENT(e, list); 
02133          break;
02134       }
02135    }
02136    AST_RWLIST_TRAVERSE_SAFE_END;
02137 
02138    if (!cur)
02139       AST_RWLIST_INSERT_TAIL(&helpers, e, list); 
02140    ret = 0; /* success */
02141 
02142 done:
02143    AST_RWLIST_UNLOCK(&helpers);
02144    if (ret) {
02145       ast_free(e->command);
02146       e->command = NULL;
02147    }
02148 
02149    return ret;
02150 }

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

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

Referenced by ast_cli_unregister().

02061 {
02062    if (e->inuse) {
02063       ast_log(LOG_WARNING, "Can't remove command that is in use\n");
02064    } else {
02065       AST_RWLIST_WRLOCK(&helpers);
02066       AST_RWLIST_REMOVE(&helpers, e, list);
02067       AST_RWLIST_UNLOCK(&helpers);
02068       ast_free(e->_full_cmd);
02069       e->_full_cmd = NULL;
02070       if (e->handler) {
02071          /* this is a new-style entry. Reset fields and free memory. */
02072          char *cmda = (char *) e->cmda;
02073          memset(cmda, '\0', sizeof(e->cmda));
02074          ast_free(e->command);
02075          e->command = NULL;
02076          e->usage = NULL;
02077       }
02078    }
02079    return 0;
02080 }

static void __init_ast_cli_buf ( void   )  [static]

Definition at line 100 of file cli.c.

00106 {

void ast_builtins_init ( void   ) 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 1880 of file cli.c.

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

Referenced by main().

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

Definition at line 105 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(), _sip_show_peers_one(), _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(), 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_odbc_read(), cli_odbc_write(), 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(), db_show_cb(), db_showkey_cb(), 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_add_cmd(), 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_memory_atexit_list(), handle_memory_atexit_summary(), handle_memory_show_allocations(), handle_memory_show_summary(), handle_mgcp_audit_endpoint(), handle_mgcp_set_debug(), handle_mgcp_show_endpoints(), handle_minivm_list_templates(), handle_minivm_reload(), handle_minivm_show_settings(), handle_minivm_show_stats(), handle_minivm_show_users(), handle_minivm_show_zones(), handle_modlist(), handle_parkedcalls(), 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_application(), 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_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_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_docs(), print_bc_info(), print_cel_sub(), print_codec_to_cli(), print_group(), print_stats_cb(), print_uptimestr(), realtime_ldap_status(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_chanstats_cb(), show_codec_n(), show_codecs(), show_config_description(), show_debug_helper(), show_dialplan_helper(), show_license(), show_users_realtime(), show_warranty(), sip_cli_notify(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_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(), unistim_do_debug(), unistim_info(), and unistim_sp().

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

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

02531 {
02532    const char *args[AST_MAX_ARGS + 1];
02533    struct ast_cli_entry *e;
02534    int x;
02535    char *duplicate = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL);
02536    char tmp[AST_MAX_ARGS + 1];
02537    char *retval = NULL;
02538    struct ast_cli_args a = {
02539       .fd = fd, .argc = x, .argv = args+1 };
02540 
02541    if (duplicate == NULL)
02542       return -1;
02543 
02544    if (x < 1)  /* We need at least one entry, otherwise ignore */
02545       goto done;
02546 
02547    AST_RWLIST_RDLOCK(&helpers);
02548    e = find_cli(args + 1, 0);
02549    if (e)
02550       ast_atomic_fetchadd_int(&e->inuse, 1);
02551    AST_RWLIST_UNLOCK(&helpers);
02552    if (e == NULL) {
02553       ast_cli(fd, "No such command '%s' (type 'core show help %s' for other possible commands)\n", s, find_best(args + 1));
02554       goto done;
02555    }
02556 
02557    ast_join(tmp, sizeof(tmp), args + 1);
02558    /* Check if the user has rights to run this command. */
02559    if (!cli_has_permissions(uid, gid, tmp)) {
02560       ast_cli(fd, "You don't have permissions to run '%s' command\n", tmp);
02561       ast_free(duplicate);
02562       return 0;
02563    }
02564 
02565    /*
02566     * Within the handler, argv[-1] contains a pointer to the ast_cli_entry.
02567     * Remember that the array returned by parse_args is NULL-terminated.
02568     */
02569    args[0] = (char *)e;
02570 
02571    retval = e->handler(e, CLI_HANDLER, &a);
02572 
02573    if (retval == CLI_SHOWUSAGE) {
02574       ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
02575    } else {
02576       if (retval == CLI_FAILURE)
02577          ast_cli(fd, "Command '%s' failed.\n", s);
02578    }
02579    ast_atomic_fetchadd_int(&e->inuse, -1);
02580 done:
02581    ast_free(duplicate);
02582    return 0;
02583 }

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

References ast_cli_command_full().

Referenced by netconsole().

02586 {
02587    char cmd[512];
02588    int x, y = 0, count = 0;
02589 
02590    for (x = 0; x < size; x++) {
02591       cmd[y] = s[x];
02592       y++;
02593       if (s[x] == '\0') {
02594          ast_cli_command_full(uid, gid, fd, cmd);
02595          y = 0;
02596          count++;
02597       }
02598    }
02599    return count;
02600 }

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

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

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

01536 {
01537    int i, which = 0, len;
01538    len = ast_strlen_zero(word) ? 0 : strlen(word);
01539 
01540    for (i = 0; choices[i]; i++) {
01541       if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state)
01542          return ast_strdup(choices[i]);
01543    }
01544    return NULL;
01545 }

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

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

Referenced by cli_complete(), and handle_commandmatchesarray().

02369 {
02370    char **match_list = NULL, *retstr, *prevstr;
02371    char **new_list;
02372    size_t match_list_len, max_equal, which, i;
02373    int matches = 0;
02374 
02375    /* leave entry 0 free for the longest common substring */
02376    match_list_len = 1;
02377    while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
02378       if (matches + 1 >= match_list_len) {
02379          match_list_len <<= 1;
02380          new_list = ast_realloc(match_list, match_list_len * sizeof(*match_list));
02381          if (!new_list) {
02382             destroy_match_list(match_list, matches);
02383             return NULL;
02384          }
02385          match_list = new_list;
02386       }
02387       match_list[++matches] = retstr;
02388    }
02389 
02390    if (!match_list) {
02391       return match_list; /* NULL */
02392    }
02393 
02394    /* Find the longest substring that is common to all results
02395     * (it is a candidate for completion), and store a copy in entry 0.
02396     */
02397    prevstr = match_list[1];
02398    max_equal = strlen(prevstr);
02399    for (which = 2; which <= matches; which++) {
02400       for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
02401          continue;
02402       max_equal = i;
02403    }
02404 
02405    retstr = ast_malloc(max_equal + 1);
02406    if (!retstr) {
02407       destroy_match_list(match_list, matches);
02408       return NULL;
02409    }
02410    ast_copy_string(retstr, match_list[1], max_equal + 1);
02411    match_list[0] = retstr;
02412 
02413    /* ensure that the array is NULL terminated */
02414    if (matches + 1 >= match_list_len) {
02415       new_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list));
02416       if (!new_list) {
02417          ast_free(retstr);
02418          destroy_match_list(match_list, matches);
02419          return NULL;
02420       }
02421       match_list = new_list;
02422    }
02423    match_list[matches + 1] = NULL;
02424 
02425    return match_list;
02426 }

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

02526 {
02527    return __ast_cli_generator(text, word, state, 1);
02528 }

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

Return the number of unique matches for the generator.

Definition at line 2339 of file cli.c.

References ast_cli_generator(), and ast_free.

Referenced by handle_commandnummatches().

02340 {
02341    int matches = 0, i = 0;
02342    char *buf = NULL, *oldbuf = NULL;
02343 
02344    while ((buf = ast_cli_generator(text, word, i++))) {
02345       if (!oldbuf || strcmp(buf,oldbuf))
02346          matches++;
02347       if (oldbuf)
02348          ast_free(oldbuf);
02349       oldbuf = buf;
02350    }
02351    if (oldbuf)
02352       ast_free(oldbuf);
02353    return matches;
02354 }

int ast_cli_perms_init ( int  reload  ) 

Provided by cli.c

Definition at line 1752 of file cli.c.

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

Referenced by handle_cli_reload_permissions(), and main().

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

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 2159 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(), load_config(), and load_module().

02160 {
02161    return __ast_cli_register(e, NULL);
02162 }

int ast_cli_register_multiple ( struct ast_cli_entry e,
int  len 
)
int ast_cli_unregister ( struct ast_cli_entry e  ) 

Unregisters a command or an array of commands.

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

Definition at line 2153 of file cli.c.

References __ast_cli_unregister().

Referenced by alias_unregister_cb(), ast_cel_engine_term(), ast_cli_unregister_multiple(), cdr_engine_shutdown(), dnsmgr_shutdown(), do_reload(), load_module(), and unload_module().

02154 {
02155    return __ast_cli_unregister(e, NULL);
02156 }

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

References ast_cli_unregister().

Referenced by __unload_module(), aoc_shutdown(), ast_ais_clm_unload_module(), astdb_shutdown(), astobj2_cleanup(), cc_shutdown(), channels_shutdown(), cli_shutdown(), close_logger(), config_shutdown(), data_shutdown(), event_shutdown(), features_shutdown(), file_shutdown(), framer_shutdown(), http_shutdown(), iax_provision_unload(), image_shutdown(), indications_shutdown(), load_module(), main_atexit(), manager_shutdown(), mm_atexit_ast(), stun_shutdown(), timing_shutdown(), tps_shutdown(), udptl_shutdown(), unload_module(), and unload_pbx().

02178 {
02179    int i, res = 0;
02180 
02181    for (i = 0; i < len; i++)
02182       res |= ast_cli_unregister(e + i);
02183 
02184    return res;
02185 }

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

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

01548 {
01549    struct ast_channel *c = NULL;
01550    int which = 0;
01551    char notfound = '\0';
01552    char *ret = &notfound; /* so NULL can break the loop */
01553    struct ast_channel_iterator *iter;
01554 
01555    if (pos != rpos) {
01556       return NULL;
01557    }
01558 
01559    if (ast_strlen_zero(word)) {
01560       iter = ast_channel_iterator_all_new();
01561    } else {
01562       iter = ast_channel_iterator_by_name_new(word, strlen(word));
01563    }
01564 
01565    if (!iter) {
01566       return NULL;
01567    }
01568 
01569    while (ret == &notfound && (c = ast_channel_iterator_next(iter))) {
01570       if (++which > state) {
01571          ast_channel_lock(c);
01572          ret = ast_strdup(c->name);
01573          ast_channel_unlock(c);
01574       }
01575       ast_channel_unref(c);
01576    }
01577 
01578    ast_channel_iterator_destroy(iter);
01579 
01580    return ret == &notfound ? NULL : ret;
01581 }

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

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

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

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

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

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

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

Definition at line 1280 of file cli.c.

References args, ast_channel_lock, ast_channel_unlock, ast_cli(), DEBUGCHAN_FLAG, channel_set_debug_args::fd, ast_channel::fin, ast_channel::fout, and channel_set_debug_args::is_off.

Referenced by handle_core_set_debug_channel().

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

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

Definition at line 170 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::permit, usergroup_cli_perm::perms, and usergroup_cli_perm::uid.

Referenced by ast_cli_command_full(), and handle_cli_check_permissions().

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

static int cli_is_registered ( struct ast_cli_entry e  )  [static]

Definition at line 2048 of file cli.c.

References cli_next().

Referenced by __ast_cli_register().

02049 {
02050    struct ast_cli_entry *cur = NULL;
02051 
02052    while ((cur = cli_next(cur))) {
02053       if (cur == e) {
02054          return 1;
02055       }
02056    }
02057    return 0;
02058 }

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

Definition at line 712 of file cli.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

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

00713 {
00714    if (e) {
00715       return AST_LIST_NEXT(e, list);
00716    } else {
00717       return AST_LIST_FIRST(&helpers);
00718    }
00719 }

static void cli_shutdown ( void   )  [static]

Definition at line 1874 of file cli.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by ast_builtins_init().

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

Definition at line 227 of file cli.c.

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

Referenced by handle_load().

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

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

Definition at line 349 of file cli.c.

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

Referenced by handle_verbose().

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

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

Definition at line 2356 of file cli.c.

References ast_free.

Referenced by ast_cli_completion_matches().

02357 {
02358    if (match_list) {
02359       int idx;
02360 
02361       for (idx = 1; idx < matches; ++idx) {
02362          ast_free(match_list[idx]);
02363       }
02364       ast_free(match_list);
02365    }
02366 }

static void destroy_user_perms ( void   )  [static]

cleanup (free) cli_perms linkedlist.

Definition at line 1736 of file cli.c.

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

Referenced by ast_cli_perms_init().

01737 {
01738    struct cli_perm *perm;
01739    struct usergroup_cli_perm *user_perm;
01740 
01741    AST_RWLIST_WRLOCK(&cli_perms);
01742    while ((user_perm = AST_LIST_REMOVE_HEAD(&cli_perms, list))) {
01743       while ((perm = AST_LIST_REMOVE_HEAD(user_perm->perms, list))) {
01744          ast_free(perm->command);
01745          ast_free(perm);
01746       }
01747       ast_free(user_perm);
01748    }
01749    AST_RWLIST_UNLOCK(&cli_perms);
01750 }

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

Definition at line 2030 of file cli.c.

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

Referenced by ast_cli_command_full().

02031 {
02032    static char cmdline[80];
02033    int x;
02034    /* See how close we get, then print the candidate */
02035    const char *myargv[AST_MAX_CMD_LEN] = { NULL, };
02036 
02037    AST_RWLIST_RDLOCK(&helpers);
02038    for (x = 0; argv[x]; x++) {
02039       myargv[x] = argv[x];
02040       if (!find_cli(myargv, -1))
02041          break;
02042    }
02043    AST_RWLIST_UNLOCK(&helpers);
02044    ast_join(cmdline, sizeof(cmdline), myargv);
02045    return cmdline;
02046 }

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

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

01987 {
01988    int matchlen = -1;   /* length of longest match so far */
01989    struct ast_cli_entry *cand = NULL, *e=NULL;
01990 
01991    while ( (e = cli_next(e)) ) {
01992       /* word-by word regexp comparison */
01993       const char * const *src = cmds;
01994       const char * const *dst = e->cmda;
01995       int n = 0;
01996       for (;; dst++, src += n) {
01997          n = word_match(*src, *dst);
01998          if (n < 0)
01999             break;
02000       }
02001       if (ast_strlen_zero(*dst) || ((*dst)[0] == '[' && ast_strlen_zero(dst[1]))) {
02002          /* no more words in 'e' */
02003          if (ast_strlen_zero(*src)) /* exact match, cannot do better */
02004             break;
02005          /* Here, cmds has more words than the entry 'e' */
02006          if (match_type != 0) /* but we look for almost exact match... */
02007             continue;   /* so we skip this one. */
02008          /* otherwise we like it (case 0) */
02009       } else { /* still words in 'e' */
02010          if (ast_strlen_zero(*src))
02011             continue; /* cmds is shorter than 'e', not good */
02012          /* Here we have leftover words in cmds and 'e',
02013           * but there is a mismatch. We only accept this one if match_type == -1
02014           * and this is the last word for both.
02015           */
02016          if (match_type != -1 || !ast_strlen_zero(src[1]) ||
02017              !ast_strlen_zero(dst[1])) /* not the one we look for */
02018             continue;
02019          /* good, we are in case match_type == -1 and mismatch on last word */
02020       }
02021       if (src - cmds > matchlen) {  /* remember the candidate */
02022          matchlen = src - cmds;
02023          cand = e;
02024       }
02025    }
02026 
02027    return e ? e : cand;
02028 }

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

Find the debug or verbose file setting.

  • debug 1 for debug, 0 for verbose

Definition at line 336 of file cli.c.

References AST_LIST_TRAVERSE, debug_modules, module_level::module, and verbose_modules.

Referenced by handle_verbose().

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

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

Definition at line 1583 of file cli.c.

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

01584 {
01585 #define FORMAT_STRING  "%-25s  %-20s  %-20s\n"
01586 
01587    struct ast_group_info *gi = NULL;
01588    int numchans = 0;
01589    regex_t regexbuf;
01590    int havepattern = 0;
01591 
01592    switch (cmd) {
01593    case CLI_INIT:
01594       e->command = "group show channels";
01595       e->usage = 
01596          "Usage: group show channels [pattern]\n"
01597          "       Lists all currently active channels with channel group(s) specified.\n"
01598          "       Optional regular expression pattern is matched to group names for each\n"
01599          "       channel.\n";
01600       return NULL;
01601    case CLI_GENERATE:
01602       return NULL;
01603    }
01604 
01605    if (a->argc < 3 || a->argc > 4)
01606       return CLI_SHOWUSAGE;
01607    
01608    if (a->argc == 4) {
01609       if (regcomp(&regexbuf, a->argv[3], REG_EXTENDED | REG_NOSUB))
01610          return CLI_SHOWUSAGE;
01611       havepattern = 1;
01612    }
01613 
01614    ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category");
01615 
01616    ast_app_group_list_rdlock();
01617    
01618    gi = ast_app_group_list_head();
01619    while (gi) {
01620       if (!havepattern || !regexec(&regexbuf, gi->group, 0, NULL, 0)) {
01621          ast_cli(a->fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category));
01622          numchans++;
01623       }
01624       gi = AST_LIST_NEXT(gi, group_list);
01625    }
01626    
01627    ast_app_group_list_unlock();
01628    
01629    if (havepattern)
01630       regfree(&regexbuf);
01631 
01632    ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
01633    return CLI_SUCCESS;
01634 #undef FORMAT_STRING
01635 }

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

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

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

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

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

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

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

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

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 1028 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::permit, usergroup_cli_perm::perms, usergroup_cli_perm::uid, and ast_cli_entry::usage.

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

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

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

01638 {
01639    switch (cmd) {
01640    case CLI_INIT:
01641       e->command = "core waitfullybooted";
01642       e->usage =
01643          "Usage: core waitfullybooted\n"
01644          "  Wait until Asterisk has fully booted.\n";
01645       return NULL;
01646    case CLI_GENERATE:
01647       return NULL;
01648    }
01649 
01650    while (!ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
01651       usleep(100);
01652    }
01653 
01654    ast_cli(a->fd, "Asterisk has fully booted.\n");
01655 
01656    return CLI_SUCCESS;
01657 }

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 1304 of file cli.c.

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

Referenced by handle_nodebugchan_deprecated().

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

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

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

02221 {
02222    char fullcmd[80];
02223    struct ast_cli_entry *my_e;
02224    char *res = CLI_SUCCESS;
02225 
02226    if (cmd == CLI_INIT) {
02227       e->command = "core show help";
02228       e->usage =
02229          "Usage: core show help [topic]\n"
02230          "       When called with a topic as an argument, displays usage\n"
02231          "       information on the given command. If called without a\n"
02232          "       topic, it provides a list of commands.\n";
02233       return NULL;
02234 
02235    } else if (cmd == CLI_GENERATE) {
02236       /* skip first 14 or 15 chars, "core show help " */
02237       int l = strlen(a->line);
02238 
02239       if (l > 15) {
02240          l = 15;
02241       }
02242       /* XXX watch out, should stop to the non-generator parts */
02243       return __ast_cli_generator(a->line + l, a->word, a->n, 0);
02244    }
02245    if (a->argc == e->args) {
02246       return help1(a->fd, NULL, 0);
02247    }
02248 
02249    AST_RWLIST_RDLOCK(&helpers);
02250    my_e = find_cli(a->argv + 3, 1); /* try exact match first */
02251    if (!my_e) {
02252       res = help1(a->fd, a->argv + 3, 1 /* locked */);
02253       AST_RWLIST_UNLOCK(&helpers);
02254       return res;
02255    }
02256    if (my_e->usage)
02257       ast_cli(a->fd, "%s", my_e->usage);
02258    else {
02259       ast_join(fullcmd, sizeof(fullcmd), a->argv + 3);
02260       ast_cli(a->fd, "No help text available for '%s'.\n", fullcmd);
02261    }
02262    AST_RWLIST_UNLOCK(&helpers);
02263    return res;
02264 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

< Buffer for variable, CDR variable, and trace output.

< Accumulation buffer for all output.

Definition at line 1388 of file cli.c.

References ast_channel::_bridge, ast_channel::_state, ast_channel::appl, ast_cli_args::argc, ast_cli_args::argv, ast_bridged_channel(), ast_cdr_serialize_variables(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), AST_FLAG_BLOCKING, ast_free, ast_getformatname_multiple(), ast_state2str(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_thread_get(), ast_test_flag, ast_translate_path_to_str(), ast_tvnow(), ast_channel::blockproc, ast_channel::caller, ast_channel::callgroup, ast_channel::cdr, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel::connected, ast_channel::context, ast_channel::data, DEBUGCHAN_FLAG, ast_channel::dialed, ast_channel::exten, ast_cli_args::fd, ast_channel::fds, ast_channel::fin, ast_channel::fout, ast_party_connected_line::id, ast_party_caller::id, ast_cli_args::line, ast_cli_args::n, name, ast_party_id::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, pbx_builtin_serialize_variables(), ast_channel::pickupgroup, ast_cli_args::pos, ast_channel::priority, 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_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.

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

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

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

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

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

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

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

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

Definition at line 596 of file cli.c.

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

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

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

Definition at line 389 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(), debug_modules, 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, ast_cli_entry::usage, and verbose_modules.

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

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

02192 {
02193    char matchstr[80] = "";
02194    struct ast_cli_entry *e = NULL;
02195    int len = 0;
02196    int found = 0;
02197 
02198    if (match) {
02199       ast_join(matchstr, sizeof(matchstr), match);
02200       len = strlen(matchstr);
02201    }
02202    if (!locked)
02203       AST_RWLIST_RDLOCK(&helpers);
02204    while ( (e = cli_next(e)) ) {
02205       /* Hide commands that start with '_' */
02206       if (e->_full_cmd[0] == '_')
02207          continue;
02208       if (match && strncasecmp(matchstr, e->_full_cmd, len))
02209          continue;
02210       ast_cli(fd, "%30.30s %s\n", e->_full_cmd, S_OR(e->summary, "<no description available>"));
02211       found++;
02212    }
02213    if (!locked)
02214       AST_RWLIST_UNLOCK(&helpers);
02215    if (!found && matchstr[0])
02216       ast_cli(fd, "No such command '%s'.\n", matchstr);
02217    return CLI_SUCCESS;
02218 }

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

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

Referenced by __ast_cli_generator().

01938 {
01939    int lw;
01940    char *s, *t1;
01941 
01942    *actual = 0;
01943    if (ast_strlen_zero(token))
01944       return NULL;
01945    if (ast_strlen_zero(word))
01946       word = "";  /* dummy */
01947    lw = strlen(word);
01948    if (strcspn(word, cli_rsvd) != lw)
01949       return NULL;   /* no match if word has reserved chars */
01950    if (strchr(cli_rsvd, token[0]) == NULL) { /* regular match */
01951       if (strncasecmp(token, word, lw))   /* no match */
01952          return NULL;
01953       *actual = 1;
01954       return (pos != 0) ? NULL : ast_strdup(token);
01955    }
01956    /* now handle regexp match */
01957 
01958    /* Wildcard always matches, so we never do is_prefix on them */
01959 
01960    t1 = ast_strdupa(token + 1);  /* copy, skipping first char */
01961    while (pos >= 0 && (s = strsep(&t1, cli_rsvd)) && *s) {
01962       if (*s == '%') /* wildcard */
01963          continue;
01964       if (strncasecmp(s, word, lw)) /* no match */
01965          continue;
01966       (*actual)++;
01967       if (pos-- == 0)
01968          return ast_strdup(s);
01969    }
01970    return NULL;
01971 }

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

Definition at line 651 of file cli.c.

References ast_cli(), and MODLIST_FORMAT.

Referenced by handle_modlist().

00652 {
00653    /* Comparing the like with the module */
00654    if (strcasestr(module, like) ) {
00655       ast_cli(climodentryfd, MODLIST_FORMAT, module, description, usecnt);
00656       return 1;
00657    } 
00658    return 0;
00659 }

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

returns true if there are more words to match

Definition at line 2429 of file cli.c.

Referenced by __ast_cli_generator().

02430 {
02431    int i;
02432    for (i = 0; dst[i]; i++) {
02433       if (dst[i][0] != '[')
02434          return -1;
02435    }
02436    return 0;
02437 }

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

Definition at line 2266 of file cli.c.

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

Referenced by __ast_cli_generator(), and ast_cli_command_full().

02267 {
02268    char *duplicate, *cur;
02269    int x = 0;
02270    int quoted = 0;
02271    int escaped = 0;
02272    int whitespace = 1;
02273    int dummy = 0;
02274 
02275    if (trailingwhitespace == NULL)
02276       trailingwhitespace = &dummy;
02277    *trailingwhitespace = 0;
02278    if (s == NULL) /* invalid, though! */
02279       return NULL;
02280    /* make a copy to store the parsed string */
02281    if (!(duplicate = ast_strdup(s)))
02282       return NULL;
02283 
02284    cur = duplicate;
02285 
02286    /* Remove leading spaces from the command */
02287    while (isspace(*s)) {
02288       cur++;
02289       s++;
02290    }
02291 
02292    /* scan the original string copying into cur when needed */
02293    for (; *s ; s++) {
02294       if (x >= max - 1) {
02295          ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s);
02296          break;
02297       }
02298       if (*s == '"' && !escaped) {
02299          quoted = !quoted;
02300          if (quoted && whitespace) {
02301             /* start a quoted string from previous whitespace: new argument */
02302             argv[x++] = cur;
02303             whitespace = 0;
02304          }
02305       } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) {
02306          /* If we are not already in whitespace, and not in a quoted string or
02307             processing an escape sequence, and just entered whitespace, then
02308             finalize the previous argument and remember that we are in whitespace
02309          */
02310          if (!whitespace) {
02311             *cur++ = '\0';
02312             whitespace = 1;
02313          }
02314       } else if (*s == '\\' && !escaped) {
02315          escaped = 1;
02316       } else {
02317          if (whitespace) {
02318             /* we leave whitespace, and are not quoted. So it's a new argument */
02319             argv[x++] = cur;
02320             whitespace = 0;
02321          }
02322          *cur++ = *s;
02323          escaped = 0;
02324       }
02325    }
02326    /* Null terminate */
02327    *cur++ = '\0';
02328    /* XXX put a NULL in the last argument, because some functions that take
02329     * the array may want a null-terminated array.
02330     * argc still reflects the number of non-NULL entries.
02331     */
02332    argv[x] = NULL;
02333    *argc = x;
02334    *trailingwhitespace = whitespace;
02335    return duplicate;
02336 }

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

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

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

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

01718 {
01719    int i;
01720    char buf[80];
01721 
01722    ast_join(buf, sizeof(buf), e->cmda);
01723    e->_full_cmd = ast_strdup(buf);
01724    if (!e->_full_cmd) {
01725       ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf);
01726       return -1;
01727    }
01728    e->cmdlen = strcspn(e->_full_cmd, cli_rsvd);
01729    for (i = 0; e->cmda[i]; i++)
01730       ;
01731    e->args = i;
01732    return 0;
01733 }

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

References ast_strlen_zero().

Referenced by __ast_cli_generator(), and find_cli().

01898 {
01899    int l;
01900    char *pos;
01901 
01902    if (ast_strlen_zero(cmd) || ast_strlen_zero(cli_word))
01903       return -1;
01904    if (!strchr(cli_rsvd, cli_word[0])) /* normal match */
01905       return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1;
01906    l = strlen(cmd);
01907    /* wildcard match - will extend in the future */
01908    if (l > 0 && cli_word[0] == '%') {
01909       return 1;   /* wildcard */
01910    }
01911 
01912    /* Start a search for the command entered against the cli word in question */
01913    pos = strcasestr(cli_word, cmd);
01914    while (pos) {
01915 
01916       /*
01917        *Check if the word matched with is surrounded by reserved characters on both sides
01918        * and isn't at the beginning of the cli_word since that would make it check in a location we shouldn't know about.
01919        * If it is surrounded by reserved chars and isn't at the beginning, it's a match.
01920        */
01921       if (pos != cli_word && strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) {
01922          return 1;   /* valid match */
01923       }
01924 
01925       /* Ok, that one didn't match, strcasestr to the next appearance of the command and start over.*/
01926       pos = strcasestr(pos + 1, cmd);
01927    }
01928    /* If no matches were found over the course of the while loop, we hit the end of the string. It's a mismatch. */
01929    return -1;
01930 }


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

struct ast_cli_entry cli_cli[] [static]

Definition at line 1661 of file cli.c.

int cli_default_perm = 1 [static]

Default permissions value 1=Permit 0=Deny.

Definition at line 76 of file cli.c.

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

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

Definition at line 1711 of file cli.c.

int climodentryfd = -1 [static]

Definition at line 649 of file cli.c.

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

Definition at line 648 of file cli.c.

Referenced by handle_modlist().

struct module_level_list debug_modules = AST_RWLIST_HEAD_INIT_VALUE [static]

list of module names and their debug levels

Definition at line 96 of file cli.c.

Referenced by ast_debug_get_by_module(), find_module_level(), and handle_verbose().

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

CLI permissions config file.

Definition at line 74 of file cli.c.

Referenced by ast_cli_perms_init().

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

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

Definition at line 80 of file cli.c.

struct module_level_list verbose_modules = AST_RWLIST_HEAD_INIT_VALUE [static]

list of module names and their verbose levels

Definition at line 98 of file cli.c.

Referenced by ast_verbose_get_by_module(), find_module_level(), and handle_verbose().


Generated on 7 Aug 2019 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1