Fri Apr 15 20:39:39 2016

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 <readline.h>
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/lock.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
Include dependency graph for cli.c:

Go to the source code of this file.

Data Structures

struct  channel_set_debug_args
struct  cli_perm
 List of restrictions per user. More...
struct  cli_perm_head
struct  cli_perms
 List of users and permissions. More...
struct  helpers
struct  module_level
 map a debug or verbose level to a module name More...
struct  module_level_list
struct  usergroup_cli_perm
 list of users to apply restrictions. More...

Defines

#define AST_CLI_INITLEN   256
 Initial buffer size for resulting strings in ast_cli().
#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
#define DAY   (HOUR*24)
#define FORMAT_STRING   "%-25s %-20s %-20s\n"
#define FORMAT_STRING   "%-20.20s %-20.20s %-7.7s %-30.30s\n"
#define FORMAT_STRING2   "%-20.20s %-20.20s %-7.7s %-30.30s\n"
#define HOUR   (MINUTE*60)
#define MINUTE   (SECOND*60)
#define MODLIST_FORMAT   "%-30s %-40.40s %-10d\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 104 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 646 of file cli.c.

Referenced by modlist_modentry().

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

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

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

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

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

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

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

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

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

static void __init_ast_cli_buf ( void   )  [static]

Definition at line 101 of file cli.c.

00107 {

void ast_builtins_init ( void   ) 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

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

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

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

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

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

References ast_cli_command_full().

Referenced by netconsole().

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

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

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

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

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

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

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

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

Return the number of unique matches for the generator.

Definition at line 2340 of file cli.c.

References ast_cli_generator(), and ast_free.

Referenced by handle_commandnummatches().

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

int ast_cli_perms_init ( int  reload  ) 

Provided by cli.c

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

static int cli_is_registered ( struct ast_cli_entry e  )  [static]

Definition at line 2049 of file cli.c.

References cli_next().

Referenced by __ast_cli_register().

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

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

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

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

static void cli_shutdown ( void   )  [static]

Definition at line 1875 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 228 of file cli.c.

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

Referenced by handle_load().

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

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

Definition at line 350 of file cli.c.

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

Referenced by handle_verbose().

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

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

Definition at line 2357 of file cli.c.

References ast_free.

Referenced by ast_cli_completion_matches().

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

static void destroy_user_perms ( void   )  [static]

cleanup (free) cli_perms linkedlist.

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

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

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

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

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

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

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

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

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

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

Referenced by handle_verbose().

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Referenced by __ast_cli_generator().

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

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

Definition at line 652 of file cli.c.

References ast_cli(), and MODLIST_FORMAT.

Referenced by handle_modlist().

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

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

returns true if there are more words to match

Definition at line 2430 of file cli.c.

Referenced by __ast_cli_generator().

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

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

Definition at line 2267 of file cli.c.

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

Referenced by __ast_cli_generator(), and ast_cli_command_full().

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

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

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

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

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

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

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

References ast_strlen_zero().

Referenced by __ast_cli_generator(), and find_cli().

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


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

struct ast_cli_entry cli_cli[] [static]

Definition at line 1662 of file cli.c.

int cli_default_perm = 1 [static]

Default permissions value 1=Permit 0=Deny.

Definition at line 77 of file cli.c.

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

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

Definition at line 1712 of file cli.c.

int climodentryfd = -1 [static]

Definition at line 650 of file cli.c.

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

Definition at line 649 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 97 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 75 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 81 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 99 of file cli.c.

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


Generated on 15 Apr 2016 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1