Mon Mar 19 11:30:46 2012

Asterisk developer's documentation


cli.c File Reference

Standard Command Line Interface. More...

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

Go to the source code of this file.

Data Structures

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

Defines

#define AST_CLI_INITLEN   256
 Initial buffer size for resulting strings in ast_cli().
#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
#define DAY   (HOUR*24)
#define FORMAT_STRING   "%-25s %-20s %-20s\n"
#define FORMAT_STRING   "%-20.20s %-20.20s %-7.7s %-30.30s\n"
#define FORMAT_STRING2   "%-20.20s %-20.20s %-7.7s %-30.30s\n"
#define HOUR   (MINUTE*60)
#define MINUTE   (SECOND*60)
#define MODLIST_FORMAT   "%-30s %-40.40s %-10d\n"
#define MODLIST_FORMAT2   "%-30s %-40.40s %-10s\n"
#define NEEDCOMMA(x)   ((x)? ",": "")
#define SECOND   (1)
#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
#define VERBOSE_FORMAT_STRING2   "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
#define WEEK   (DAY*7)
#define YEAR   (DAY*365)

Functions

static char * __ast_cli_generator (const char *text, const char *word, int state, int lock)
static int __ast_cli_register (struct ast_cli_entry *e, struct ast_cli_entry *ed)
static int __ast_cli_unregister (struct ast_cli_entry *e, struct ast_cli_entry *ed)
static void __init_ast_cli_buf (void)
void ast_builtins_init (void)
 initialize the _full_cmd string in * each of the builtins.
void ast_cli (int fd, const char *fmt,...)
int ast_cli_command_full (int uid, int gid, int fd, const char *s)
 Interprets a command Interpret a command s, sending output to fd if uid:gid has permissions to run this command. uid = CLI_NO_PERMS to avoid checking user permissions gid = CLI_NO_PERMS to avoid checking group permissions.
int ast_cli_command_multiple_full (int uid, int gid, int fd, size_t size, const char *s)
 Executes multiple CLI commands Interpret strings separated by NULL and execute each one, sending output to fd if uid has permissions, uid = CLI_NO_PERMS to avoid checking users permissions. gid = CLI_NO_PERMS to avoid checking group permissions.
char * ast_cli_complete (const char *word, const char *const choices[], int state)
char ** ast_cli_completion_matches (const char *text, const char *word)
 Generates a NULL-terminated array of strings that 1) begin with the string in the second parameter, and 2) are valid in a command after the string in the first parameter.
char * ast_cli_generator (const char *text, const char *word, int state)
 Readline madness Useful for readline, that's about it.
int ast_cli_generatornummatches (const char *text, const char *word)
 Return the number of unique matches for the generator.
int ast_cli_perms_init (int reload)
int ast_cli_register (struct ast_cli_entry *e)
 Registers a command or an array of commands.
int ast_cli_register_multiple (struct ast_cli_entry *e, int len)
 Register multiple commands.
int ast_cli_unregister (struct ast_cli_entry *e)
 Unregisters a command or an array of commands.
int ast_cli_unregister_multiple (struct ast_cli_entry *e, int len)
 Unregister multiple commands.
char * ast_complete_channels (const char *line, const char *word, int pos, int state, int rpos)
 Command completion for the list of active channels.
unsigned int ast_debug_get_by_module (const char *module)
 Get the debug level for a module.
unsigned int ast_verbose_get_by_module (const char *module)
 Get the verbose level for a module.
static int channel_set_debug (void *obj, void *arg, void *data, int flags)
static int cli_has_permissions (int uid, int gid, const char *command)
static struct ast_cli_entrycli_next (struct ast_cli_entry *e)
static char * complete_fn (const char *word, int state)
static char * complete_number (const char *partial, unsigned int min, unsigned int max, int n)
static void destroy_user_perms (void)
 cleanup (free) cli_perms linkedlist.
static char * find_best (const char *argv[])
static struct ast_cli_entryfind_cli (const char *const cmds[], int match_type)
static struct module_levelfind_module_level (const char *module, unsigned int debug)
 Find the debug or verbose file setting.
static char * group_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_chanlist (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_check_permissions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handles CLI command 'cli check permissions'
static char * handle_cli_reload_permissions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handles CLI command 'cli reload permissions'
static char * handle_cli_show_permissions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handles CLI command 'cli show permissions'
static char * handle_cli_wait_fullybooted (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_commandcomplete (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_commandmatchesarray (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_commandnummatches (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_core_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_core_set_debug_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_help (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_load (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_logger_mute (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_modlist (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_nodebugchan_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showcalls (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showchan (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showuptime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_softhangup (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_unload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_verbose (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * help1 (int fd, const char *const match[], int locked)
 helper for final part of handle_help if locked = 1, assume the list is already locked
static char * is_prefix (const char *word, const char *token, int pos, int *actual)
 if word is a valid prefix for token, returns the pos-th match as a malloced string, or NULL otherwise. Always tell in *actual how many matches we got.
static int modlist_modentry (const char *module, const char *description, int usecnt, const char *like)
static int more_words (const char *const *dst)
 returns true if there are more words to match
static char * parse_args (const char *s, int *argc, const char *argv[], int max, int *trailingwhitespace)
static void print_uptimestr (int fd, struct timeval timeval, const char *prefix, int printsec)
static int set_full_cmd (struct ast_cli_entry *e)
static int word_match (const char *cmd, const char *cli_word)

Variables

static struct ast_threadstorage ast_cli_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ast_cli_buf , .custom_init = NULL , }
static struct ast_cli_entry cli_cli []
static int cli_default_perm = 1
 Default permissions value 1=Permit 0=Deny.
static const char cli_rsvd [] = "[]{}|*%"
static int climodentryfd = -1
static ast_mutex_t climodentrylock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static struct module_level_list debug_modules
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


Detailed Description

Standard Command Line Interface.

Author:
Mark Spencer <markster@digium.com>

Definition in file cli.c.


Define Documentation

#define AST_CLI_INITLEN   256

Initial buffer size for resulting strings in ast_cli().

Definition at line 99 of file cli.c.

Referenced by ast_cli().

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

Referenced by handle_chanlist().

#define DAY   (HOUR*24)

Referenced by print_uptimestr().

#define FORMAT_STRING   "%-25s %-20s %-20s\n"

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

Referenced by group_show_channels(), and handle_chanlist().

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

Referenced by handle_chanlist().

#define HOUR   (MINUTE*60)

Referenced by print_uptimestr().

#define MINUTE   (SECOND*60)

Referenced by print_uptimestr().

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

Definition at line 641 of file cli.c.

Referenced by modlist_modentry().

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

Definition at line 642 of file cli.c.

Referenced by handle_modlist().

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

Referenced by print_uptimestr().

#define SECOND   (1)

#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"

Referenced by handle_chanlist().

#define VERBOSE_FORMAT_STRING2   "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"

Referenced by handle_chanlist().

#define WEEK   (DAY*7)

Referenced by print_uptimestr().

#define YEAR   (DAY*365)

Referenced by print_uptimestr().


Function Documentation

static char * __ast_cli_generator ( const char *  text,
const char *  word,
int  state,
int  lock 
) [static]

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

02374 {
02375    const char *argv[AST_MAX_ARGS];
02376    struct ast_cli_entry *e = NULL;
02377    int x = 0, argindex, matchlen;
02378    int matchnum=0;
02379    char *ret = NULL;
02380    char matchstr[80] = "";
02381    int tws = 0;
02382    /* Split the argument into an array of words */
02383    char *duplicate = parse_args(text, &x, argv, ARRAY_LEN(argv), &tws);
02384 
02385    if (!duplicate)   /* malloc error */
02386       return NULL;
02387 
02388    /* Compute the index of the last argument (could be an empty string) */
02389    argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x;
02390 
02391    /* rebuild the command, ignore terminating white space and flatten space */
02392    ast_join(matchstr, sizeof(matchstr)-1, argv);
02393    matchlen = strlen(matchstr);
02394    if (tws) {
02395       strcat(matchstr, " "); /* XXX */
02396       if (matchlen)
02397          matchlen++;
02398    }
02399    if (lock)
02400       AST_RWLIST_RDLOCK(&helpers);
02401    while ( (e = cli_next(e)) ) {
02402       /* XXX repeated code */
02403       int src = 0, dst = 0, n = 0;
02404 
02405       if (e->command[0] == '_')
02406          continue;
02407 
02408       /*
02409        * Try to match words, up to and excluding the last word, which
02410        * is either a blank or something that we want to extend.
02411        */
02412       for (;src < argindex; dst++, src += n) {
02413          n = word_match(argv[src], e->cmda[dst]);
02414          if (n < 0)
02415             break;
02416       }
02417 
02418       if (src != argindex && more_words(e->cmda + dst))  /* not a match */
02419          continue;
02420       ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n);
02421       matchnum += n; /* this many matches here */
02422       if (ret) {
02423          /*
02424           * argv[src] is a valid prefix of the next word in this
02425           * command. If this is also the correct entry, return it.
02426           */
02427          if (matchnum > state)
02428             break;
02429          ast_free(ret);
02430          ret = NULL;
02431       } else if (ast_strlen_zero(e->cmda[dst])) {
02432          /*
02433           * This entry is a prefix of the command string entered
02434           * (only one entry in the list should have this property).
02435           * Run the generator if one is available. In any case we are done.
02436           */
02437          if (e->handler) { /* new style command */
02438             struct ast_cli_args a = {
02439                .line = matchstr, .word = word,
02440                .pos = argindex,
02441                .n = state - matchnum,
02442                .argv = argv,
02443                .argc = x};
02444             ret = e->handler(e, CLI_GENERATE, &a);
02445          }
02446          if (ret)
02447             break;
02448       }
02449    }
02450    if (lock)
02451       AST_RWLIST_UNLOCK(&helpers);
02452    ast_free(duplicate);
02453    return ret;
02454 }

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

Definition at line 2060 of file cli.c.

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

Referenced by ast_cli_register().

02061 {
02062    struct ast_cli_entry *cur;
02063    int i, lf, ret = -1;
02064 
02065    struct ast_cli_args a;  /* fake argument */
02066    char **dst = (char **)e->cmda;   /* need to cast as the entry is readonly */
02067    char *s;
02068 
02069    memset(&a, '\0', sizeof(a));
02070    e->handler(e, CLI_INIT, &a);
02071    /* XXX check that usage and command are filled up */
02072    s = ast_skip_blanks(e->command);
02073    s = e->command = ast_strdup(s);
02074    for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) {
02075       *dst++ = s; /* store string */
02076       s = ast_skip_nonblanks(s);
02077       if (*s == '\0')   /* we are done */
02078          break;
02079       *s++ = '\0';
02080       s = ast_skip_blanks(s);
02081    }
02082    *dst++ = NULL;
02083    
02084    AST_RWLIST_WRLOCK(&helpers);
02085    
02086    if (find_cli(e->cmda, 1)) {
02087       ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", S_OR(e->_full_cmd, e->command));
02088       goto done;
02089    }
02090    if (set_full_cmd(e))
02091       goto done;
02092 
02093    lf = e->cmdlen;
02094    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
02095       int len = cur->cmdlen;
02096       if (lf < len)
02097          len = lf;
02098       if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) {
02099          AST_RWLIST_INSERT_BEFORE_CURRENT(e, list); 
02100          break;
02101       }
02102    }
02103    AST_RWLIST_TRAVERSE_SAFE_END;
02104 
02105    if (!cur)
02106       AST_RWLIST_INSERT_TAIL(&helpers, e, list); 
02107    ret = 0; /* success */
02108 
02109 done:
02110    AST_RWLIST_UNLOCK(&helpers);
02111 
02112    return ret;
02113 }

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

Definition at line 2038 of file cli.c.

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

Referenced by ast_cli_unregister().

02039 {
02040    if (e->inuse) {
02041       ast_log(LOG_WARNING, "Can't remove command that is in use\n");
02042    } else {
02043       AST_RWLIST_WRLOCK(&helpers);
02044       AST_RWLIST_REMOVE(&helpers, e, list);
02045       AST_RWLIST_UNLOCK(&helpers);
02046       ast_free(e->_full_cmd);
02047       e->_full_cmd = NULL;
02048       if (e->handler) {
02049          /* this is a new-style entry. Reset fields and free memory. */
02050          char *cmda = (char *) e->cmda;
02051          memset(cmda, '\0', sizeof(e->cmda));
02052          ast_free(e->command);
02053          e->command = NULL;
02054          e->usage = NULL;
02055       }
02056    }
02057    return 0;
02058 }

static void __init_ast_cli_buf ( void   )  [static]

Definition at line 96 of file cli.c.

00102 {

void ast_builtins_init ( void   ) 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 1871 of file cli.c.

References ARRAY_LEN, ast_cli_register_multiple(), and cli_cli.

Referenced by main().

01872 {
01873    ast_cli_register_multiple(cli_cli, ARRAY_LEN(cli_cli));
01874 }

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

Definition at line 101 of file cli.c.

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

Referenced by __iax2_show_peers(), __say_cli_init(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), agent_logoff_cmd(), agents_show(), agents_show_online(), ais_clm_show_members(), ais_evt_show_event_channels(), aji_cli_create_collection(), aji_cli_create_leafnode(), aji_cli_delete_pubsub_node(), aji_cli_list_pubsub_nodes(), aji_cli_purge_pubsub_nodes(), aji_do_reload(), aji_do_set_debug(), aji_show_buddies(), aji_show_clients(), aji_test(), alias_show(), aoc_cli_debug_enable(), ast_cli_command_full(), ast_cli_netstats(), ast_console_toggle_mute(), cc_cli_output_status(), cc_cli_print_monitor_stats(), channel_set_debug(), cli_console_active(), cli_console_answer(), cli_console_autoanswer(), cli_console_dial(), cli_console_flash(), cli_console_hangup(), cli_console_mute(), cli_console_sendtext(), cli_fax_set_debug(), cli_fax_show_capabilities(), cli_fax_show_session(), cli_fax_show_sessions(), cli_fax_show_settings(), cli_fax_show_stats(), cli_fax_show_version(), cli_list_available(), cli_list_devices(), cli_match_char_tree(), cli_realtime_destroy(), cli_realtime_load(), cli_realtime_store(), cli_realtime_update(), cli_realtime_update2(), cli_tps_ping(), cli_tps_report(), console_active(), console_answer(), console_autoanswer(), console_boost(), console_cmd(), console_dial(), console_do_answer(), console_flash(), console_hangup(), console_mute(), console_sendtext(), console_transfer(), dahdi_set_dnd(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), dahdi_show_status(), dahdi_show_version(), data_provider_print_cli(), data_result_print_cli(), data_result_print_cli_node(), 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_mfcr2_set_debug(), handle_mfcr2_show_channels(), handle_mfcr2_show_variants(), handle_mfcr2_version(), handle_mgcp_set_debug(), handle_mgcp_show_endpoints(), handle_minivm_list_templates(), handle_minivm_reload(), handle_minivm_show_settings(), handle_minivm_show_stats(), handle_minivm_show_users(), handle_minivm_show_zones(), handle_modlist(), handle_parkedcalls(), handle_pri_debug(), handle_pri_service_generic(), handle_pri_set_debug_file(), handle_pri_show_debug(), handle_pri_show_span(), handle_pri_version(), handle_queue_add_member(), handle_queue_pause_member(), handle_queue_remove_member(), handle_queue_rule_show(), handle_queue_set_member_penalty(), handle_redirect(), handle_reload(), handle_restart_when_convenient(), handle_set_chanvar(), handle_set_extenpatternmatchnew(), handle_set_global(), handle_show_applications(), handle_show_calendar(), handle_show_calendars(), handle_show_chanvar(), handle_show_dialplan(), handle_show_function(), handle_show_functions(), handle_show_globals(), handle_show_hint(), handle_show_hints(), handle_show_http(), handle_show_profile(), handle_show_routes(), handle_show_settings(), handle_show_switches(), handle_show_sysinfo(), handle_show_threads(), handle_show_version_files(), handle_showcalls(), handle_showchan(), handle_showmanager(), handle_showmanagers(), handle_showmancmd(), handle_showmancmds(), handle_showmanconn(), handle_showmaneventq(), handle_skinny_set_debug(), handle_skinny_show_settings(), handle_softhangup(), handle_stop_when_convenient(), handle_unload(), handle_unset_extenpatternmatchnew(), handle_verbose(), handle_version(), handle_voicemail_reload(), handle_voicemail_show_users(), handle_voicemail_show_zones(), help1(), help_workhorse(), iax_show_provisioning(), jingle_show_channels(), locals_show(), meetme_cmd(), meetme_show_cmd(), modlist_modentry(), orig_app(), orig_exten(), peer_dump_func(), pktccops_debug(), pktccops_gatedel(), pktccops_gateset(), pktccops_show_cmtses(), pktccops_show_gates(), pktccops_show_pools(), print_app(), print_app_docs(), print_bc_info(), print_cel_sub(), print_codec_to_cli(), print_group(), print_stats_cb(), print_uptimestr(), radio_active(), radio_set_debug(), radio_set_debug_off(), radio_set_xpmr_debug(), radio_tune(), realtime_ldap_status(), rpt_do_cmd(), rpt_do_debug(), rpt_do_dump(), rpt_do_fun(), rpt_do_local_nodes(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_chanstats_cb(), show_codec_n(), show_codecs(), show_config_description(), show_debug_helper(), show_dialplan_helper(), show_license(), show_users_realtime(), show_warranty(), sig_pri_cli_show_channels(), sig_pri_cli_show_channels_header(), sig_pri_cli_show_span(), sig_pri_cli_show_spans(), sip_cli_notify(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_prune_realtime(), sip_set_history(), sip_show_channel(), sip_show_channels(), sip_show_channelstats(), sip_show_domains(), sip_show_history(), sip_show_inuse(), sip_show_mwi(), sip_show_objects(), sip_show_registry(), sip_show_sched(), sip_show_settings(), sip_show_tcp(), sip_show_user(), sip_show_users(), sip_unregister(), sla_show_stations(), sla_show_trunks(), spandsp_fax_cli_show_capabilities(), spandsp_fax_cli_show_session(), spandsp_fax_cli_show_stats(), timing_test(), tune_rxctcss(), tune_rxinput(), tune_rxvoice(), tune_txoutput(), unistim_do_debug(), unistim_info(), and unistim_sp().

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

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

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

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

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

02462 {
02463    const char *args[AST_MAX_ARGS + 1];
02464    struct ast_cli_entry *e;
02465    int x;
02466    char *duplicate = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL);
02467    char tmp[AST_MAX_ARGS + 1];
02468    char *retval = NULL;
02469    struct ast_cli_args a = {
02470       .fd = fd, .argc = x, .argv = args+1 };
02471 
02472    if (duplicate == NULL)
02473       return -1;
02474 
02475    if (x < 1)  /* We need at least one entry, otherwise ignore */
02476       goto done;
02477 
02478    AST_RWLIST_RDLOCK(&helpers);
02479    e = find_cli(args + 1, 0);
02480    if (e)
02481       ast_atomic_fetchadd_int(&e->inuse, 1);
02482    AST_RWLIST_UNLOCK(&helpers);
02483    if (e == NULL) {
02484       ast_cli(fd, "No such command '%s' (type 'core show help %s' for other possible commands)\n", s, find_best(args + 1));
02485       goto done;
02486    }
02487 
02488    ast_join(tmp, sizeof(tmp), args + 1);
02489    /* Check if the user has rights to run this command. */
02490    if (!cli_has_permissions(uid, gid, tmp)) {
02491       ast_cli(fd, "You don't have permissions to run '%s' command\n", tmp);
02492       ast_free(duplicate);
02493       return 0;
02494    }
02495 
02496    /*
02497     * Within the handler, argv[-1] contains a pointer to the ast_cli_entry.
02498     * Remember that the array returned by parse_args is NULL-terminated.
02499     */
02500    args[0] = (char *)e;
02501 
02502    retval = e->handler(e, CLI_HANDLER, &a);
02503 
02504    if (retval == CLI_SHOWUSAGE) {
02505       ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
02506    } else {
02507       if (retval == CLI_FAILURE)
02508          ast_cli(fd, "Command '%s' failed.\n", s);
02509    }
02510    ast_atomic_fetchadd_int(&e->inuse, -1);
02511 done:
02512    ast_free(duplicate);
02513    return 0;
02514 }

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

References ast_cli_command_full().

Referenced by netconsole().

02517 {
02518    char cmd[512];
02519    int x, y = 0, count = 0;
02520 
02521    for (x = 0; x < size; x++) {
02522       cmd[y] = s[x];
02523       y++;
02524       if (s[x] == '\0') {
02525          ast_cli_command_full(uid, gid, fd, cmd);
02526          y = 0;
02527          count++;
02528       }
02529    }
02530    return count;
02531 }

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

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

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

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

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

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

Referenced by cli_complete(), and handle_commandmatchesarray().

02313 {
02314    char **match_list = NULL, *retstr, *prevstr;
02315    size_t match_list_len, max_equal, which, i;
02316    int matches = 0;
02317 
02318    /* leave entry 0 free for the longest common substring */
02319    match_list_len = 1;
02320    while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
02321       if (matches + 1 >= match_list_len) {
02322          match_list_len <<= 1;
02323          if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(*match_list))))
02324             return NULL;
02325       }
02326       match_list[++matches] = retstr;
02327    }
02328 
02329    if (!match_list)
02330       return match_list; /* NULL */
02331 
02332    /* Find the longest substring that is common to all results
02333     * (it is a candidate for completion), and store a copy in entry 0.
02334     */
02335    prevstr = match_list[1];
02336    max_equal = strlen(prevstr);
02337    for (which = 2; which <= matches; which++) {
02338       for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
02339          continue;
02340       max_equal = i;
02341    }
02342 
02343    if (!(retstr = ast_malloc(max_equal + 1)))
02344       return NULL;
02345    
02346    ast_copy_string(retstr, match_list[1], max_equal + 1);
02347    match_list[0] = retstr;
02348 
02349    /* ensure that the array is NULL terminated */
02350    if (matches + 1 >= match_list_len) {
02351       if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list))))
02352          return NULL;
02353    }
02354    match_list[matches + 1] = NULL;
02355 
02356    return match_list;
02357 }

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

02457 {
02458    return __ast_cli_generator(text, word, state, 1);
02459 }

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

Return the number of unique matches for the generator.

Definition at line 2295 of file cli.c.

References ast_cli_generator(), and ast_free.

Referenced by handle_commandnummatches().

02296 {
02297    int matches = 0, i = 0;
02298    char *buf = NULL, *oldbuf = NULL;
02299 
02300    while ((buf = ast_cli_generator(text, word, i++))) {
02301       if (!oldbuf || strcmp(buf,oldbuf))
02302          matches++;
02303       if (oldbuf)
02304          ast_free(oldbuf);
02305       oldbuf = buf;
02306    }
02307    if (oldbuf)
02308       ast_free(oldbuf);
02309    return matches;
02310 }

int ast_cli_perms_init ( int  reload  ) 

Provided by cli.c

Definition at line 1748 of file cli.c.

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

Referenced by handle_cli_reload_permissions(), and main().

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

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

References __ast_cli_register().

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

02123 {
02124    return __ast_cli_register(e, NULL);
02125 }

int ast_cli_register_multiple ( struct ast_cli_entry e,
int  len 
)

Register multiple commands.

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

Definition at line 2130 of file cli.c.

References ast_cli_register().

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

02131 {
02132    int i, res = 0;
02133 
02134    for (i = 0; i < len; i++)
02135       res |= ast_cli_register(e + i);
02136 
02137    return res;
02138 }

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

References __ast_cli_unregister().

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

02117 {
02118    return __ast_cli_unregister(e, NULL);
02119 }

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

References ast_cli_unregister().

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

02141 {
02142    int i, res = 0;
02143 
02144    for (i = 0; i < len; i++)
02145       res |= ast_cli_unregister(e + i);
02146 
02147    return res;
02148 }

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

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

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

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

unsigned int ast_debug_get_by_module ( const char *  module  ) 

Get the debug level for a module.

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

Definition at line 119 of file cli.c.

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

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

unsigned int ast_verbose_get_by_module ( const char *  module  ) 

Get the verbose level for a module.

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

Definition at line 136 of file cli.c.

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

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

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

Definition at line 1276 of file cli.c.

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

Referenced by handle_core_set_debug_channel().

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

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

Definition at line 166 of file cli.c.

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

Referenced by ast_cli_command_full(), and handle_cli_check_permissions().

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

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

Definition at line 708 of file cli.c.

References AST_LIST_FIRST, AST_LIST_NEXT, and cli_perm::list.

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

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

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

Definition at line 223 of file cli.c.

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

Referenced by handle_load().

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

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

Definition at line 345 of file cli.c.

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

Referenced by handle_verbose().

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

static void destroy_user_perms ( void   )  [static]

cleanup (free) cli_perms linkedlist.

Definition at line 1732 of file cli.c.

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

Referenced by ast_cli_perms_init().

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

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

Definition at line 2020 of file cli.c.

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

02021 {
02022    static char cmdline[80];
02023    int x;
02024    /* See how close we get, then print the candidate */
02025    const char *myargv[AST_MAX_CMD_LEN] = { NULL, };
02026 
02027    AST_RWLIST_RDLOCK(&helpers);
02028    for (x = 0; argv[x]; x++) {
02029       myargv[x] = argv[x];
02030       if (!find_cli(myargv, -1))
02031          break;
02032    }
02033    AST_RWLIST_UNLOCK(&helpers);
02034    ast_join(cmdline, sizeof(cmdline), myargv);
02035    return cmdline;
02036 }

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

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

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

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

Find the debug or verbose file setting.

Definition at line 332 of file cli.c.

References AST_LIST_TRAVERSE, and module_level::module.

Referenced by handle_verbose().

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

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

Definition at line 1579 of file cli.c.

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

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

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

Definition at line 842 of file cli.c.

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

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

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

handles CLI command 'cli check permissions'

Definition at line 1088 of file cli.c.

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

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

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

handles CLI command 'cli reload permissions'

Definition at line 1069 of file cli.c.

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

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

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

handles CLI command 'cli show permissions'

Definition at line 1024 of file cli.c.

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

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

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

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

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

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

Definition at line 1246 of file cli.c.

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

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

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

Definition at line 1165 of file cli.c.

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

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

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

Definition at line 1220 of file cli.c.

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

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

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

Definition at line 306 of file cli.c.

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

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

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

Definition at line 1300 of file cli.c.

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

Referenced by handle_nodebugchan_deprecated().

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

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

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

02184 {
02185    char fullcmd[80];
02186    struct ast_cli_entry *my_e;
02187    char *res = CLI_SUCCESS;
02188 
02189    if (cmd == CLI_INIT) {
02190       e->command = "core show help";
02191       e->usage =
02192          "Usage: core show help [topic]\n"
02193          "       When called with a topic as an argument, displays usage\n"
02194          "       information on the given command. If called without a\n"
02195          "       topic, it provides a list of commands.\n";
02196       return NULL;
02197 
02198    } else if (cmd == CLI_GENERATE) {
02199       /* skip first 14 or 15 chars, "core show help " */
02200       int l = strlen(a->line);
02201 
02202       if (l > 15) {
02203          l = 15;
02204       }
02205       /* XXX watch out, should stop to the non-generator parts */
02206       return __ast_cli_generator(a->line + l, a->word, a->n, 0);
02207    }
02208    if (a->argc == e->args) {
02209       return help1(a->fd, NULL, 0);
02210    }
02211 
02212    AST_RWLIST_RDLOCK(&helpers);
02213    my_e = find_cli(a->argv + 3, 1); /* try exact match first */
02214    if (!my_e) {
02215       res = help1(a->fd, a->argv + 3, 1 /* locked */);
02216       AST_RWLIST_UNLOCK(&helpers);
02217       return res;
02218    }
02219    if (my_e->usage)
02220       ast_cli(a->fd, "%s", my_e->usage);
02221    else {
02222       ast_join(fullcmd, sizeof(fullcmd), a->argv + 3);
02223       ast_cli(a->fd, "No help text available for '%s'.\n", fullcmd);
02224    }
02225    AST_RWLIST_UNLOCK(&helpers);
02226    return res;
02227 }

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

Definition at line 245 of file cli.c.

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

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

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

Definition at line 567 of file cli.c.

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

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

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

Definition at line 748 of file cli.c.

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

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

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

Definition at line 1357 of file cli.c.

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

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

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

Definition at line 271 of file cli.c.

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

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

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

Definition at line 787 of file cli.c.

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

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

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

Definition at line 1384 of file cli.c.

References ast_channel::_bridge, ast_channel::_state, ast_cli_args::argc, ast_cli_args::argv, ast_bridged_channel(), ast_cdr_serialize_variables(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), AST_FLAG_BLOCKING, ast_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::caller, ast_channel::cdr, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel::connected, DEBUGCHAN_FLAG, ast_channel::dialed, ast_cli_args::fd, ast_channel::fds, ast_channel::fin, ast_channel::fout, ast_party_connected_line::id, ast_party_caller::id, ast_channel::language, ast_cli_args::line, ast_channel::linkedid, ast_cli_args::n, name, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, pbx_builtin_serialize_variables(), ast_cli_args::pos, ast_channel::readformat, ast_channel::readtrans, ast_channel::rings, S_COR, S_OR, ast_cdr::start, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech, ast_channel_tech::type, ast_channel::uniqueid, ast_cli_entry::usage, ast_party_name::valid, ast_party_number::valid, ast_channel::whentohangup, ast_cli_args::word, ast_channel::writeformat, and ast_channel::writetrans.

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

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

Definition at line 717 of file cli.c.

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

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

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

Definition at line 976 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_channel::name, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

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

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

Definition at line 592 of file cli.c.

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

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

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

Definition at line 385 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, args, ast_cli_args::argv, ast_calloc, ast_clear_flag, ast_cli(), ast_complete_source_filename(), ast_free, AST_OPT_FLAG_DEBUG_MODULE, AST_OPT_FLAG_VERBOSE_MODULE, ast_options, AST_RWLIST_EMPTY, AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_set_flag, ast_strdup, ast_strdupa, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_number(), module_level::entry, ast_cli_args::fd, find_module_level(), module_level::level, module_level::module, ast_cli_args::n, option_debug, option_verbose, ast_cli_args::pos, S_OR, and ast_cli_entry::usage.

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

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

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

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

02155 {
02156    char matchstr[80] = "";
02157    struct ast_cli_entry *e = NULL;
02158    int len = 0;
02159    int found = 0;
02160 
02161    if (match) {
02162       ast_join(matchstr, sizeof(matchstr), match);
02163       len = strlen(matchstr);
02164    }
02165    if (!locked)
02166       AST_RWLIST_RDLOCK(&helpers);
02167    while ( (e = cli_next(e)) ) {
02168       /* Hide commands that start with '_' */
02169       if (e->_full_cmd[0] == '_')
02170          continue;
02171       if (match && strncasecmp(matchstr, e->_full_cmd, len))
02172          continue;
02173       ast_cli(fd, "%30.30s %s\n", e->_full_cmd, S_OR(e->summary, "<no description available>"));
02174       found++;
02175    }
02176    if (!locked)
02177       AST_RWLIST_UNLOCK(&helpers);
02178    if (!found && matchstr[0])
02179       ast_cli(fd, "No such command '%s'.\n", matchstr);
02180    return CLI_SUCCESS;
02181 }

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

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

Referenced by __ast_cli_generator().

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

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

Definition at line 647 of file cli.c.

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

Referenced by handle_modlist().

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

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

returns true if there are more words to match

Definition at line 2360 of file cli.c.

Referenced by __ast_cli_generator().

02361 {
02362    int i;
02363    for (i = 0; dst[i]; i++) {
02364       if (dst[i][0] != '[')
02365          return -1;
02366    }
02367    return 0;
02368 }

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

Definition at line 2229 of file cli.c.

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

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

02230 {
02231    char *duplicate, *cur;
02232    int x = 0;
02233    int quoted = 0;
02234    int escaped = 0;
02235    int whitespace = 1;
02236    int dummy = 0;
02237 
02238    if (trailingwhitespace == NULL)
02239       trailingwhitespace = &dummy;
02240    *trailingwhitespace = 0;
02241    if (s == NULL) /* invalid, though! */
02242       return NULL;
02243    /* make a copy to store the parsed string */
02244    if (!(duplicate = ast_strdup(s)))
02245       return NULL;
02246 
02247    cur = duplicate;
02248    /* scan the original string copying into cur when needed */
02249    for (; *s ; s++) {
02250       if (x >= max - 1) {
02251          ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s);
02252          break;
02253       }
02254       if (*s == '"' && !escaped) {
02255          quoted = !quoted;
02256          if (quoted && whitespace) {
02257             /* start a quoted string from previous whitespace: new argument */
02258             argv[x++] = cur;
02259             whitespace = 0;
02260          }
02261       } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) {
02262          /* If we are not already in whitespace, and not in a quoted string or
02263             processing an escape sequence, and just entered whitespace, then
02264             finalize the previous argument and remember that we are in whitespace
02265          */
02266          if (!whitespace) {
02267             *cur++ = '\0';
02268             whitespace = 1;
02269          }
02270       } else if (*s == '\\' && !escaped) {
02271          escaped = 1;
02272       } else {
02273          if (whitespace) {
02274             /* we leave whitespace, and are not quoted. So it's a new argument */
02275             argv[x++] = cur;
02276             whitespace = 0;
02277          }
02278          *cur++ = *s;
02279          escaped = 0;
02280       }
02281    }
02282    /* Null terminate */
02283    *cur++ = '\0';
02284    /* XXX put a NULL in the last argument, because some functions that take
02285     * the array may want a null-terminated array.
02286     * argc still reflects the number of non-NULL entries.
02287     */
02288    argv[x] = NULL;
02289    *argc = x;
02290    *trailingwhitespace = whitespace;
02291    return duplicate;
02292 }

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

Definition at line 657 of file cli.c.

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

Referenced by handle_showcalls(), and handle_showuptime().

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

static int set_full_cmd ( struct ast_cli_entry e  )  [static]

initialize the _full_cmd string and related parameters, return 0 on success, -1 on error.

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

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

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

References ast_strlen_zero(), and strcasestr().

Referenced by __ast_cli_generator(), and find_cli().

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


Variable Documentation

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

Definition at line 96 of file cli.c.

struct ast_cli_entry cli_cli[] [static]

Definition at line 1657 of file cli.c.

Referenced by ast_builtins_init().

int cli_default_perm = 1 [static]

Default permissions value 1=Permit 0=Deny.

Definition at line 72 of file cli.c.

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

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

Definition at line 1707 of file cli.c.

int climodentryfd = -1 [static]

Definition at line 645 of file cli.c.

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

Definition at line 644 of file cli.c.

Referenced by handle_modlist().

struct module_level_list debug_modules [static]

list of module names and their debug levels

Definition at line 92 of file cli.c.

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

CLI permissions config file.

Definition at line 70 of file cli.c.

Referenced by ast_cli_perms_init().

ast_mutex_t permsconfiglock = { 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 76 of file cli.c.

struct module_level_list verbose_modules [static]

list of module names and their verbose levels

Definition at line 94 of file cli.c.


Generated on Mon Mar 19 11:30:46 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7