Mon Oct 8 12:39:20 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 103 of file cli.c.

Referenced by ast_cli().

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

Referenced by handle_chanlist().

#define DAY   (HOUR*24)

Referenced by print_uptimestr().

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

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

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

Referenced by modlist_modentry().

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

Definition at line 646 of file cli.c.

Referenced by handle_modlist().

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

Referenced by print_uptimestr().

#define SECOND   (1)

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

Referenced by handle_chanlist().

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

Referenced by handle_chanlist().

#define WEEK   (DAY*7)

Referenced by print_uptimestr().

#define YEAR   (DAY*365)

Referenced by print_uptimestr().


Function Documentation

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

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

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

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

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

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

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

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

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

static void __init_ast_cli_buf ( void   )  [static]

Definition at line 100 of file cli.c.

00106 {

void ast_builtins_init ( void   ) 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 1875 of file cli.c.

References ARRAY_LEN, ast_cli_register_multiple(), and cli_cli.

Referenced by main().

01876 {
01877    ast_cli_register_multiple(cli_cli, ARRAY_LEN(cli_cli));
01878 }

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

Definition at line 105 of file cli.c.

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

Referenced by __iax2_show_peers(), __say_cli_init(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), _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(), realtime_ldap_status(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_chanstats_cb(), show_codec_n(), show_codecs(), show_config_description(), show_debug_helper(), show_dialplan_helper(), show_license(), show_users_realtime(), show_warranty(), 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(), unistim_do_debug(), unistim_info(), and unistim_sp().

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

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

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

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

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

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

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

References ast_cli_command_full().

Referenced by netconsole().

02525 {
02526    char cmd[512];
02527    int x, y = 0, count = 0;
02528 
02529    for (x = 0; x < size; x++) {
02530       cmd[y] = s[x];
02531       y++;
02532       if (s[x] == '\0') {
02533          ast_cli_command_full(uid, gid, fd, cmd);
02534          y = 0;
02535          count++;
02536       }
02537    }
02538    return count;
02539 }

char* ast_cli_complete ( const char *  word,
const char *const   choices[],
int  pos 
)

Helper function to generate cli entries from a NULL-terminated array. Returns the n-th matching entry from the array, or NULL if not found. Can be used to implement generate() for static entries as below (in this example we complete the word in position 2):

    char *my_generate(const char *line, const char *word, int pos, int n)
    {
        static const char * const choices[] = { "one", "two", "three", NULL };
   if (pos == 2)
         return ast_cli_complete(word, choices, n);
   else
      return NULL;
    }

Definition at line 1535 of file cli.c.

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

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

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

char** ast_cli_completion_matches ( const char *  ,
const char *   
)

Generates a NULL-terminated array of strings that 1) begin with the string in the second parameter, and 2) are valid in a command after the string in the first parameter.

The first entry (offset 0) of the result is the longest common substring in the results, useful to extend the string that has been completed. Subsequent entries are all possible values, followed by a NULL. All strings and the array itself are malloc'ed and must be freed by the caller.

Definition at line 2316 of file cli.c.

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

Referenced by cli_complete(), and handle_commandmatchesarray().

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

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

02465 {
02466    return __ast_cli_generator(text, word, state, 1);
02467 }

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

Return the number of unique matches for the generator.

Definition at line 2299 of file cli.c.

References ast_cli_generator(), and ast_free.

Referenced by handle_commandnummatches().

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

int ast_cli_perms_init ( int  reload  ) 

Provided by cli.c

Definition at line 1752 of file cli.c.

References ast_calloc, ast_category_browse(), ast_config_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_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().

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

int ast_cli_register ( struct ast_cli_entry e  ) 

Registers a command or an array of commands.

Parameters:
e which cli entry to register. Register your own command
Return values:
0 on success
-1 on failure

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

02127 {
02128    return __ast_cli_register(e, NULL);
02129 }

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

02135 {
02136    int i, res = 0;
02137 
02138    for (i = 0; i < len; i++)
02139       res |= ast_cli_register(e + i);
02140 
02141    return res;
02142 }

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

References __ast_cli_unregister().

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

02121 {
02122    return __ast_cli_unregister(e, NULL);
02123 }

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

02145 {
02146    int i, res = 0;
02147 
02148    for (i = 0; i < len; i++)
02149       res |= ast_cli_unregister(e + i);
02150 
02151    return res;
02152 }

char* ast_complete_channels ( const char *  line,
const char *  word,
int  pos,
int  state,
int  rpos 
)

Command completion for the list of active channels.

This can be called from a CLI command completion function that wants to complete from the list of active channels. 'rpos' is the required position in the command. This function will return NULL immediately if 'rpos' is not the same as the current position, 'pos'.

Definition at line 1547 of file cli.c.

References ast_channel_iterator_all_new(), ast_channel_iterator_by_name_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_strdup, 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().

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

unsigned int ast_debug_get_by_module ( const char *  module  ) 

Get the debug level for a module.

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

Definition at line 123 of file cli.c.

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

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

unsigned int ast_verbose_get_by_module ( const char *  module  ) 

Get the verbose level for a module.

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

Definition at line 140 of file cli.c.

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

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

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

Definition at line 1280 of file cli.c.

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

Referenced by handle_core_set_debug_channel().

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

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

Definition at line 170 of file cli.c.

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

Referenced by ast_cli_command_full(), and handle_cli_check_permissions().

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

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

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

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

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

Definition at line 227 of file cli.c.

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

Referenced by handle_load().

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

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

Definition at line 349 of file cli.c.

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

Referenced by handle_verbose().

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

static void destroy_user_perms ( void   )  [static]

cleanup (free) cli_perms linkedlist.

Definition at line 1736 of file cli.c.

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

Referenced by ast_cli_perms_init().

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

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

Definition at line 2024 of file cli.c.

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

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

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

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

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

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

Find the debug or verbose file setting.

Definition at line 336 of file cli.c.

References AST_LIST_TRAVERSE, and module_level::module.

Referenced by handle_verbose().

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

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

Definition at line 1583 of file cli.c.

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

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

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

Definition at line 846 of file cli.c.

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

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

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

handles CLI command 'cli check permissions'

Definition at line 1092 of file cli.c.

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

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

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

handles CLI command 'cli reload permissions'

Definition at line 1073 of file cli.c.

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

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

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

handles CLI command 'cli show permissions'

Definition at line 1028 of file cli.c.

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

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

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

Definition at line 1637 of file cli.c.

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

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

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

Definition at line 1250 of file cli.c.

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

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

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

Definition at line 1169 of file cli.c.

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

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

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

Definition at line 1224 of file cli.c.

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

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

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

Definition at line 310 of file cli.c.

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

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

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

Definition at line 1304 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, 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().

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

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

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

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

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

Definition at line 249 of file cli.c.

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

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

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

Definition at line 571 of file cli.c.

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

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

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

Definition at line 752 of file cli.c.

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

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

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

Definition at line 1361 of file cli.c.

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

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

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

Definition at line 275 of file cli.c.

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

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

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

Definition at line 791 of file cli.c.

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

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

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

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

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

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

Definition at line 721 of file cli.c.

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

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

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

Definition at line 980 of file cli.c.

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

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

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

Definition at line 596 of file cli.c.

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

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

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

Definition at line 389 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, args, ast_cli_args::argv, ast_calloc, ast_clear_flag, ast_cli(), ast_complete_source_filename(), ast_free, AST_OPT_FLAG_DEBUG_MODULE, AST_OPT_FLAG_VERBOSE_MODULE, ast_options, AST_RWLIST_EMPTY, AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_set_flag, ast_strdup, ast_strdupa, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_number(), 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.

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

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

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

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

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

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

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

Referenced by __ast_cli_generator().

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

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

Definition at line 651 of file cli.c.

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

Referenced by handle_modlist().

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

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

returns true if there are more words to match

Definition at line 2368 of file cli.c.

Referenced by __ast_cli_generator().

02369 {
02370    int i;
02371    for (i = 0; dst[i]; i++) {
02372       if (dst[i][0] != '[')
02373          return -1;
02374    }
02375    return 0;
02376 }

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

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

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

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

Definition at line 661 of file cli.c.

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

Referenced by handle_showcalls(), and handle_showuptime().

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

static int set_full_cmd ( struct ast_cli_entry e  )  [static]

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

Definition at line 1717 of file cli.c.

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

Referenced by __ast_cli_register().

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

static int word_match ( const char *  cmd,
const char *  cli_word 
) [static]

match a word in the CLI entry. returns -1 on mismatch, 0 on match of an optional word, 1 on match of a full word.

The pattern can be any_word match for equal [foo|bar|baz] optionally, one of these words {foo|bar|baz} exactly, one of these words % any word

Definition at line 1891 of file cli.c.

References ast_strlen_zero(), and strcasestr().

Referenced by __ast_cli_generator(), and find_cli().

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


Variable Documentation

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

Definition at line 100 of file cli.c.

struct ast_cli_entry cli_cli[] [static]

Definition at line 1661 of file cli.c.

Referenced by ast_builtins_init().

int cli_default_perm = 1 [static]

Default permissions value 1=Permit 0=Deny.

Definition at line 76 of file cli.c.

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

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

Definition at line 1711 of file cli.c.

int climodentryfd = -1 [static]

Definition at line 649 of file cli.c.

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

Definition at line 648 of file cli.c.

Referenced by handle_modlist().

struct module_level_list debug_modules [static]

list of module names and their debug levels

Definition at line 96 of file cli.c.

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

CLI permissions config file.

Definition at line 74 of file cli.c.

Referenced by ast_cli_perms_init().

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

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

Definition at line 80 of file cli.c.

struct module_level_list verbose_modules [static]

list of module names and their verbose levels

Definition at line 98 of file cli.c.


Generated on Mon Oct 8 12:39:20 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7