#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_entry * | cli_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_entry * | find_cli (const char *const cmds[], int match_type) |
static struct module_level * | find_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 |
Definition in file cli.c.
#define AST_CLI_INITLEN 256 |
#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" |
#define MODLIST_FORMAT2 "%-30s %-40.40s %-10s\n" |
#define NEEDCOMMA | ( | x | ) | ((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().
static char * __ast_cli_generator | ( | const char * | text, | |
const char * | word, | |||
int | state, | |||
int | lock | |||
) | [static] |
Definition at line 2345 of file cli.c.
References ARRAY_LEN, ast_free, ast_join(), AST_MAX_ARGS, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_strlen_zero(), CLI_GENERATE, cli_next(), ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::handler, is_prefix(), ast_cli_args::line, more_words(), parse_args(), and word_match().
Referenced by ast_cli_generator(), handle_commandcomplete(), and handle_help().
02346 { 02347 const char *argv[AST_MAX_ARGS]; 02348 struct ast_cli_entry *e = NULL; 02349 int x = 0, argindex, matchlen; 02350 int matchnum=0; 02351 char *ret = NULL; 02352 char matchstr[80] = ""; 02353 int tws = 0; 02354 /* Split the argument into an array of words */ 02355 char *duplicate = parse_args(text, &x, argv, ARRAY_LEN(argv), &tws); 02356 02357 if (!duplicate) /* malloc error */ 02358 return NULL; 02359 02360 /* Compute the index of the last argument (could be an empty string) */ 02361 argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x; 02362 02363 /* rebuild the command, ignore terminating white space and flatten space */ 02364 ast_join(matchstr, sizeof(matchstr)-1, argv); 02365 matchlen = strlen(matchstr); 02366 if (tws) { 02367 strcat(matchstr, " "); /* XXX */ 02368 if (matchlen) 02369 matchlen++; 02370 } 02371 if (lock) 02372 AST_RWLIST_RDLOCK(&helpers); 02373 while ( (e = cli_next(e)) ) { 02374 /* XXX repeated code */ 02375 int src = 0, dst = 0, n = 0; 02376 02377 if (e->command[0] == '_') 02378 continue; 02379 02380 /* 02381 * Try to match words, up to and excluding the last word, which 02382 * is either a blank or something that we want to extend. 02383 */ 02384 for (;src < argindex; dst++, src += n) { 02385 n = word_match(argv[src], e->cmda[dst]); 02386 if (n < 0) 02387 break; 02388 } 02389 02390 if (src != argindex && more_words(e->cmda + dst)) /* not a match */ 02391 continue; 02392 ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n); 02393 matchnum += n; /* this many matches here */ 02394 if (ret) { 02395 /* 02396 * argv[src] is a valid prefix of the next word in this 02397 * command. If this is also the correct entry, return it. 02398 */ 02399 if (matchnum > state) 02400 break; 02401 ast_free(ret); 02402 ret = NULL; 02403 } else if (ast_strlen_zero(e->cmda[dst])) { 02404 /* 02405 * This entry is a prefix of the command string entered 02406 * (only one entry in the list should have this property). 02407 * Run the generator if one is available. In any case we are done. 02408 */ 02409 if (e->handler) { /* new style command */ 02410 struct ast_cli_args a = { 02411 .line = matchstr, .word = word, 02412 .pos = argindex, 02413 .n = state - matchnum, 02414 .argv = argv, 02415 .argc = x}; 02416 ret = e->handler(e, CLI_GENERATE, &a); 02417 } 02418 if (ret) 02419 break; 02420 } 02421 } 02422 if (lock) 02423 AST_RWLIST_UNLOCK(&helpers); 02424 ast_free(duplicate); 02425 return ret; 02426 }
static int __ast_cli_register | ( | struct ast_cli_entry * | e, | |
struct ast_cli_entry * | ed | |||
) | [static] |
Definition at line 2032 of file cli.c.
References ast_cli_entry::_full_cmd, ast_log(), AST_MAX_CMD_LEN, AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_skip_blanks(), ast_skip_nonblanks(), ast_strdup, ast_strlen_zero(), CLI_INIT, ast_cli_entry::cmda, ast_cli_entry::cmdlen, ast_cli_entry::command, find_cli(), ast_cli_entry::handler, len(), LOG_WARNING, S_OR, and set_full_cmd().
Referenced by ast_cli_register().
02033 { 02034 struct ast_cli_entry *cur; 02035 int i, lf, ret = -1; 02036 02037 struct ast_cli_args a; /* fake argument */ 02038 char **dst = (char **)e->cmda; /* need to cast as the entry is readonly */ 02039 char *s; 02040 02041 memset(&a, '\0', sizeof(a)); 02042 e->handler(e, CLI_INIT, &a); 02043 /* XXX check that usage and command are filled up */ 02044 s = ast_skip_blanks(e->command); 02045 s = e->command = ast_strdup(s); 02046 for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) { 02047 *dst++ = s; /* store string */ 02048 s = ast_skip_nonblanks(s); 02049 if (*s == '\0') /* we are done */ 02050 break; 02051 *s++ = '\0'; 02052 s = ast_skip_blanks(s); 02053 } 02054 *dst++ = NULL; 02055 02056 AST_RWLIST_WRLOCK(&helpers); 02057 02058 if (find_cli(e->cmda, 1)) { 02059 ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", S_OR(e->_full_cmd, e->command)); 02060 goto done; 02061 } 02062 if (set_full_cmd(e)) 02063 goto done; 02064 02065 lf = e->cmdlen; 02066 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) { 02067 int len = cur->cmdlen; 02068 if (lf < len) 02069 len = lf; 02070 if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) { 02071 AST_RWLIST_INSERT_BEFORE_CURRENT(e, list); 02072 break; 02073 } 02074 } 02075 AST_RWLIST_TRAVERSE_SAFE_END; 02076 02077 if (!cur) 02078 AST_RWLIST_INSERT_TAIL(&helpers, e, list); 02079 ret = 0; /* success */ 02080 02081 done: 02082 AST_RWLIST_UNLOCK(&helpers); 02083 02084 return ret; 02085 }
static int __ast_cli_unregister | ( | struct ast_cli_entry * | e, | |
struct ast_cli_entry * | ed | |||
) | [static] |
Definition at line 2010 of file cli.c.
References ast_cli_entry::_full_cmd, ast_free, ast_log(), AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::handler, ast_cli_entry::inuse, ast_cli_entry::list, LOG_WARNING, and ast_cli_entry::usage.
Referenced by ast_cli_unregister().
02011 { 02012 if (e->inuse) { 02013 ast_log(LOG_WARNING, "Can't remove command that is in use\n"); 02014 } else { 02015 AST_RWLIST_WRLOCK(&helpers); 02016 AST_RWLIST_REMOVE(&helpers, e, list); 02017 AST_RWLIST_UNLOCK(&helpers); 02018 ast_free(e->_full_cmd); 02019 e->_full_cmd = NULL; 02020 if (e->handler) { 02021 /* this is a new-style entry. Reset fields and free memory. */ 02022 char *cmda = (char *) e->cmda; 02023 memset(cmda, '\0', sizeof(e->cmda)); 02024 ast_free(e->command); 02025 e->command = NULL; 02026 e->usage = NULL; 02027 } 02028 } 02029 return 0; 02030 }
void ast_builtins_init | ( | void | ) |
initialize the _full_cmd string in * each of the builtins.
Provided by cli.c
Definition at line 1853 of file cli.c.
References ARRAY_LEN, ast_cli_register_multiple(), and cli_cli.
Referenced by main().
01854 { 01855 ast_cli_register_multiple(cli_cli, ARRAY_LEN(cli_cli)); 01856 }
void ast_cli | ( | int | fd, | |
const char * | fmt, | |||
... | ||||
) |
Definition at line 101 of file cli.c.
References ast_carefulwrite(), AST_CLI_INITLEN, AST_DYNSTR_BUILD_FAILED, ast_str_buffer(), ast_str_set_va(), ast_str_strlen(), and ast_str_thread_get().
Referenced by __iax2_show_peers(), __say_cli_init(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), agent_logoff_cmd(), agents_show(), agents_show_online(), ais_clm_show_members(), ais_evt_show_event_channels(), aji_cli_create_collection(), aji_cli_create_leafnode(), aji_cli_delete_pubsub_node(), aji_cli_list_pubsub_nodes(), aji_cli_purge_pubsub_nodes(), aji_do_reload(), aji_do_set_debug(), aji_show_buddies(), aji_show_clients(), aji_test(), alias_show(), aoc_cli_debug_enable(), ast_cli_command_full(), ast_cli_netstats(), ast_console_toggle_mute(), cc_cli_output_status(), cc_cli_print_monitor_stats(), channel_set_debug(), cli_console_active(), cli_console_answer(), cli_console_autoanswer(), cli_console_dial(), cli_console_flash(), cli_console_hangup(), cli_console_mute(), cli_console_sendtext(), cli_fax_set_debug(), cli_fax_show_capabilities(), cli_fax_show_session(), cli_fax_show_sessions(), cli_fax_show_settings(), cli_fax_show_stats(), cli_fax_show_version(), cli_list_available(), cli_list_devices(), cli_match_char_tree(), cli_realtime_destroy(), cli_realtime_load(), cli_realtime_store(), cli_realtime_update(), cli_realtime_update2(), cli_tps_ping(), cli_tps_report(), console_active(), console_answer(), console_autoanswer(), console_boost(), console_cmd(), console_dial(), console_do_answer(), console_flash(), console_hangup(), console_mute(), console_sendtext(), console_transfer(), dahdi_set_dnd(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), dahdi_show_status(), dahdi_show_version(), data_provider_print_cli(), data_result_print_cli(), data_result_print_cli_node(), dialog_dump_func(), do_print(), dump_raw_ie(), dundi_do_lookup(), dundi_do_precache(), dundi_do_query(), dundi_flush(), dundi_set_debug(), dundi_show_entityid(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), dundi_store_history(), event_dump_cache(), event_dump_cli(), group_show_channels(), gtalk_show_channels(), handle_chanlist(), handle_cli_agi_debug(), handle_cli_agi_dump_html(), handle_cli_agi_show(), handle_cli_check_permissions(), handle_cli_config_list(), handle_cli_core_show_channeltype(), handle_cli_core_show_channeltypes(), handle_cli_core_show_config_mappings(), handle_cli_core_show_file_formats(), handle_cli_core_show_translation(), handle_cli_database_del(), handle_cli_database_deltree(), handle_cli_database_get(), handle_cli_database_put(), handle_cli_database_show(), handle_cli_database_showkey(), handle_cli_devstate_change(), handle_cli_devstate_list(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_add_ignorepat(), handle_cli_dialplan_add_include(), handle_cli_dialplan_reload(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_remove_ignorepat(), handle_cli_dialplan_remove_include(), handle_cli_dialplan_save(), handle_cli_file_convert(), handle_cli_h323_set_debug(), handle_cli_h323_set_trace(), handle_cli_iax2_provision(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_set_debug_jb(), handle_cli_iax2_set_debug_trunk(), handle_cli_iax2_set_mtu(), handle_cli_iax2_show_cache(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_firmware(), handle_cli_iax2_show_netstats(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_stats(), handle_cli_iax2_show_threads(), handle_cli_iax2_show_users(), handle_cli_iax2_unregister(), handle_cli_indication_show(), handle_cli_keys_show(), handle_cli_misdn_reload(), handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_set_debug(), handle_cli_misdn_show_channels(), handle_cli_misdn_show_config(), handle_cli_misdn_show_port(), handle_cli_misdn_show_ports_stats(), handle_cli_misdn_show_stacks(), handle_cli_misdn_toggle_echocancel(), handle_cli_mixmonitor(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_cli_odbc_show(), handle_cli_osp_show(), handle_cli_realtime_pgsql_cache(), handle_cli_realtime_pgsql_status(), handle_cli_refresh(), handle_cli_rtcp_set_debug(), handle_cli_rtcp_set_stats(), handle_cli_rtp_set_debug(), handle_cli_show_permissions(), handle_cli_show_sqlite_status(), handle_cli_sqlite_show_tables(), handle_cli_status(), handle_cli_stun_set_debug(), handle_cli_submit(), handle_cli_transcoder_show(), handle_cli_udptl_set_debug(), handle_cli_ulimit(), handle_cli_wait_fullybooted(), handle_commandcomplete(), handle_commandmatchesarray(), handle_commandnummatches(), handle_core_set_debug_channel(), handle_core_show_image_formats(), handle_dahdi_show_cadences(), handle_debug_dialplan(), handle_feature_show(), handle_help(), handle_load(), handle_logger_reload(), handle_logger_rotate(), handle_logger_set_level(), handle_logger_show_channels(), handle_manager_show_settings(), handle_mandebug(), handle_mfcr2_set_debug(), handle_mfcr2_show_channels(), handle_mfcr2_show_variants(), handle_mfcr2_version(), handle_mgcp_set_debug(), handle_mgcp_show_endpoints(), handle_minivm_list_templates(), handle_minivm_reload(), handle_minivm_show_settings(), handle_minivm_show_stats(), handle_minivm_show_users(), handle_minivm_show_zones(), handle_modlist(), handle_parkedcalls(), handle_pri_debug(), handle_pri_service_generic(), handle_pri_set_debug_file(), handle_pri_show_debug(), handle_pri_show_span(), handle_pri_version(), handle_queue_add_member(), handle_queue_pause_member(), handle_queue_remove_member(), handle_queue_rule_show(), handle_queue_set_member_penalty(), handle_redirect(), handle_reload(), handle_restart_when_convenient(), handle_set_chanvar(), handle_set_extenpatternmatchnew(), handle_set_global(), handle_show_applications(), handle_show_calendar(), handle_show_calendars(), handle_show_chanvar(), handle_show_dialplan(), handle_show_function(), handle_show_functions(), handle_show_globals(), handle_show_hint(), handle_show_hints(), handle_show_http(), handle_show_locks(), handle_show_profile(), handle_show_routes(), handle_show_settings(), handle_show_switches(), handle_show_sysinfo(), handle_show_threads(), handle_show_version_files(), handle_showcalls(), handle_showchan(), handle_showmanager(), handle_showmanagers(), handle_showmancmd(), handle_showmancmds(), handle_showmanconn(), handle_showmaneventq(), handle_skinny_set_debug(), handle_skinny_show_settings(), handle_softhangup(), handle_stop_when_convenient(), handle_unload(), handle_unset_extenpatternmatchnew(), handle_verbose(), handle_version(), handle_voicemail_reload(), handle_voicemail_show_users(), handle_voicemail_show_zones(), help1(), help_workhorse(), iax_show_provisioning(), jingle_show_channels(), locals_show(), meetme_cmd(), meetme_show_cmd(), modlist_modentry(), orig_app(), orig_exten(), peer_dump_func(), pktccops_debug(), pktccops_gatedel(), pktccops_gateset(), pktccops_show_cmtses(), pktccops_show_gates(), pktccops_show_pools(), print_app(), print_app_docs(), print_bc_info(), print_cel_sub(), print_codec_to_cli(), print_group(), print_stats_cb(), print_uptimestr(), radio_active(), radio_set_debug(), radio_set_debug_off(), radio_set_xpmr_debug(), radio_tune(), realtime_ldap_status(), rpt_do_cmd(), rpt_do_debug(), rpt_do_dump(), rpt_do_fun(), rpt_do_local_nodes(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_chanstats_cb(), show_codec_n(), show_codecs(), show_config_description(), show_debug_helper(), show_dialplan_helper(), show_license(), show_users_realtime(), show_warranty(), sig_pri_cli_show_span(), sig_pri_cli_show_spans(), sip_cli_notify(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_prune_realtime(), sip_set_history(), sip_show_channel(), sip_show_channels(), sip_show_channelstats(), sip_show_domains(), sip_show_history(), sip_show_inuse(), sip_show_mwi(), sip_show_objects(), sip_show_registry(), sip_show_sched(), sip_show_settings(), sip_show_tcp(), sip_show_user(), sip_show_users(), sip_unregister(), sla_show_stations(), sla_show_trunks(), spandsp_fax_cli_show_capabilities(), spandsp_fax_cli_show_session(), spandsp_fax_cli_show_stats(), timing_test(), tune_rxctcss(), tune_rxinput(), tune_rxvoice(), tune_txoutput(), unistim_do_debug(), unistim_info(), and unistim_sp().
00102 { 00103 int res; 00104 struct ast_str *buf; 00105 va_list ap; 00106 00107 if (!(buf = ast_str_thread_get(&ast_cli_buf, AST_CLI_INITLEN))) 00108 return; 00109 00110 va_start(ap, fmt); 00111 res = ast_str_set_va(&buf, 0, fmt, ap); 00112 va_end(ap); 00113 00114 if (res != AST_DYNSTR_BUILD_FAILED) { 00115 ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100); 00116 } 00117 }
int ast_cli_command_full | ( | int | uid, | |
int | gid, | |||
int | fd, | |||
const char * | s | |||
) |
Interprets a command Interpret a command s, sending output to fd if uid:gid has permissions to run this command. uid = CLI_NO_PERMS to avoid checking user permissions gid = CLI_NO_PERMS to avoid checking group permissions.
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 |
0 | on success | |
-1 | on failure |
Definition at line 2433 of file cli.c.
References args, ast_atomic_fetchadd_int(), ast_cli(), ast_free, ast_join(), AST_MAX_ARGS, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_FAILURE, CLI_HANDLER, cli_has_permissions(), CLI_SHOWUSAGE, ast_cli_args::fd, find_best(), find_cli(), ast_cli_entry::handler, ast_cli_entry::inuse, parse_args(), S_OR, and ast_cli_entry::usage.
Referenced by ast_cli_command_multiple_full().
02434 { 02435 const char *args[AST_MAX_ARGS + 1]; 02436 struct ast_cli_entry *e; 02437 int x; 02438 char *duplicate = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL); 02439 char tmp[AST_MAX_ARGS + 1]; 02440 char *retval = NULL; 02441 struct ast_cli_args a = { 02442 .fd = fd, .argc = x, .argv = args+1 }; 02443 02444 if (duplicate == NULL) 02445 return -1; 02446 02447 if (x < 1) /* We need at least one entry, otherwise ignore */ 02448 goto done; 02449 02450 AST_RWLIST_RDLOCK(&helpers); 02451 e = find_cli(args + 1, 0); 02452 if (e) 02453 ast_atomic_fetchadd_int(&e->inuse, 1); 02454 AST_RWLIST_UNLOCK(&helpers); 02455 if (e == NULL) { 02456 ast_cli(fd, "No such command '%s' (type 'core show help %s' for other possible commands)\n", s, find_best(args + 1)); 02457 goto done; 02458 } 02459 02460 ast_join(tmp, sizeof(tmp), args + 1); 02461 /* Check if the user has rights to run this command. */ 02462 if (!cli_has_permissions(uid, gid, tmp)) { 02463 ast_cli(fd, "You don't have permissions to run '%s' command\n", tmp); 02464 ast_free(duplicate); 02465 return 0; 02466 } 02467 02468 /* 02469 * Within the handler, argv[-1] contains a pointer to the ast_cli_entry. 02470 * Remember that the array returned by parse_args is NULL-terminated. 02471 */ 02472 args[0] = (char *)e; 02473 02474 retval = e->handler(e, CLI_HANDLER, &a); 02475 02476 if (retval == CLI_SHOWUSAGE) { 02477 ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n")); 02478 } else { 02479 if (retval == CLI_FAILURE) 02480 ast_cli(fd, "Command '%s' failed.\n", s); 02481 } 02482 ast_atomic_fetchadd_int(&e->inuse, -1); 02483 done: 02484 ast_free(duplicate); 02485 return 0; 02486 }
int ast_cli_command_multiple_full | ( | int | uid, | |
int | gid, | |||
int | fd, | |||
size_t | size, | |||
const char * | s | |||
) |
Executes multiple CLI commands Interpret strings separated by NULL and execute each one, sending output to fd if uid has permissions, uid = CLI_NO_PERMS to avoid checking users permissions. gid = CLI_NO_PERMS to avoid checking group permissions.
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 |
number | of commands executed |
Definition at line 2488 of file cli.c.
References ast_cli_command_full().
Referenced by netconsole().
02489 { 02490 char cmd[512]; 02491 int x, y = 0, count = 0; 02492 02493 for (x = 0; x < size; x++) { 02494 cmd[y] = s[x]; 02495 y++; 02496 if (s[x] == '\0') { 02497 ast_cli_command_full(uid, gid, fd, cmd); 02498 y = 0; 02499 count++; 02500 } 02501 } 02502 return count; 02503 }
char* ast_cli_complete | ( | const char * | word, | |
const char *const | choices[], | |||
int | pos | |||
) |
Helper function to generate cli entries from a NULL-terminated array. Returns the n-th matching entry from the array, or NULL if not found. Can be used to implement generate() for static entries as below (in this example we complete the word in position 2):
char *my_generate(const char *line, const char *word, int pos, int n) { static const char * const choices[] = { "one", "two", "three", NULL }; if (pos == 2) return ast_cli_complete(word, choices, n); else return NULL; }
Definition at line 1513 of file cli.c.
References ast_strdup, ast_strlen_zero(), and len().
Referenced by complete_meetmecmd(), event_dump_cache(), handle_cc_kill(), handle_cli_core_show_translation(), handle_cli_devstate_change(), handle_cli_iax2_prune_realtime(), handle_orig(), handle_show_applications(), and sip_prune_realtime().
01514 { 01515 int i, which = 0, len; 01516 len = ast_strlen_zero(word) ? 0 : strlen(word); 01517 01518 for (i = 0; choices[i]; i++) { 01519 if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state) 01520 return ast_strdup(choices[i]); 01521 } 01522 return NULL; 01523 }
char** ast_cli_completion_matches | ( | const char * | , | |
const char * | ||||
) |
Generates a NULL-terminated array of strings that 1) begin with the string in the second parameter, and 2) are valid in a command after the string in the first parameter.
The first entry (offset 0) of the result is the longest common substring in the results, useful to extend the string that has been completed. Subsequent entries are all possible values, followed by a NULL. All strings and the array itself are malloc'ed and must be freed by the caller.
Definition at line 2284 of file cli.c.
References ast_cli_generator(), ast_copy_string(), ast_malloc, and ast_realloc.
Referenced by cli_complete(), and handle_commandmatchesarray().
02285 { 02286 char **match_list = NULL, *retstr, *prevstr; 02287 size_t match_list_len, max_equal, which, i; 02288 int matches = 0; 02289 02290 /* leave entry 0 free for the longest common substring */ 02291 match_list_len = 1; 02292 while ((retstr = ast_cli_generator(text, word, matches)) != NULL) { 02293 if (matches + 1 >= match_list_len) { 02294 match_list_len <<= 1; 02295 if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(*match_list)))) 02296 return NULL; 02297 } 02298 match_list[++matches] = retstr; 02299 } 02300 02301 if (!match_list) 02302 return match_list; /* NULL */ 02303 02304 /* Find the longest substring that is common to all results 02305 * (it is a candidate for completion), and store a copy in entry 0. 02306 */ 02307 prevstr = match_list[1]; 02308 max_equal = strlen(prevstr); 02309 for (which = 2; which <= matches; which++) { 02310 for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++) 02311 continue; 02312 max_equal = i; 02313 } 02314 02315 if (!(retstr = ast_malloc(max_equal + 1))) 02316 return NULL; 02317 02318 ast_copy_string(retstr, match_list[1], max_equal + 1); 02319 match_list[0] = retstr; 02320 02321 /* ensure that the array is NULL terminated */ 02322 if (matches + 1 >= match_list_len) { 02323 if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list)))) 02324 return NULL; 02325 } 02326 match_list[matches + 1] = NULL; 02327 02328 return match_list; 02329 }
char* ast_cli_generator | ( | const char * | , | |
const char * | , | |||
int | ||||
) |
Readline madness Useful for readline, that's about it.
0 | on success | |
-1 | on failure |
Definition at line 2428 of file cli.c.
References __ast_cli_generator().
Referenced by ast_cli_completion_matches(), ast_cli_generatornummatches(), cli_alias_passthrough(), and handle_cli_check_permissions().
02429 { 02430 return __ast_cli_generator(text, word, state, 1); 02431 }
int ast_cli_generatornummatches | ( | const char * | text, | |
const char * | word | |||
) |
Return the number of unique matches for the generator.
Definition at line 2267 of file cli.c.
References ast_cli_generator(), and ast_free.
Referenced by handle_commandnummatches().
02268 { 02269 int matches = 0, i = 0; 02270 char *buf = NULL, *oldbuf = NULL; 02271 02272 while ((buf = ast_cli_generator(text, word, i++))) { 02273 if (!oldbuf || strcmp(buf,oldbuf)) 02274 matches++; 02275 if (oldbuf) 02276 ast_free(oldbuf); 02277 oldbuf = buf; 02278 } 02279 if (oldbuf) 02280 ast_free(oldbuf); 02281 return matches; 02282 }
int ast_cli_perms_init | ( | int | reload | ) |
Provided by cli.c
Definition at line 1730 of file cli.c.
References ast_calloc, ast_category_browse(), ast_config_load2(), ast_free, AST_LIST_TRAVERSE, ast_log(), ast_mutex_trylock, ast_mutex_unlock, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_strlen_zero(), ast_variable_browse(), CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEUNCHANGED, destroy_user_perms(), usergroup_cli_perm::gid, cli_perm::list, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, perms_config, usergroup_cli_perm::uid, and ast_variable::value.
Referenced by handle_cli_reload_permissions(), and main().
01731 { 01732 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 01733 struct ast_config *cfg; 01734 char *cat = NULL; 01735 struct ast_variable *v; 01736 struct usergroup_cli_perm *user_group, *cp_entry; 01737 struct cli_perm *perm = NULL; 01738 struct passwd *pw; 01739 struct group *gr; 01740 01741 if (ast_mutex_trylock(&permsconfiglock)) { 01742 ast_log(LOG_NOTICE, "You must wait until last 'cli reload permissions' command finish\n"); 01743 return 1; 01744 } 01745 01746 cfg = ast_config_load2(perms_config, "" /* core, can't reload */, config_flags); 01747 if (!cfg) { 01748 ast_mutex_unlock(&permsconfiglock); 01749 return 1; 01750 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 01751 ast_mutex_unlock(&permsconfiglock); 01752 return 0; 01753 } 01754 01755 /* free current structures. */ 01756 destroy_user_perms(); 01757 01758 while ((cat = ast_category_browse(cfg, cat))) { 01759 if (!strcasecmp(cat, "general")) { 01760 /* General options */ 01761 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 01762 if (!strcasecmp(v->name, "default_perm")) { 01763 cli_default_perm = (!strcasecmp(v->value, "permit")) ? 1: 0; 01764 } 01765 } 01766 continue; 01767 } 01768 01769 /* users or groups */ 01770 gr = NULL, pw = NULL; 01771 if (cat[0] == '@') { 01772 /* This is a group */ 01773 gr = getgrnam(&cat[1]); 01774 if (!gr) { 01775 ast_log (LOG_WARNING, "Unknown group '%s'\n", &cat[1]); 01776 continue; 01777 } 01778 } else { 01779 /* This is a user */ 01780 pw = getpwnam(cat); 01781 if (!pw) { 01782 ast_log (LOG_WARNING, "Unknown user '%s'\n", cat); 01783 continue; 01784 } 01785 } 01786 user_group = NULL; 01787 /* Check for duplicates */ 01788 AST_RWLIST_WRLOCK(&cli_perms); 01789 AST_LIST_TRAVERSE(&cli_perms, cp_entry, list) { 01790 if ((pw && cp_entry->uid == pw->pw_uid) || (gr && cp_entry->gid == gr->gr_gid)) { 01791 /* if it is duplicated, just added this new settings, to 01792 the current list. */ 01793 user_group = cp_entry; 01794 break; 01795 } 01796 } 01797 AST_RWLIST_UNLOCK(&cli_perms); 01798 01799 if (!user_group) { 01800 /* alloc space for the new user config. */ 01801 user_group = ast_calloc(1, sizeof(*user_group)); 01802 if (!user_group) { 01803 continue; 01804 } 01805 user_group->uid = (pw ? pw->pw_uid : -1); 01806 user_group->gid = (gr ? gr->gr_gid : -1); 01807 user_group->perms = ast_calloc(1, sizeof(*user_group->perms)); 01808 if (!user_group->perms) { 01809 ast_free(user_group); 01810 continue; 01811 } 01812 } 01813 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 01814 if (ast_strlen_zero(v->value)) { 01815 /* we need to check this condition cause it could break security. */ 01816 ast_log(LOG_WARNING, "Empty permit/deny option in user '%s'\n", cat); 01817 continue; 01818 } 01819 if (!strcasecmp(v->name, "permit")) { 01820 perm = ast_calloc(1, sizeof(*perm)); 01821 if (perm) { 01822 perm->permit = 1; 01823 perm->command = ast_strdup(v->value); 01824 } 01825 } else if (!strcasecmp(v->name, "deny")) { 01826 perm = ast_calloc(1, sizeof(*perm)); 01827 if (perm) { 01828 perm->permit = 0; 01829 perm->command = ast_strdup(v->value); 01830 } 01831 } else { 01832 /* up to now, only 'permit' and 'deny' are possible values. */ 01833 ast_log(LOG_WARNING, "Unknown '%s' option\n", v->name); 01834 continue; 01835 } 01836 if (perm) { 01837 /* Added the permission to the user's list. */ 01838 AST_LIST_INSERT_TAIL(user_group->perms, perm, list); 01839 perm = NULL; 01840 } 01841 } 01842 AST_RWLIST_WRLOCK(&cli_perms); 01843 AST_RWLIST_INSERT_TAIL(&cli_perms, user_group, list); 01844 AST_RWLIST_UNLOCK(&cli_perms); 01845 } 01846 01847 ast_config_destroy(cfg); 01848 ast_mutex_unlock(&permsconfiglock); 01849 return 0; 01850 }
int ast_cli_register | ( | struct ast_cli_entry * | e | ) |
Registers a command or an array of commands.
e | which cli entry to register. Register your own command |
0 | on success | |
-1 | on failure |
Definition at line 2094 of file cli.c.
References __ast_cli_register().
Referenced by ast_cdr_engine_init(), ast_cel_engine_init(), ast_cli_register_multiple(), dnsmgr_init(), do_reload(), and load_module().
02095 { 02096 return __ast_cli_register(e, NULL); 02097 }
int ast_cli_register_multiple | ( | struct ast_cli_entry * | e, | |
int | len | |||
) |
Register multiple commands.
e | pointer to first cli entry to register | |
len | number of entries to register |
Definition at line 2102 of file cli.c.
References ast_cli_register().
Referenced by __ast_register_translator(), __init_manager(), ast_ais_clm_load_module(), ast_ais_evt_load_module(), ast_aoc_cli_init(), ast_builtins_init(), ast_cc_init(), ast_channels_init(), ast_data_init(), ast_event_init(), ast_features_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_stun_init(), ast_test_init(), ast_timing_init(), ast_tps_init(), ast_udptl_init(), ast_utils_init(), astdb_init(), astobj2_init(), crypto_init(), iax_provision_init(), init_framer(), init_logger(), load_module(), load_pbx(), main(), and register_config_cli().
02103 { 02104 int i, res = 0; 02105 02106 for (i = 0; i < len; i++) 02107 res |= ast_cli_register(e + i); 02108 02109 return res; 02110 }
int ast_cli_unregister | ( | struct ast_cli_entry * | e | ) |
Unregisters a command or an array of commands.
e | which cli entry to unregister Unregister your own command. You must pass a completed ast_cli_entry structure |
Definition at line 2088 of file cli.c.
References __ast_cli_unregister().
Referenced by alias_destroy(), ast_cli_unregister_multiple(), do_reload(), load_module(), and unload_module().
02089 { 02090 return __ast_cli_unregister(e, NULL); 02091 }
int ast_cli_unregister_multiple | ( | struct ast_cli_entry * | e, | |
int | len | |||
) |
Unregister multiple commands.
e | pointer to first cli entry to unregister | |
len | number of entries to unregister |
Definition at line 2112 of file cli.c.
References ast_cli_unregister().
Referenced by __unload_module(), ast_ais_clm_unload_module(), iax_provision_unload(), load_module(), and unload_module().
02113 { 02114 int i, res = 0; 02115 02116 for (i = 0; i < len; i++) 02117 res |= ast_cli_unregister(e + i); 02118 02119 return res; 02120 }
char* ast_complete_channels | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
int | rpos | |||
) |
Command completion for the list of active channels.
This can be called from a CLI command completion function that wants to complete from the list of active channels. 'rpos' is the required position in the command. This function will return NULL immediately if 'rpos' is not the same as the current position, 'pos'.
Definition at line 1525 of file cli.c.
References ast_channel_iterator_all_new(), ast_channel_iterator_by_name_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_strdup, ast_strlen_zero(), and state::name.
Referenced by complete_ch(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_core_set_debug_channel(), handle_redirect(), handle_set_chanvar(), handle_show_chanvar(), handle_showchan(), and handle_softhangup().
01526 { 01527 struct ast_channel *c = NULL; 01528 int which = 0; 01529 char notfound = '\0'; 01530 char *ret = ¬found; /* so NULL can break the loop */ 01531 struct ast_channel_iterator *iter; 01532 01533 if (pos != rpos) { 01534 return NULL; 01535 } 01536 01537 if (ast_strlen_zero(word)) { 01538 iter = ast_channel_iterator_all_new(); 01539 } else { 01540 iter = ast_channel_iterator_by_name_new(word, strlen(word)); 01541 } 01542 01543 if (!iter) { 01544 return NULL; 01545 } 01546 01547 while (ret == ¬found && (c = ast_channel_iterator_next(iter))) { 01548 if (++which > state) { 01549 ast_channel_lock(c); 01550 ret = ast_strdup(c->name); 01551 ast_channel_unlock(c); 01552 } 01553 ast_channel_unref(c); 01554 } 01555 01556 ast_channel_iterator_destroy(iter); 01557 01558 return ret == ¬found ? NULL : ret; 01559 }
unsigned int ast_debug_get_by_module | ( | const char * | module | ) |
Get the debug level for a module.
module | the name of module |
Definition at line 119 of file cli.c.
References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, module_level::entry, module_level::level, and module_level::module.
00120 { 00121 struct module_level *ml; 00122 unsigned int res = 0; 00123 00124 AST_RWLIST_RDLOCK(&debug_modules); 00125 AST_LIST_TRAVERSE(&debug_modules, ml, entry) { 00126 if (!strcasecmp(ml->module, module)) { 00127 res = ml->level; 00128 break; 00129 } 00130 } 00131 AST_RWLIST_UNLOCK(&debug_modules); 00132 00133 return res; 00134 }
unsigned int ast_verbose_get_by_module | ( | const char * | module | ) |
Get the verbose level for a module.
module | the name of module |
Definition at line 136 of file cli.c.
References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, module_level::entry, module_level::level, and module_level::module.
00137 { 00138 struct module_level *ml; 00139 unsigned int res = 0; 00140 00141 AST_RWLIST_RDLOCK(&verbose_modules); 00142 AST_LIST_TRAVERSE(&verbose_modules, ml, entry) { 00143 if (!strcasecmp(ml->module, module)) { 00144 res = ml->level; 00145 break; 00146 } 00147 } 00148 AST_RWLIST_UNLOCK(&verbose_modules); 00149 00150 return res; 00151 }
static int channel_set_debug | ( | void * | obj, | |
void * | arg, | |||
void * | data, | |||
int | flags | |||
) | [static] |
Definition at line 1276 of file cli.c.
References args, ast_channel_lock, ast_channel_unlock, ast_cli(), DEBUGCHAN_FLAG, ast_channel::fin, ast_channel::fout, and ast_channel::name.
Referenced by handle_core_set_debug_channel().
01277 { 01278 struct ast_channel *chan = obj; 01279 struct channel_set_debug_args *args = data; 01280 01281 ast_channel_lock(chan); 01282 01283 if (!(chan->fin & DEBUGCHAN_FLAG) || !(chan->fout & DEBUGCHAN_FLAG)) { 01284 if (args->is_off) { 01285 chan->fin &= ~DEBUGCHAN_FLAG; 01286 chan->fout &= ~DEBUGCHAN_FLAG; 01287 } else { 01288 chan->fin |= DEBUGCHAN_FLAG; 01289 chan->fout |= DEBUGCHAN_FLAG; 01290 } 01291 ast_cli(args->fd, "Debugging %s on channel %s\n", args->is_off ? "disabled" : "enabled", 01292 chan->name); 01293 } 01294 01295 ast_channel_unlock(chan); 01296 01297 return 0; 01298 }
static int cli_has_permissions | ( | int | uid, | |
int | gid, | |||
const char * | command | |||
) | [static] |
Definition at line 166 of file cli.c.
References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_NO_PERMS, cli_perm::command, usergroup_cli_perm::gid, cli_perm::list, cli_perm::permit, usergroup_cli_perm::perms, and usergroup_cli_perm::uid.
Referenced by ast_cli_command_full(), and handle_cli_check_permissions().
00167 { 00168 struct usergroup_cli_perm *user_perm; 00169 struct cli_perm *perm; 00170 /* set to the default permissions general option. */ 00171 int isallowg = cli_default_perm, isallowu = -1, ispattern; 00172 regex_t regexbuf; 00173 00174 /* if uid == -1 or gid == -1 do not check permissions. 00175 if uid == -2 and gid == -2 is because rasterisk client didn't send 00176 the credentials, so the cli_default_perm will be applied. */ 00177 if ((uid == CLI_NO_PERMS && gid == CLI_NO_PERMS) || command[0] == '_') { 00178 return 1; 00179 } 00180 00181 if (gid < 0 && uid < 0) { 00182 return cli_default_perm; 00183 } 00184 00185 AST_RWLIST_RDLOCK(&cli_perms); 00186 AST_LIST_TRAVERSE(&cli_perms, user_perm, list) { 00187 if (user_perm->gid != gid && user_perm->uid != uid) { 00188 continue; 00189 } 00190 AST_LIST_TRAVERSE(user_perm->perms, perm, list) { 00191 if (strcasecmp(perm->command, "all") && strncasecmp(perm->command, command, strlen(perm->command))) { 00192 /* if the perm->command is a pattern, check it against command. */ 00193 ispattern = !regcomp(®exbuf, perm->command, REG_EXTENDED | REG_NOSUB | REG_ICASE); 00194 if (ispattern && regexec(®exbuf, command, 0, NULL, 0)) { 00195 regfree(®exbuf); 00196 continue; 00197 } 00198 if (!ispattern) { 00199 continue; 00200 } 00201 regfree(®exbuf); 00202 } 00203 if (user_perm->uid == uid) { 00204 /* this is a user definition. */ 00205 isallowu = perm->permit; 00206 } else { 00207 /* otherwise is a group definition. */ 00208 isallowg = perm->permit; 00209 } 00210 } 00211 } 00212 AST_RWLIST_UNLOCK(&cli_perms); 00213 if (isallowu > -1) { 00214 /* user definition override group definition. */ 00215 isallowg = isallowu; 00216 } 00217 00218 return isallowg; 00219 }
static struct ast_cli_entry* cli_next | ( | struct ast_cli_entry * | e | ) | [static] |
Definition at line 708 of file cli.c.
References AST_LIST_FIRST, AST_LIST_NEXT, and cli_perm::list.
Referenced by __ast_cli_generator(), find_cli(), handle_cli_check_permissions(), and help1().
00709 { 00710 if (e) { 00711 return AST_LIST_NEXT(e, list); 00712 } else { 00713 return AST_LIST_FIRST(&helpers); 00714 } 00715 }
static char* complete_fn | ( | const char * | word, | |
int | state | |||
) | [static] |
Definition at line 223 of file cli.c.
References ast_config_AST_MODULE_DIR, ast_copy_string(), ast_strdup, and free.
Referenced by handle_load().
00224 { 00225 char *c, *d; 00226 char filename[PATH_MAX]; 00227 00228 if (word[0] == '/') 00229 ast_copy_string(filename, word, sizeof(filename)); 00230 else 00231 snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word); 00232 00233 c = d = filename_completion_function(filename, state); 00234 00235 if (c && word[0] != '/') 00236 c += (strlen(ast_config_AST_MODULE_DIR) + 1); 00237 if (c) 00238 c = ast_strdup(c); 00239 00240 free(d); 00241 00242 return c; 00243 }
static char* complete_number | ( | const char * | partial, | |
unsigned int | min, | |||
unsigned int | max, | |||
int | n | |||
) | [static] |
Definition at line 345 of file cli.c.
References ast_strdup, ast_strlen_zero(), and cli_perm::next.
Referenced by handle_verbose().
00346 { 00347 int i, count = 0; 00348 unsigned int prospective[2]; 00349 unsigned int part = strtoul(partial, NULL, 10); 00350 char next[12]; 00351 00352 if (part < min || part > max) { 00353 return NULL; 00354 } 00355 00356 for (i = 0; i < 21; i++) { 00357 if (i == 0) { 00358 prospective[0] = prospective[1] = part; 00359 } else if (part == 0 && !ast_strlen_zero(partial)) { 00360 break; 00361 } else if (i < 11) { 00362 prospective[0] = prospective[1] = part * 10 + (i - 1); 00363 } else { 00364 prospective[0] = (part * 10 + (i - 11)) * 10; 00365 prospective[1] = prospective[0] + 9; 00366 } 00367 if (i < 11 && (prospective[0] < min || prospective[0] > max)) { 00368 continue; 00369 } else if (prospective[1] < min || prospective[0] > max) { 00370 continue; 00371 } 00372 00373 if (++count > n) { 00374 if (i < 11) { 00375 snprintf(next, sizeof(next), "%u", prospective[0]); 00376 } else { 00377 snprintf(next, sizeof(next), "%u...", prospective[0] / 10); 00378 } 00379 return ast_strdup(next); 00380 } 00381 } 00382 return NULL; 00383 }
static void destroy_user_perms | ( | void | ) | [static] |
cleanup (free) cli_perms linkedlist.
Definition at line 1714 of file cli.c.
References ast_free, AST_LIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cli_perm::command, cli_perm::list, and usergroup_cli_perm::perms.
Referenced by ast_cli_perms_init().
01715 { 01716 struct cli_perm *perm; 01717 struct usergroup_cli_perm *user_perm; 01718 01719 AST_RWLIST_WRLOCK(&cli_perms); 01720 while ((user_perm = AST_LIST_REMOVE_HEAD(&cli_perms, list))) { 01721 while ((perm = AST_LIST_REMOVE_HEAD(user_perm->perms, list))) { 01722 ast_free(perm->command); 01723 ast_free(perm); 01724 } 01725 ast_free(user_perm); 01726 } 01727 AST_RWLIST_UNLOCK(&cli_perms); 01728 }
static char* find_best | ( | const char * | argv[] | ) | [static] |
Definition at line 1992 of file cli.c.
References ast_join(), AST_MAX_CMD_LEN, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and find_cli().
01993 { 01994 static char cmdline[80]; 01995 int x; 01996 /* See how close we get, then print the candidate */ 01997 const char *myargv[AST_MAX_CMD_LEN] = { NULL, }; 01998 01999 AST_RWLIST_RDLOCK(&helpers); 02000 for (x = 0; argv[x]; x++) { 02001 myargv[x] = argv[x]; 02002 if (!find_cli(myargv, -1)) 02003 break; 02004 } 02005 AST_RWLIST_UNLOCK(&helpers); 02006 ast_join(cmdline, sizeof(cmdline), myargv); 02007 return cmdline; 02008 }
static struct ast_cli_entry* find_cli | ( | const char *const | cmds[], | |
int | match_type | |||
) | [static] |
Definition at line 1948 of file cli.c.
References ast_strlen_zero(), cli_next(), ast_cli_entry::cmda, and word_match().
Referenced by __ast_cli_register(), ast_cli_command_full(), find_best(), and handle_help().
01949 { 01950 int matchlen = -1; /* length of longest match so far */ 01951 struct ast_cli_entry *cand = NULL, *e=NULL; 01952 01953 while ( (e = cli_next(e)) ) { 01954 /* word-by word regexp comparison */ 01955 const char * const *src = cmds; 01956 const char * const *dst = e->cmda; 01957 int n = 0; 01958 for (;; dst++, src += n) { 01959 n = word_match(*src, *dst); 01960 if (n < 0) 01961 break; 01962 } 01963 if (ast_strlen_zero(*dst) || ((*dst)[0] == '[' && ast_strlen_zero(dst[1]))) { 01964 /* no more words in 'e' */ 01965 if (ast_strlen_zero(*src)) /* exact match, cannot do better */ 01966 break; 01967 /* Here, cmds has more words than the entry 'e' */ 01968 if (match_type != 0) /* but we look for almost exact match... */ 01969 continue; /* so we skip this one. */ 01970 /* otherwise we like it (case 0) */ 01971 } else { /* still words in 'e' */ 01972 if (ast_strlen_zero(*src)) 01973 continue; /* cmds is shorter than 'e', not good */ 01974 /* Here we have leftover words in cmds and 'e', 01975 * but there is a mismatch. We only accept this one if match_type == -1 01976 * and this is the last word for both. 01977 */ 01978 if (match_type != -1 || !ast_strlen_zero(src[1]) || 01979 !ast_strlen_zero(dst[1])) /* not the one we look for */ 01980 continue; 01981 /* good, we are in case match_type == -1 and mismatch on last word */ 01982 } 01983 if (src - cmds > matchlen) { /* remember the candidate */ 01984 matchlen = src - cmds; 01985 cand = e; 01986 } 01987 } 01988 01989 return e ? e : cand; 01990 }
static struct module_level* find_module_level | ( | const char * | module, | |
unsigned int | debug | |||
) | [static] |
Find the debug or verbose file setting.
Definition at line 332 of file cli.c.
References AST_LIST_TRAVERSE, and module_level::module.
Referenced by handle_verbose().
00333 { 00334 struct module_level *ml; 00335 struct module_level_list *mll = debug ? &debug_modules : &verbose_modules; 00336 00337 AST_LIST_TRAVERSE(mll, ml, entry) { 00338 if (!strcasecmp(ml->module, module)) 00339 return ml; 00340 } 00341 00342 return NULL; 00343 }
static char* group_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1561 of file cli.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_app_group_list_head(), ast_app_group_list_rdlock(), ast_app_group_list_unlock(), ast_cli(), AST_LIST_NEXT, ast_strlen_zero(), ast_group_info::category, ast_group_info::chan, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ESS, ast_cli_args::fd, FORMAT_STRING, ast_group_info::group, ast_group_info::group_list, ast_channel::name, and ast_cli_entry::usage.
01562 { 01563 #define FORMAT_STRING "%-25s %-20s %-20s\n" 01564 01565 struct ast_group_info *gi = NULL; 01566 int numchans = 0; 01567 regex_t regexbuf; 01568 int havepattern = 0; 01569 01570 switch (cmd) { 01571 case CLI_INIT: 01572 e->command = "group show channels"; 01573 e->usage = 01574 "Usage: group show channels [pattern]\n" 01575 " Lists all currently active channels with channel group(s) specified.\n" 01576 " Optional regular expression pattern is matched to group names for each\n" 01577 " channel.\n"; 01578 return NULL; 01579 case CLI_GENERATE: 01580 return NULL; 01581 } 01582 01583 if (a->argc < 3 || a->argc > 4) 01584 return CLI_SHOWUSAGE; 01585 01586 if (a->argc == 4) { 01587 if (regcomp(®exbuf, a->argv[3], REG_EXTENDED | REG_NOSUB)) 01588 return CLI_SHOWUSAGE; 01589 havepattern = 1; 01590 } 01591 01592 ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category"); 01593 01594 ast_app_group_list_rdlock(); 01595 01596 gi = ast_app_group_list_head(); 01597 while (gi) { 01598 if (!havepattern || !regexec(®exbuf, gi->group, 0, NULL, 0)) { 01599 ast_cli(a->fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category)); 01600 numchans++; 01601 } 01602 gi = AST_LIST_NEXT(gi, group_list); 01603 } 01604 01605 ast_app_group_list_unlock(); 01606 01607 if (havepattern) 01608 regfree(®exbuf); 01609 01610 ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans)); 01611 return CLI_SUCCESS; 01612 #undef FORMAT_STRING 01613 }
static char* handle_chanlist | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 842 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_active_channels(), ast_bridged_channel(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_processed_calls(), ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, CONCISE_FORMAT_STRING, ESS, ast_cli_args::fd, FORMAT_STRING, FORMAT_STRING2, option_maxcalls, S_COR, S_OR, ast_cli_entry::usage, VERBOSE_FORMAT_STRING, and VERBOSE_FORMAT_STRING2.
00843 { 00844 #define FORMAT_STRING "%-20.20s %-20.20s %-7.7s %-30.30s\n" 00845 #define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n" 00846 #define CONCISE_FORMAT_STRING "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n" 00847 #define VERBOSE_FORMAT_STRING "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n" 00848 #define VERBOSE_FORMAT_STRING2 "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n" 00849 00850 struct ast_channel *c = NULL; 00851 int numchans = 0, concise = 0, verbose = 0, count = 0; 00852 struct ast_channel_iterator *iter = NULL; 00853 00854 switch (cmd) { 00855 case CLI_INIT: 00856 e->command = "core show channels [concise|verbose|count]"; 00857 e->usage = 00858 "Usage: core show channels [concise|verbose|count]\n" 00859 " Lists currently defined channels and some information about them. If\n" 00860 " 'concise' is specified, the format is abridged and in a more easily\n" 00861 " machine parsable format. If 'verbose' is specified, the output includes\n" 00862 " more and longer fields. If 'count' is specified only the channel and call\n" 00863 " count is output.\n" 00864 " The 'concise' option is deprecated and will be removed from future versions\n" 00865 " of Asterisk.\n"; 00866 return NULL; 00867 00868 case CLI_GENERATE: 00869 return NULL; 00870 } 00871 00872 if (a->argc == e->args) { 00873 if (!strcasecmp(a->argv[e->args-1],"concise")) 00874 concise = 1; 00875 else if (!strcasecmp(a->argv[e->args-1],"verbose")) 00876 verbose = 1; 00877 else if (!strcasecmp(a->argv[e->args-1],"count")) 00878 count = 1; 00879 else 00880 return CLI_SHOWUSAGE; 00881 } else if (a->argc != e->args - 1) 00882 return CLI_SHOWUSAGE; 00883 00884 if (!count) { 00885 if (!concise && !verbose) 00886 ast_cli(a->fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)"); 00887 else if (verbose) 00888 ast_cli(a->fd, VERBOSE_FORMAT_STRING2, "Channel", "Context", "Extension", "Priority", "State", "Application", "Data", 00889 "CallerID", "Duration", "Accountcode", "PeerAccount", "BridgedTo"); 00890 } 00891 00892 if (!count && !(iter = ast_channel_iterator_all_new())) { 00893 return CLI_FAILURE; 00894 } 00895 00896 for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { 00897 struct ast_channel *bc; 00898 char durbuf[10] = "-"; 00899 00900 ast_channel_lock(c); 00901 00902 bc = ast_bridged_channel(c); 00903 00904 if (!count) { 00905 if ((concise || verbose) && c->cdr && !ast_tvzero(c->cdr->start)) { 00906 int duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 00907 if (verbose) { 00908 int durh = duration / 3600; 00909 int durm = (duration % 3600) / 60; 00910 int durs = duration % 60; 00911 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 00912 } else { 00913 snprintf(durbuf, sizeof(durbuf), "%d", duration); 00914 } 00915 } 00916 if (concise) { 00917 ast_cli(a->fd, CONCISE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state), 00918 c->appl ? c->appl : "(None)", 00919 S_OR(c->data, ""), /* XXX different from verbose ? */ 00920 S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""), 00921 S_OR(c->accountcode, ""), 00922 S_OR(c->peeraccount, ""), 00923 c->amaflags, 00924 durbuf, 00925 bc ? bc->name : "(None)", 00926 c->uniqueid); 00927 } else if (verbose) { 00928 ast_cli(a->fd, VERBOSE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state), 00929 c->appl ? c->appl : "(None)", 00930 c->data ? S_OR(c->data, "(Empty)" ): "(None)", 00931 S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""), 00932 durbuf, 00933 S_OR(c->accountcode, ""), 00934 S_OR(c->peeraccount, ""), 00935 bc ? bc->name : "(None)"); 00936 } else { 00937 char locbuf[40] = "(None)"; 00938 char appdata[40] = "(None)"; 00939 00940 if (!ast_strlen_zero(c->context) && !ast_strlen_zero(c->exten)) 00941 snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority); 00942 if (c->appl) 00943 snprintf(appdata, sizeof(appdata), "%s(%s)", c->appl, S_OR(c->data, "")); 00944 ast_cli(a->fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata); 00945 } 00946 } 00947 ast_channel_unlock(c); 00948 } 00949 00950 if (iter) { 00951 ast_channel_iterator_destroy(iter); 00952 } 00953 00954 if (!concise) { 00955 numchans = ast_active_channels(); 00956 ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans)); 00957 if (option_maxcalls) 00958 ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n", 00959 ast_active_calls(), option_maxcalls, ESS(ast_active_calls()), 00960 ((double)ast_active_calls() / (double)option_maxcalls) * 100.0); 00961 else 00962 ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls())); 00963 00964 ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls())); 00965 } 00966 00967 return CLI_SUCCESS; 00968 00969 #undef FORMAT_STRING 00970 #undef FORMAT_STRING2 00971 #undef CONCISE_FORMAT_STRING 00972 #undef VERBOSE_FORMAT_STRING 00973 #undef VERBOSE_FORMAT_STRING2 00974 }
static char* handle_cli_check_permissions | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
handles CLI command 'cli check permissions'
Definition at line 1088 of file cli.c.
References ast_cli_entry::_full_cmd, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_generator(), ast_join(), AST_MAX_ARGS, ast_strdupa, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, cli_has_permissions(), CLI_INIT, cli_next(), CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, cli_perm::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, S_OR, ast_cli_entry::summary, ast_cli_entry::usage, and ast_cli_args::word.
01089 { 01090 struct passwd *pw = NULL; 01091 struct group *gr; 01092 int gid = -1, uid = -1; 01093 char command[AST_MAX_ARGS] = ""; 01094 struct ast_cli_entry *ce = NULL; 01095 int found = 0; 01096 char *group, *tmp; 01097 01098 switch (cmd) { 01099 case CLI_INIT: 01100 e->command = "cli check permissions"; 01101 e->usage = 01102 "Usage: cli check permissions {<username>|@<groupname>|<username>@<groupname>} [<command>]\n" 01103 " Check permissions config for a user@group or list the allowed commands for the specified user.\n" 01104 " The username or the groupname may be omitted.\n"; 01105 return NULL; 01106 case CLI_GENERATE: 01107 if (a->pos >= 4) { 01108 return ast_cli_generator(a->line + strlen("cli check permissions") + strlen(a->argv[3]) + 1, a->word, a->n); 01109 } 01110 return NULL; 01111 } 01112 01113 if (a->argc < 4) { 01114 return CLI_SHOWUSAGE; 01115 } 01116 01117 tmp = ast_strdupa(a->argv[3]); 01118 group = strchr(tmp, '@'); 01119 if (group) { 01120 gr = getgrnam(&group[1]); 01121 if (!gr) { 01122 ast_cli(a->fd, "Unknown group '%s'\n", &group[1]); 01123 return CLI_FAILURE; 01124 } 01125 group[0] = '\0'; 01126 gid = gr->gr_gid; 01127 } 01128 01129 if (!group && ast_strlen_zero(tmp)) { 01130 ast_cli(a->fd, "You didn't supply a username\n"); 01131 } else if (!ast_strlen_zero(tmp) && !(pw = getpwnam(tmp))) { 01132 ast_cli(a->fd, "Unknown user '%s'\n", tmp); 01133 return CLI_FAILURE; 01134 } else if (pw) { 01135 uid = pw->pw_uid; 01136 } 01137 01138 if (a->argc == 4) { 01139 while ((ce = cli_next(ce))) { 01140 /* Hide commands that start with '_' */ 01141 if (ce->_full_cmd[0] == '_') { 01142 continue; 01143 } 01144 if (cli_has_permissions(uid, gid, ce->_full_cmd)) { 01145 ast_cli(a->fd, "%30.30s %s\n", ce->_full_cmd, S_OR(ce->summary, "<no description available>")); 01146 found++; 01147 } 01148 } 01149 if (!found) { 01150 ast_cli(a->fd, "You are not allowed to run any command on Asterisk\n"); 01151 } 01152 } else { 01153 ast_join(command, sizeof(command), a->argv + 4); 01154 ast_cli(a->fd, "%s '%s%s%s' is %s to run command: '%s'\n", uid >= 0 ? "User" : "Group", tmp, 01155 group && uid >= 0 ? "@" : "", 01156 group ? &group[1] : "", 01157 cli_has_permissions(uid, gid, command) ? "allowed" : "not allowed", command); 01158 } 01159 01160 return CLI_SUCCESS; 01161 }
static char* handle_cli_reload_permissions | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
handles CLI command 'cli reload permissions'
Definition at line 1069 of file cli.c.
References ast_cli_perms_init(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
01070 { 01071 switch (cmd) { 01072 case CLI_INIT: 01073 e->command = "cli reload permissions"; 01074 e->usage = 01075 "Usage: cli reload permissions\n" 01076 " Reload the 'cli_permissions.conf' file.\n"; 01077 return NULL; 01078 case CLI_GENERATE: 01079 return NULL; 01080 } 01081 01082 ast_cli_perms_init(1); 01083 01084 return CLI_SUCCESS; 01085 }
static char* handle_cli_show_permissions | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
handles CLI command 'cli show permissions'
Definition at line 1024 of file cli.c.
References ast_cli(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, cli_perm::command, ast_cli_entry::command, ast_cli_args::fd, usergroup_cli_perm::gid, cli_perm::list, cli_perm::permit, usergroup_cli_perm::perms, usergroup_cli_perm::uid, and ast_cli_entry::usage.
01025 { 01026 struct usergroup_cli_perm *cp; 01027 struct cli_perm *perm; 01028 struct passwd *pw = NULL; 01029 struct group *gr = NULL; 01030 01031 switch (cmd) { 01032 case CLI_INIT: 01033 e->command = "cli show permissions"; 01034 e->usage = 01035 "Usage: cli show permissions\n" 01036 " Shows CLI configured permissions.\n"; 01037 return NULL; 01038 case CLI_GENERATE: 01039 return NULL; 01040 } 01041 01042 AST_RWLIST_RDLOCK(&cli_perms); 01043 AST_LIST_TRAVERSE(&cli_perms, cp, list) { 01044 if (cp->uid >= 0) { 01045 pw = getpwuid(cp->uid); 01046 if (pw) { 01047 ast_cli(a->fd, "user: %s [uid=%d]\n", pw->pw_name, cp->uid); 01048 } 01049 } else { 01050 gr = getgrgid(cp->gid); 01051 if (gr) { 01052 ast_cli(a->fd, "group: %s [gid=%d]\n", gr->gr_name, cp->gid); 01053 } 01054 } 01055 ast_cli(a->fd, "Permissions:\n"); 01056 if (cp->perms) { 01057 AST_LIST_TRAVERSE(cp->perms, perm, list) { 01058 ast_cli(a->fd, "\t%s -> %s\n", perm->permit ? "permit" : "deny", perm->command); 01059 } 01060 } 01061 ast_cli(a->fd, "\n"); 01062 } 01063 AST_RWLIST_UNLOCK(&cli_perms); 01064 01065 return CLI_SUCCESS; 01066 }
static char* handle_cli_wait_fullybooted | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1615 of file cli.c.
References ast_cli(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
01616 { 01617 switch (cmd) { 01618 case CLI_INIT: 01619 e->command = "core waitfullybooted"; 01620 e->usage = 01621 "Usage: core waitfullybooted\n" 01622 " Wait until Asterisk has fully booted.\n"; 01623 return NULL; 01624 case CLI_GENERATE: 01625 return NULL; 01626 } 01627 01628 while (!ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) { 01629 usleep(100); 01630 } 01631 01632 ast_cli(a->fd, "Asterisk has fully booted.\n"); 01633 01634 return CLI_SUCCESS; 01635 }
static char* handle_commandcomplete | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1246 of file cli.c.
References __ast_cli_generator(), ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_free, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
01247 { 01248 char *buf; 01249 switch (cmd) { 01250 case CLI_INIT: 01251 e->command = "_command complete"; 01252 e->usage = 01253 "Usage: _command complete \"<line>\" text state\n" 01254 " This function is used internally to help with command completion and should.\n" 01255 " never be called by the user directly.\n"; 01256 return NULL; 01257 case CLI_GENERATE: 01258 return NULL; 01259 } 01260 if (a->argc != 5) 01261 return CLI_SHOWUSAGE; 01262 buf = __ast_cli_generator(a->argv[2], a->argv[3], atoi(a->argv[4]), 0); 01263 if (buf) { 01264 ast_cli(a->fd, "%s", buf); 01265 ast_free(buf); 01266 } else 01267 ast_cli(a->fd, "NULL\n"); 01268 return CLI_SUCCESS; 01269 }
static char* handle_commandmatchesarray | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1165 of file cli.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_COMPLETE_EOF, ast_cli_completion_matches(), ast_free, ast_malloc, ast_realloc, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, len(), and ast_cli_entry::usage.
01166 { 01167 char *buf, *obuf; 01168 int buflen = 2048; 01169 int len = 0; 01170 char **matches; 01171 int x, matchlen; 01172 01173 switch (cmd) { 01174 case CLI_INIT: 01175 e->command = "_command matchesarray"; 01176 e->usage = 01177 "Usage: _command matchesarray \"<line>\" text \n" 01178 " This function is used internally to help with command completion and should.\n" 01179 " never be called by the user directly.\n"; 01180 return NULL; 01181 case CLI_GENERATE: 01182 return NULL; 01183 } 01184 01185 if (a->argc != 4) 01186 return CLI_SHOWUSAGE; 01187 if (!(buf = ast_malloc(buflen))) 01188 return CLI_FAILURE; 01189 buf[len] = '\0'; 01190 matches = ast_cli_completion_matches(a->argv[2], a->argv[3]); 01191 if (matches) { 01192 for (x=0; matches[x]; x++) { 01193 matchlen = strlen(matches[x]) + 1; 01194 if (len + matchlen >= buflen) { 01195 buflen += matchlen * 3; 01196 obuf = buf; 01197 if (!(buf = ast_realloc(obuf, buflen))) 01198 /* Memory allocation failure... Just free old buffer and be done */ 01199 ast_free(obuf); 01200 } 01201 if (buf) 01202 len += sprintf( buf + len, "%s ", matches[x]); 01203 ast_free(matches[x]); 01204 matches[x] = NULL; 01205 } 01206 ast_free(matches); 01207 } 01208 01209 if (buf) { 01210 ast_cli(a->fd, "%s%s",buf, AST_CLI_COMPLETE_EOF); 01211 ast_free(buf); 01212 } else 01213 ast_cli(a->fd, "NULL\n"); 01214 01215 return CLI_SUCCESS; 01216 }
static char* handle_commandnummatches | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1220 of file cli.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_generatornummatches(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
01221 { 01222 int matches = 0; 01223 01224 switch (cmd) { 01225 case CLI_INIT: 01226 e->command = "_command nummatches"; 01227 e->usage = 01228 "Usage: _command nummatches \"<line>\" text \n" 01229 " This function is used internally to help with command completion and should.\n" 01230 " never be called by the user directly.\n"; 01231 return NULL; 01232 case CLI_GENERATE: 01233 return NULL; 01234 } 01235 01236 if (a->argc != 4) 01237 return CLI_SHOWUSAGE; 01238 01239 matches = ast_cli_generatornummatches(a->argv[2], a->argv[3]); 01240 01241 ast_cli(a->fd, "%d", matches); 01242 01243 return CLI_SUCCESS; 01244 }
static char* handle_core_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 306 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_module_reload(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
00307 { 00308 switch (cmd) { 00309 case CLI_INIT: 00310 e->command = "core reload"; 00311 e->usage = 00312 "Usage: core reload\n" 00313 " Execute a global reload.\n"; 00314 return NULL; 00315 00316 case CLI_GENERATE: 00317 return NULL; 00318 } 00319 00320 if (a->argc != e->args) { 00321 return CLI_SHOWUSAGE; 00322 } 00323 00324 ast_module_reload(NULL); 00325 00326 return CLI_SUCCESS; 00327 }
static char* handle_core_set_debug_channel | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1300 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, args, ast_cli_args::argv, ast_channel_callback(), ast_channel_get_by_name(), ast_channel_unref, ast_cli(), ast_complete_channels(), ast_strdup, channel_set_debug(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEBUGCHAN_FLAG, ast_cli_args::fd, global_fin, global_fout, ast_cli_args::line, ast_cli_args::n, OBJ_MULTIPLE, OBJ_NODATA, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
Referenced by handle_nodebugchan_deprecated().
01301 { 01302 struct ast_channel *c = NULL; 01303 struct channel_set_debug_args args = { 01304 .fd = a->fd, 01305 }; 01306 01307 switch (cmd) { 01308 case CLI_INIT: 01309 e->command = "core set debug channel"; 01310 e->usage = 01311 "Usage: core set debug channel <all|channel> [off]\n" 01312 " Enables/disables debugging on all or on a specific channel.\n"; 01313 return NULL; 01314 case CLI_GENERATE: 01315 /* XXX remember to handle the optional "off" */ 01316 if (a->pos != e->args) 01317 return NULL; 01318 return a->n == 0 ? ast_strdup("all") : ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args); 01319 } 01320 01321 if (cmd == (CLI_HANDLER + 1000)) { 01322 /* called from handle_nodebugchan_deprecated */ 01323 args.is_off = 1; 01324 } else if (a->argc == e->args + 2) { 01325 /* 'core set debug channel {all|chan_id}' */ 01326 if (!strcasecmp(a->argv[e->args + 1], "off")) 01327 args.is_off = 1; 01328 else 01329 return CLI_SHOWUSAGE; 01330 } else if (a->argc != e->args + 1) { 01331 return CLI_SHOWUSAGE; 01332 } 01333 01334 if (!strcasecmp("all", a->argv[e->args])) { 01335 if (args.is_off) { 01336 global_fin &= ~DEBUGCHAN_FLAG; 01337 global_fout &= ~DEBUGCHAN_FLAG; 01338 } else { 01339 global_fin |= DEBUGCHAN_FLAG; 01340 global_fout |= DEBUGCHAN_FLAG; 01341 } 01342 ast_channel_callback(channel_set_debug, NULL, &args, OBJ_NODATA | OBJ_MULTIPLE); 01343 } else { 01344 if ((c = ast_channel_get_by_name(a->argv[e->args]))) { 01345 channel_set_debug(c, NULL, &args, 0); 01346 ast_channel_unref(c); 01347 } else { 01348 ast_cli(a->fd, "No such channel %s\n", a->argv[e->args]); 01349 } 01350 } 01351 01352 ast_cli(a->fd, "Debugging on new channels is %s\n", args.is_off ? "disabled" : "enabled"); 01353 01354 return CLI_SUCCESS; 01355 }
static char * handle_help | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2155 of file cli.c.
References __ast_cli_generator(), ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_join(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, find_cli(), help1(), ast_cli_args::line, ast_cli_args::n, ast_cli_entry::usage, and ast_cli_args::word.
02156 { 02157 char fullcmd[80]; 02158 struct ast_cli_entry *my_e; 02159 char *res = CLI_SUCCESS; 02160 02161 if (cmd == CLI_INIT) { 02162 e->command = "core show help"; 02163 e->usage = 02164 "Usage: core show help [topic]\n" 02165 " When called with a topic as an argument, displays usage\n" 02166 " information on the given command. If called without a\n" 02167 " topic, it provides a list of commands.\n"; 02168 return NULL; 02169 02170 } else if (cmd == CLI_GENERATE) { 02171 /* skip first 14 or 15 chars, "core show help " */ 02172 int l = strlen(a->line); 02173 02174 if (l > 15) { 02175 l = 15; 02176 } 02177 /* XXX watch out, should stop to the non-generator parts */ 02178 return __ast_cli_generator(a->line + l, a->word, a->n, 0); 02179 } 02180 if (a->argc == e->args) { 02181 return help1(a->fd, NULL, 0); 02182 } 02183 02184 AST_RWLIST_RDLOCK(&helpers); 02185 my_e = find_cli(a->argv + 3, 1); /* try exact match first */ 02186 if (!my_e) { 02187 res = help1(a->fd, a->argv + 3, 1 /* locked */); 02188 AST_RWLIST_UNLOCK(&helpers); 02189 return res; 02190 } 02191 if (my_e->usage) 02192 ast_cli(a->fd, "%s", my_e->usage); 02193 else { 02194 ast_join(fullcmd, sizeof(fullcmd), a->argv + 3); 02195 ast_cli(a->fd, "No help text available for '%s'.\n", fullcmd); 02196 } 02197 AST_RWLIST_UNLOCK(&helpers); 02198 return res; 02199 }
static char* handle_load | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 245 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_load_resource(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_fn(), ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
00246 { 00247 /* "module load <mod>" */ 00248 switch (cmd) { 00249 case CLI_INIT: 00250 e->command = "module load"; 00251 e->usage = 00252 "Usage: module load <module name>\n" 00253 " Loads the specified module into Asterisk.\n"; 00254 return NULL; 00255 00256 case CLI_GENERATE: 00257 if (a->pos != e->args) 00258 return NULL; 00259 return complete_fn(a->word, a->n); 00260 } 00261 if (a->argc != e->args + 1) 00262 return CLI_SHOWUSAGE; 00263 if (ast_load_resource(a->argv[e->args])) { 00264 ast_cli(a->fd, "Unable to load module %s\n", a->argv[e->args]); 00265 return CLI_FAILURE; 00266 } 00267 ast_cli(a->fd, "Loaded %s\n", a->argv[e->args]); 00268 return CLI_SUCCESS; 00269 }
static char* handle_logger_mute | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 567 of file cli.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_console_toggle_mute(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
00568 { 00569 switch (cmd) { 00570 case CLI_INIT: 00571 e->command = "logger mute"; 00572 e->usage = 00573 "Usage: logger mute\n" 00574 " Disables logging output to the current console, making it possible to\n" 00575 " gather information without being disturbed by scrolling lines.\n"; 00576 return NULL; 00577 case CLI_GENERATE: 00578 return NULL; 00579 } 00580 00581 if (a->argc < 2 || a->argc > 3) 00582 return CLI_SHOWUSAGE; 00583 00584 if (a->argc == 3 && !strcasecmp(a->argv[2], "silent")) 00585 ast_console_toggle_mute(a->fd, 1); 00586 else 00587 ast_console_toggle_mute(a->fd, 0); 00588 00589 return CLI_SUCCESS; 00590 }
static char* handle_modlist | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 748 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_module_helper(), ast_mutex_lock, ast_mutex_unlock, ast_update_module_list(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, climodentrylock, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, MODLIST_FORMAT2, modlist_modentry(), ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
00749 { 00750 const char *like; 00751 00752 switch (cmd) { 00753 case CLI_INIT: 00754 e->command = "module show [like]"; 00755 e->usage = 00756 "Usage: module show [like keyword]\n" 00757 " Shows Asterisk modules currently in use, and usage statistics.\n"; 00758 return NULL; 00759 00760 case CLI_GENERATE: 00761 if (a->pos == e->args) 00762 return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0); 00763 else 00764 return NULL; 00765 } 00766 /* all the above return, so we proceed with the handler. 00767 * we are guaranteed to have argc >= e->args 00768 */ 00769 if (a->argc == e->args - 1) 00770 like = ""; 00771 else if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args-1], "like") ) 00772 like = a->argv[e->args]; 00773 else 00774 return CLI_SHOWUSAGE; 00775 00776 ast_mutex_lock(&climodentrylock); 00777 climodentryfd = a->fd; /* global, protected by climodentrylock */ 00778 ast_cli(a->fd, MODLIST_FORMAT2, "Module", "Description", "Use Count"); 00779 ast_cli(a->fd,"%d modules loaded\n", ast_update_module_list(modlist_modentry, like)); 00780 climodentryfd = -1; 00781 ast_mutex_unlock(&climodentrylock); 00782 return CLI_SUCCESS; 00783 }
static char* handle_nodebugchan_deprecated | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1357 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, and handle_core_set_debug_channel().
01358 { 01359 char *res; 01360 01361 switch (cmd) { 01362 case CLI_INIT: 01363 e->command = "no debug channel"; 01364 return NULL; 01365 case CLI_HANDLER: 01366 /* exit out of switch statement */ 01367 break; 01368 default: 01369 return NULL; 01370 } 01371 01372 if (a->argc != e->args + 1) 01373 return CLI_SHOWUSAGE; 01374 01375 /* add a 'magic' value to the CLI_HANDLER command so that 01376 * handle_core_set_debug_channel() will act as if 'off' 01377 * had been specified as part of the command 01378 */ 01379 res = handle_core_set_debug_channel(e, CLI_HANDLER + 1000, a); 01380 01381 return res; 01382 }
static char* handle_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 271 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_module_helper(), ast_module_reload(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
00272 { 00273 int x; 00274 00275 switch (cmd) { 00276 case CLI_INIT: 00277 e->command = "module reload"; 00278 e->usage = 00279 "Usage: module reload [module ...]\n" 00280 " Reloads configuration files for all listed modules which support\n" 00281 " reloading, or for all supported modules if none are listed.\n"; 00282 return NULL; 00283 00284 case CLI_GENERATE: 00285 return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 1); 00286 } 00287 if (a->argc == e->args) { 00288 ast_module_reload(NULL); 00289 return CLI_SUCCESS; 00290 } 00291 for (x = e->args; x < a->argc; x++) { 00292 int res = ast_module_reload(a->argv[x]); 00293 /* XXX reload has multiple error returns, including -1 on error and 2 on success */ 00294 switch (res) { 00295 case 0: 00296 ast_cli(a->fd, "No such module '%s'\n", a->argv[x]); 00297 break; 00298 case 1: 00299 ast_cli(a->fd, "Module '%s' does not support reload\n", a->argv[x]); 00300 break; 00301 } 00302 } 00303 return CLI_SUCCESS; 00304 }
static char* handle_showcalls | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 787 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_cli(), ast_processed_calls(), ast_startuptime, ast_strdup, ast_tvnow(), ast_tvsub(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, ESS, ast_cli_args::fd, ast_cli_args::n, option_maxcalls, ast_cli_args::pos, print_uptimestr(), RESULT_SUCCESS, and ast_cli_entry::usage.
00788 { 00789 struct timeval curtime = ast_tvnow(); 00790 int showuptime, printsec; 00791 00792 switch (cmd) { 00793 case CLI_INIT: 00794 e->command = "core show calls [uptime]"; 00795 e->usage = 00796 "Usage: core show calls [uptime] [seconds]\n" 00797 " Lists number of currently active calls and total number of calls\n" 00798 " processed through PBX since last restart. If 'uptime' is specified\n" 00799 " the system uptime is also displayed. If 'seconds' is specified in\n" 00800 " addition to 'uptime', the system uptime is displayed in seconds.\n"; 00801 return NULL; 00802 00803 case CLI_GENERATE: 00804 if (a->pos != e->args) 00805 return NULL; 00806 return a->n == 0 ? ast_strdup("seconds") : NULL; 00807 } 00808 00809 /* regular handler */ 00810 if (a->argc >= e->args && !strcasecmp(a->argv[e->args-1],"uptime")) { 00811 showuptime = 1; 00812 00813 if (a->argc == e->args+1 && !strcasecmp(a->argv[e->args],"seconds")) 00814 printsec = 1; 00815 else if (a->argc == e->args) 00816 printsec = 0; 00817 else 00818 return CLI_SHOWUSAGE; 00819 } else if (a->argc == e->args-1) { 00820 showuptime = 0; 00821 printsec = 0; 00822 } else 00823 return CLI_SHOWUSAGE; 00824 00825 if (option_maxcalls) { 00826 ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n", 00827 ast_active_calls(), option_maxcalls, ESS(ast_active_calls()), 00828 ((double)ast_active_calls() / (double)option_maxcalls) * 100.0); 00829 } else { 00830 ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls())); 00831 } 00832 00833 ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls())); 00834 00835 if (ast_startuptime.tv_sec && showuptime) { 00836 print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec); 00837 } 00838 00839 return RESULT_SUCCESS; 00840 }
static char* handle_showchan | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1384 of file cli.c.
References ast_channel::_bridge, ast_channel::_state, ast_cli_args::argc, ast_cli_args::argv, ast_bridged_channel(), ast_cdr_serialize_variables(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), AST_FLAG_BLOCKING, ast_getformatname_multiple(), ast_state2str(), ast_str_alloca, ast_str_buffer(), ast_str_thread_get(), ast_test_flag, ast_translate_path_to_str(), ast_tvnow(), ast_channel::caller, ast_channel::cdr, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEBUGCHAN_FLAG, ast_channel::dialed, ast_cli_args::fd, ast_channel::fds, ast_channel::fin, ast_channel::fout, ast_party_caller::id, ast_channel::language, ast_cli_args::line, ast_channel::linkedid, ast_cli_args::n, name, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, pbx_builtin_serialize_variables(), ast_cli_args::pos, ast_channel::readformat, ast_channel::readtrans, ast_channel::rings, S_COR, S_OR, ast_cdr::start, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech, ast_channel_tech::type, ast_channel::uniqueid, ast_cli_entry::usage, ast_party_name::valid, ast_party_number::valid, ast_channel::whentohangup, ast_cli_args::word, ast_channel::writeformat, and ast_channel::writetrans.
01385 { 01386 struct ast_channel *c=NULL; 01387 struct timeval now; 01388 struct ast_str *out = ast_str_thread_get(&ast_str_thread_global_buf, 16); 01389 char cdrtime[256]; 01390 char nf[256], wf[256], rf[256]; 01391 struct ast_str *write_transpath = ast_str_alloca(256); 01392 struct ast_str *read_transpath = ast_str_alloca(256); 01393 long elapsed_seconds=0; 01394 int hour=0, min=0, sec=0; 01395 #ifdef CHANNEL_TRACE 01396 int trace_enabled; 01397 #endif 01398 01399 switch (cmd) { 01400 case CLI_INIT: 01401 e->command = "core show channel"; 01402 e->usage = 01403 "Usage: core show channel <channel>\n" 01404 " Shows lots of information about the specified channel.\n"; 01405 return NULL; 01406 case CLI_GENERATE: 01407 return ast_complete_channels(a->line, a->word, a->pos, a->n, 3); 01408 } 01409 01410 if (a->argc != 4) { 01411 return CLI_SHOWUSAGE; 01412 } 01413 01414 now = ast_tvnow(); 01415 01416 if (!(c = ast_channel_get_by_name(a->argv[3]))) { 01417 ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); 01418 return CLI_SUCCESS; 01419 } 01420 01421 ast_channel_lock(c); 01422 01423 if (c->cdr) { 01424 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01425 hour = elapsed_seconds / 3600; 01426 min = (elapsed_seconds % 3600) / 60; 01427 sec = elapsed_seconds % 60; 01428 snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec); 01429 } else { 01430 strcpy(cdrtime, "N/A"); 01431 } 01432 01433 ast_cli(a->fd, 01434 " -- General --\n" 01435 " Name: %s\n" 01436 " Type: %s\n" 01437 " UniqueID: %s\n" 01438 " LinkedID: %s\n" 01439 " Caller ID: %s\n" 01440 " Caller ID Name: %s\n" 01441 " DNID Digits: %s\n" 01442 " Language: %s\n" 01443 " State: %s (%d)\n" 01444 " Rings: %d\n" 01445 " NativeFormats: %s\n" 01446 " WriteFormat: %s\n" 01447 " ReadFormat: %s\n" 01448 " WriteTranscode: %s %s\n" 01449 " ReadTranscode: %s %s\n" 01450 "1st File Descriptor: %d\n" 01451 " Frames in: %d%s\n" 01452 " Frames out: %d%s\n" 01453 " Time to Hangup: %ld\n" 01454 " Elapsed Time: %s\n" 01455 " Direct Bridge: %s\n" 01456 "Indirect Bridge: %s\n" 01457 " -- PBX --\n" 01458 " Context: %s\n" 01459 " Extension: %s\n" 01460 " Priority: %d\n" 01461 " Call Group: %llu\n" 01462 " Pickup Group: %llu\n" 01463 " Application: %s\n" 01464 " Data: %s\n" 01465 " Blocking in: %s\n", 01466 c->name, c->tech->type, c->uniqueid, c->linkedid, 01467 S_COR(c->caller.id.number.valid, c->caller.id.number.str, "(N/A)"), 01468 S_COR(c->caller.id.name.valid, c->caller.id.name.str, "(N/A)"), 01469 S_OR(c->dialed.number.str, "(N/A)"), 01470 c->language, 01471 ast_state2str(c->_state), c->_state, c->rings, 01472 ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats), 01473 ast_getformatname_multiple(wf, sizeof(wf), c->writeformat), 01474 ast_getformatname_multiple(rf, sizeof(rf), c->readformat), 01475 c->writetrans ? "Yes" : "No", 01476 ast_translate_path_to_str(c->writetrans, &write_transpath), 01477 c->readtrans ? "Yes" : "No", 01478 ast_translate_path_to_str(c->readtrans, &read_transpath), 01479 c->fds[0], 01480 c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", 01481 c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", 01482 (long)c->whentohangup.tv_sec, 01483 cdrtime, c->_bridge ? c->_bridge->name : "<none>", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "<none>", 01484 c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ), 01485 ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"), 01486 (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)")); 01487 01488 if (pbx_builtin_serialize_variables(c, &out)) { 01489 ast_cli(a->fd," Variables:\n%s\n", ast_str_buffer(out)); 01490 } 01491 01492 if (c->cdr && ast_cdr_serialize_variables(c->cdr, &out, '=', '\n', 1)) { 01493 ast_cli(a->fd," CDR Variables:\n%s\n", ast_str_buffer(out)); 01494 } 01495 01496 #ifdef CHANNEL_TRACE 01497 trace_enabled = ast_channel_trace_is_enabled(c); 01498 ast_cli(a->fd, " Context Trace: %s\n", trace_enabled ? "Enabled" : "Disabled"); 01499 if (trace_enabled && ast_channel_trace_serialize(c, &out)) 01500 ast_cli(a->fd, " Trace:\n%s\n", ast_str_buffer(out)); 01501 #endif 01502 01503 ast_channel_unlock(c); 01504 c = ast_channel_unref(c); 01505 01506 return CLI_SUCCESS; 01507 }
static char* handle_showuptime | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 717 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_lastreloadtime, ast_startuptime, ast_tvnow(), ast_tvsub(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, print_uptimestr(), and ast_cli_entry::usage.
00718 { 00719 struct timeval curtime = ast_tvnow(); 00720 int printsec; 00721 00722 switch (cmd) { 00723 case CLI_INIT: 00724 e->command = "core show uptime [seconds]"; 00725 e->usage = 00726 "Usage: core show uptime [seconds]\n" 00727 " Shows Asterisk uptime information.\n" 00728 " The seconds word returns the uptime in seconds only.\n"; 00729 return NULL; 00730 00731 case CLI_GENERATE: 00732 return NULL; 00733 } 00734 /* regular handler */ 00735 if (a->argc == e->args && !strcasecmp(a->argv[e->args-1],"seconds")) 00736 printsec = 1; 00737 else if (a->argc == e->args-1) 00738 printsec = 0; 00739 else 00740 return CLI_SHOWUSAGE; 00741 if (ast_startuptime.tv_sec) 00742 print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec); 00743 if (ast_lastreloadtime.tv_sec) 00744 print_uptimestr(a->fd, ast_tvsub(curtime, ast_lastreloadtime), "Last reload", printsec); 00745 return CLI_SUCCESS; 00746 }
static char* handle_softhangup | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 976 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_channel::name, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
00977 { 00978 struct ast_channel *c=NULL; 00979 00980 switch (cmd) { 00981 case CLI_INIT: 00982 e->command = "channel request hangup"; 00983 e->usage = 00984 "Usage: channel request hangup <channel>|<all>\n" 00985 " Request that a channel be hung up. The hangup takes effect\n" 00986 " the next time the driver reads or writes from the channel.\n" 00987 " If 'all' is specified instead of a channel name, all channels\n" 00988 " will see the hangup request.\n"; 00989 return NULL; 00990 case CLI_GENERATE: 00991 return ast_complete_channels(a->line, a->word, a->pos, a->n, e->args); 00992 } 00993 00994 if (a->argc != 4) { 00995 return CLI_SHOWUSAGE; 00996 } 00997 00998 if (!strcasecmp(a->argv[3], "all")) { 00999 struct ast_channel_iterator *iter = NULL; 01000 if (!(iter = ast_channel_iterator_all_new())) { 01001 return CLI_FAILURE; 01002 } 01003 for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) { 01004 ast_channel_lock(c); 01005 ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name); 01006 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01007 ast_channel_unlock(c); 01008 } 01009 ast_channel_iterator_destroy(iter); 01010 } else if ((c = ast_channel_get_by_name(a->argv[3]))) { 01011 ast_channel_lock(c); 01012 ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name); 01013 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01014 ast_channel_unlock(c); 01015 c = ast_channel_unref(c); 01016 } else { 01017 ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); 01018 } 01019 01020 return CLI_SUCCESS; 01021 }
static char* handle_unload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 592 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), AST_FORCE_FIRM, AST_FORCE_HARD, AST_FORCE_SOFT, ast_module_helper(), ast_unload_resource(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
00593 { 00594 /* "module unload mod_1 [mod_2 .. mod_N]" */ 00595 int x; 00596 int force = AST_FORCE_SOFT; 00597 const char *s; 00598 00599 switch (cmd) { 00600 case CLI_INIT: 00601 e->command = "module unload"; 00602 e->usage = 00603 "Usage: module unload [-f|-h] <module_1> [<module_2> ... ]\n" 00604 " Unloads the specified module from Asterisk. The -f\n" 00605 " option causes the module to be unloaded even if it is\n" 00606 " in use (may cause a crash) and the -h module causes the\n" 00607 " module to be unloaded even if the module says it cannot, \n" 00608 " which almost always will cause a crash.\n"; 00609 return NULL; 00610 00611 case CLI_GENERATE: 00612 return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0); 00613 } 00614 if (a->argc < e->args + 1) 00615 return CLI_SHOWUSAGE; 00616 x = e->args; /* first argument */ 00617 s = a->argv[x]; 00618 if (s[0] == '-') { 00619 if (s[1] == 'f') 00620 force = AST_FORCE_FIRM; 00621 else if (s[1] == 'h') 00622 force = AST_FORCE_HARD; 00623 else 00624 return CLI_SHOWUSAGE; 00625 if (a->argc < e->args + 2) /* need at least one module name */ 00626 return CLI_SHOWUSAGE; 00627 x++; /* skip this argument */ 00628 } 00629 00630 for (; x < a->argc; x++) { 00631 if (ast_unload_resource(a->argv[x], force)) { 00632 ast_cli(a->fd, "Unable to unload resource %s\n", a->argv[x]); 00633 return CLI_FAILURE; 00634 } 00635 ast_cli(a->fd, "Unloaded %s\n", a->argv[x]); 00636 } 00637 00638 return CLI_SUCCESS; 00639 }
static char* handle_verbose | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 385 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, args, ast_cli_args::argv, ast_calloc, ast_clear_flag, ast_cli(), ast_complete_source_filename(), ast_free, AST_OPT_FLAG_DEBUG_MODULE, AST_OPT_FLAG_VERBOSE_MODULE, ast_options, AST_RWLIST_EMPTY, AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_set_flag, ast_strdup, ast_strdupa, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_number(), module_level::entry, ast_cli_args::fd, find_module_level(), module_level::level, module_level::module, ast_cli_args::n, option_debug, option_verbose, ast_cli_args::pos, S_OR, and ast_cli_entry::usage.
00386 { 00387 int oldval; 00388 int newlevel; 00389 unsigned int is_debug; 00390 int atleast = 0; 00391 int fd = a->fd; 00392 int argc = a->argc; 00393 const char * const *argv = a->argv; 00394 const char *argv3 = a->argv ? S_OR(a->argv[3], "") : ""; 00395 int *dst; 00396 char *what; 00397 struct module_level_list *mll; 00398 struct module_level *ml; 00399 00400 switch (cmd) { 00401 case CLI_INIT: 00402 e->command = "core set {debug|verbose}"; 00403 e->usage = 00404 #if !defined(LOW_MEMORY) 00405 "Usage: core set {debug|verbose} [atleast] <level> [module]\n" 00406 #else 00407 "Usage: core set {debug|verbose} [atleast] <level>\n" 00408 #endif 00409 " core set {debug|verbose} off\n" 00410 #if !defined(LOW_MEMORY) 00411 " Sets level of debug or verbose messages to be displayed or\n" 00412 " sets a module name to display debug messages from.\n" 00413 #else 00414 " Sets level of debug or verbose messages to be displayed.\n" 00415 #endif 00416 " 0 or off means no messages should be displayed.\n" 00417 " Equivalent to -d[d[...]] or -v[v[v...]] on startup\n"; 00418 return NULL; 00419 00420 case CLI_GENERATE: 00421 if (a->pos == 3 || (a->pos == 4 && !strcasecmp(a->argv[3], "atleast"))) { 00422 const char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], ""); 00423 int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21; 00424 if (a->n < 21 && numbermatch == 0) { 00425 return complete_number(pos, 0, 0x7fffffff, a->n); 00426 } else if (pos[0] == '0') { 00427 if (a->n == 0) { 00428 return ast_strdup("0"); 00429 } else { 00430 return NULL; 00431 } 00432 } else if (a->n == (21 - numbermatch)) { 00433 if (a->pos == 3 && !strncasecmp(argv3, "off", strlen(argv3))) { 00434 return ast_strdup("off"); 00435 } else if (a->pos == 3 && !strncasecmp(argv3, "atleast", strlen(argv3))) { 00436 return ast_strdup("atleast"); 00437 } 00438 } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) { 00439 return ast_strdup("atleast"); 00440 } 00441 #if !defined(LOW_MEMORY) 00442 } else if (a->pos == 4 || (a->pos == 5 && !strcasecmp(argv3, "atleast"))) { 00443 return ast_complete_source_filename(a->pos == 4 ? S_OR(a->argv[4], "") : S_OR(a->argv[5], ""), a->n); 00444 #endif 00445 } 00446 return NULL; 00447 } 00448 /* all the above return, so we proceed with the handler. 00449 * we are guaranteed to be called with argc >= e->args; 00450 */ 00451 00452 if (argc <= e->args) 00453 return CLI_SHOWUSAGE; 00454 if (!strcasecmp(argv[e->args - 1], "debug")) { 00455 dst = &option_debug; 00456 oldval = option_debug; 00457 what = "Core debug"; 00458 is_debug = 1; 00459 } else { 00460 dst = &option_verbose; 00461 oldval = option_verbose; 00462 what = "Verbosity"; 00463 is_debug = 0; 00464 } 00465 if (argc == e->args + 1 && !strcasecmp(argv[e->args], "off")) { 00466 newlevel = 0; 00467 00468 mll = is_debug ? &debug_modules : &verbose_modules; 00469 00470 AST_RWLIST_WRLOCK(mll); 00471 while ((ml = AST_RWLIST_REMOVE_HEAD(mll, entry))) { 00472 ast_free(ml); 00473 } 00474 ast_clear_flag(&ast_options, is_debug ? AST_OPT_FLAG_DEBUG_MODULE : AST_OPT_FLAG_VERBOSE_MODULE); 00475 AST_RWLIST_UNLOCK(mll); 00476 00477 goto done; 00478 } 00479 if (!strcasecmp(argv[e->args], "atleast")) 00480 atleast = 1; 00481 if (argc != e->args + atleast + 1 && argc != e->args + atleast + 2) 00482 return CLI_SHOWUSAGE; 00483 if (sscanf(argv[e->args + atleast], "%30d", &newlevel) != 1) 00484 return CLI_SHOWUSAGE; 00485 if (argc == e->args + atleast + 2) { 00486 /* We have specified a module name. */ 00487 char *mod = ast_strdupa(argv[e->args + atleast + 1]); 00488 00489 if ((strlen(mod) > 3) && !strcasecmp(mod + strlen(mod) - 3, ".so")) { 00490 mod[strlen(mod) - 3] = '\0'; 00491 } 00492 00493 mll = is_debug ? &debug_modules : &verbose_modules; 00494 00495 AST_RWLIST_WRLOCK(mll); 00496 00497 ml = find_module_level(mod, is_debug); 00498 if (!newlevel) { 00499 if (!ml) { 00500 /* Specified off for a nonexistent entry. */ 00501 AST_RWLIST_UNLOCK(mll); 00502 return CLI_SUCCESS; 00503 } 00504 AST_RWLIST_REMOVE(mll, ml, entry); 00505 if (AST_RWLIST_EMPTY(mll)) 00506 ast_clear_flag(&ast_options, is_debug ? AST_OPT_FLAG_DEBUG_MODULE : AST_OPT_FLAG_VERBOSE_MODULE); 00507 AST_RWLIST_UNLOCK(mll); 00508 ast_cli(fd, "%s was %d and has been set to 0 for '%s'\n", what, ml->level, mod); 00509 ast_free(ml); 00510 return CLI_SUCCESS; 00511 } 00512 00513 if (ml) { 00514 if ((atleast && newlevel < ml->level) || ml->level == newlevel) { 00515 ast_cli(fd, "%s is %d for '%s'\n", what, ml->level, mod); 00516 AST_RWLIST_UNLOCK(mll); 00517 return CLI_SUCCESS; 00518 } 00519 oldval = ml->level; 00520 ml->level = newlevel; 00521 } else { 00522 ml = ast_calloc(1, sizeof(*ml) + strlen(mod) + 1); 00523 if (!ml) { 00524 AST_RWLIST_UNLOCK(mll); 00525 return CLI_FAILURE; 00526 } 00527 oldval = ml->level; 00528 ml->level = newlevel; 00529 strcpy(ml->module, mod); 00530 AST_RWLIST_INSERT_TAIL(mll, ml, entry); 00531 } 00532 00533 ast_set_flag(&ast_options, is_debug ? AST_OPT_FLAG_DEBUG_MODULE : AST_OPT_FLAG_VERBOSE_MODULE); 00534 00535 AST_RWLIST_UNLOCK(mll); 00536 00537 ast_cli(fd, "%s was %d and has been set to %d for '%s'\n", what, oldval, ml->level, ml->module); 00538 00539 return CLI_SUCCESS; 00540 } else if (!newlevel) { 00541 /* Specified level as 0 instead of off. */ 00542 mll = is_debug ? &debug_modules : &verbose_modules; 00543 00544 AST_RWLIST_WRLOCK(mll); 00545 while ((ml = AST_RWLIST_REMOVE_HEAD(mll, entry))) { 00546 ast_free(ml); 00547 } 00548 ast_clear_flag(&ast_options, is_debug ? AST_OPT_FLAG_DEBUG_MODULE : AST_OPT_FLAG_VERBOSE_MODULE); 00549 AST_RWLIST_UNLOCK(mll); 00550 } 00551 00552 done: 00553 if (!atleast || newlevel > *dst) 00554 *dst = newlevel; 00555 if (oldval > 0 && *dst == 0) 00556 ast_cli(fd, "%s is now OFF\n", what); 00557 else if (*dst > 0) { 00558 if (oldval == *dst) 00559 ast_cli(fd, "%s is at least %d\n", what, *dst); 00560 else 00561 ast_cli(fd, "%s was %d and is now %d\n", what, oldval, *dst); 00562 } 00563 00564 return CLI_SUCCESS; 00565 }
static char* help1 | ( | int | fd, | |
const char *const | match[], | |||
int | locked | |||
) | [static] |
helper for final part of handle_help if locked = 1, assume the list is already locked
Definition at line 2126 of file cli.c.
References ast_cli_entry::_full_cmd, ast_cli(), ast_join(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, cli_next(), CLI_SUCCESS, len(), S_OR, and ast_cli_entry::summary.
Referenced by handle_help().
02127 { 02128 char matchstr[80] = ""; 02129 struct ast_cli_entry *e = NULL; 02130 int len = 0; 02131 int found = 0; 02132 02133 if (match) { 02134 ast_join(matchstr, sizeof(matchstr), match); 02135 len = strlen(matchstr); 02136 } 02137 if (!locked) 02138 AST_RWLIST_RDLOCK(&helpers); 02139 while ( (e = cli_next(e)) ) { 02140 /* Hide commands that start with '_' */ 02141 if (e->_full_cmd[0] == '_') 02142 continue; 02143 if (match && strncasecmp(matchstr, e->_full_cmd, len)) 02144 continue; 02145 ast_cli(fd, "%30.30s %s\n", e->_full_cmd, S_OR(e->summary, "<no description available>")); 02146 found++; 02147 } 02148 if (!locked) 02149 AST_RWLIST_UNLOCK(&helpers); 02150 if (!found && matchstr[0]) 02151 ast_cli(fd, "No such command '%s'.\n", matchstr); 02152 return CLI_SUCCESS; 02153 }
static char* is_prefix | ( | const char * | word, | |
const char * | token, | |||
int | pos, | |||
int * | actual | |||
) | [static] |
if word is a valid prefix for token, returns the pos-th match as a malloced string, or NULL otherwise. Always tell in *actual how many matches we got.
Definition at line 1898 of file cli.c.
References ast_strdup, ast_strdupa, ast_strlen_zero(), strsep(), and t1.
Referenced by __ast_cli_generator().
01900 { 01901 int lw; 01902 char *s, *t1; 01903 01904 *actual = 0; 01905 if (ast_strlen_zero(token)) 01906 return NULL; 01907 if (ast_strlen_zero(word)) 01908 word = ""; /* dummy */ 01909 lw = strlen(word); 01910 if (strcspn(word, cli_rsvd) != lw) 01911 return NULL; /* no match if word has reserved chars */ 01912 if (strchr(cli_rsvd, token[0]) == NULL) { /* regular match */ 01913 if (strncasecmp(token, word, lw)) /* no match */ 01914 return NULL; 01915 *actual = 1; 01916 return (pos != 0) ? NULL : ast_strdup(token); 01917 } 01918 /* now handle regexp match */ 01919 01920 /* Wildcard always matches, so we never do is_prefix on them */ 01921 01922 t1 = ast_strdupa(token + 1); /* copy, skipping first char */ 01923 while (pos >= 0 && (s = strsep(&t1, cli_rsvd)) && *s) { 01924 if (*s == '%') /* wildcard */ 01925 continue; 01926 if (strncasecmp(s, word, lw)) /* no match */ 01927 continue; 01928 (*actual)++; 01929 if (pos-- == 0) 01930 return ast_strdup(s); 01931 } 01932 return NULL; 01933 }
static int modlist_modentry | ( | const char * | module, | |
const char * | description, | |||
int | usecnt, | |||
const char * | like | |||
) | [static] |
Definition at line 647 of file cli.c.
References ast_cli(), MODLIST_FORMAT, and strcasestr().
Referenced by handle_modlist().
00648 { 00649 /* Comparing the like with the module */ 00650 if (strcasestr(module, like) ) { 00651 ast_cli(climodentryfd, MODLIST_FORMAT, module, description, usecnt); 00652 return 1; 00653 } 00654 return 0; 00655 }
static int more_words | ( | const char *const * | dst | ) | [static] |
returns true if there are more words to match
Definition at line 2332 of file cli.c.
Referenced by __ast_cli_generator().
02333 { 02334 int i; 02335 for (i = 0; dst[i]; i++) { 02336 if (dst[i][0] != '[') 02337 return -1; 02338 } 02339 return 0; 02340 }
static char* parse_args | ( | const char * | s, | |
int * | argc, | |||
const char * | argv[], | |||
int | max, | |||
int * | trailingwhitespace | |||
) | [static] |
Definition at line 2201 of file cli.c.
References ast_log(), ast_strdup, dummy(), and LOG_WARNING.
Referenced by __ast_cli_generator(), agi_handle_command(), and ast_cli_command_full().
02202 { 02203 char *duplicate, *cur; 02204 int x = 0; 02205 int quoted = 0; 02206 int escaped = 0; 02207 int whitespace = 1; 02208 int dummy = 0; 02209 02210 if (trailingwhitespace == NULL) 02211 trailingwhitespace = &dummy; 02212 *trailingwhitespace = 0; 02213 if (s == NULL) /* invalid, though! */ 02214 return NULL; 02215 /* make a copy to store the parsed string */ 02216 if (!(duplicate = ast_strdup(s))) 02217 return NULL; 02218 02219 cur = duplicate; 02220 /* scan the original string copying into cur when needed */ 02221 for (; *s ; s++) { 02222 if (x >= max - 1) { 02223 ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s); 02224 break; 02225 } 02226 if (*s == '"' && !escaped) { 02227 quoted = !quoted; 02228 if (quoted && whitespace) { 02229 /* start a quoted string from previous whitespace: new argument */ 02230 argv[x++] = cur; 02231 whitespace = 0; 02232 } 02233 } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) { 02234 /* If we are not already in whitespace, and not in a quoted string or 02235 processing an escape sequence, and just entered whitespace, then 02236 finalize the previous argument and remember that we are in whitespace 02237 */ 02238 if (!whitespace) { 02239 *cur++ = '\0'; 02240 whitespace = 1; 02241 } 02242 } else if (*s == '\\' && !escaped) { 02243 escaped = 1; 02244 } else { 02245 if (whitespace) { 02246 /* we leave whitespace, and are not quoted. So it's a new argument */ 02247 argv[x++] = cur; 02248 whitespace = 0; 02249 } 02250 *cur++ = *s; 02251 escaped = 0; 02252 } 02253 } 02254 /* Null terminate */ 02255 *cur++ = '\0'; 02256 /* XXX put a NULL in the last argument, because some functions that take 02257 * the array may want a null-terminated array. 02258 * argc still reflects the number of non-NULL entries. 02259 */ 02260 argv[x] = NULL; 02261 *argc = x; 02262 *trailingwhitespace = whitespace; 02263 return duplicate; 02264 }
static void print_uptimestr | ( | int | fd, | |
struct timeval | timeval, | |||
const char * | prefix, | |||
int | printsec | |||
) | [static] |
Definition at line 657 of file cli.c.
References ast_cli(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_strlen(), DAY, ESS, HOUR, MINUTE, NEEDCOMMA, WEEK, and YEAR.
Referenced by handle_showcalls(), and handle_showuptime().
00658 { 00659 int x; /* the main part - years, weeks, etc. */ 00660 struct ast_str *out; 00661 00662 #define SECOND (1) 00663 #define MINUTE (SECOND*60) 00664 #define HOUR (MINUTE*60) 00665 #define DAY (HOUR*24) 00666 #define WEEK (DAY*7) 00667 #define YEAR (DAY*365) 00668 #define NEEDCOMMA(x) ((x)? ",": "") /* define if we need a comma */ 00669 if (timeval.tv_sec < 0) /* invalid, nothing to show */ 00670 return; 00671 00672 if (printsec) { /* plain seconds output */ 00673 ast_cli(fd, "%s: %lu\n", prefix, (u_long)timeval.tv_sec); 00674 return; 00675 } 00676 out = ast_str_alloca(256); 00677 if (timeval.tv_sec > YEAR) { 00678 x = (timeval.tv_sec / YEAR); 00679 timeval.tv_sec -= (x * YEAR); 00680 ast_str_append(&out, 0, "%d year%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00681 } 00682 if (timeval.tv_sec > WEEK) { 00683 x = (timeval.tv_sec / WEEK); 00684 timeval.tv_sec -= (x * WEEK); 00685 ast_str_append(&out, 0, "%d week%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00686 } 00687 if (timeval.tv_sec > DAY) { 00688 x = (timeval.tv_sec / DAY); 00689 timeval.tv_sec -= (x * DAY); 00690 ast_str_append(&out, 0, "%d day%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00691 } 00692 if (timeval.tv_sec > HOUR) { 00693 x = (timeval.tv_sec / HOUR); 00694 timeval.tv_sec -= (x * HOUR); 00695 ast_str_append(&out, 0, "%d hour%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00696 } 00697 if (timeval.tv_sec > MINUTE) { 00698 x = (timeval.tv_sec / MINUTE); 00699 timeval.tv_sec -= (x * MINUTE); 00700 ast_str_append(&out, 0, "%d minute%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00701 } 00702 x = timeval.tv_sec; 00703 if (x > 0 || ast_str_strlen(out) == 0) /* if there is nothing, print 0 seconds */ 00704 ast_str_append(&out, 0, "%d second%s ", x, ESS(x)); 00705 ast_cli(fd, "%s: %s\n", prefix, ast_str_buffer(out)); 00706 }
static int set_full_cmd | ( | struct ast_cli_entry * | e | ) | [static] |
initialize the _full_cmd string and related parameters, return 0 on success, -1 on error.
Definition at line 1695 of file cli.c.
References ast_cli_entry::_full_cmd, ast_cli_entry::args, ast_join(), ast_log(), ast_strdup, ast_cli_entry::cmda, ast_cli_entry::cmdlen, and LOG_WARNING.
Referenced by __ast_cli_register().
01696 { 01697 int i; 01698 char buf[80]; 01699 01700 ast_join(buf, sizeof(buf), e->cmda); 01701 e->_full_cmd = ast_strdup(buf); 01702 if (!e->_full_cmd) { 01703 ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf); 01704 return -1; 01705 } 01706 e->cmdlen = strcspn(e->_full_cmd, cli_rsvd); 01707 for (i = 0; e->cmda[i]; i++) 01708 ; 01709 e->args = i; 01710 return 0; 01711 }
static int word_match | ( | const char * | cmd, | |
const char * | cli_word | |||
) | [static] |
match a word in the CLI entry. returns -1 on mismatch, 0 on match of an optional word, 1 on match of a full word.
The pattern can be any_word match for equal [foo|bar|baz] optionally, one of these words {foo|bar|baz} exactly, one of these words % any word
Definition at line 1869 of file cli.c.
References ast_strlen_zero(), and strcasestr().
Referenced by __ast_cli_generator(), and find_cli().
01870 { 01871 int l; 01872 char *pos; 01873 01874 if (ast_strlen_zero(cmd) || ast_strlen_zero(cli_word)) 01875 return -1; 01876 if (!strchr(cli_rsvd, cli_word[0])) /* normal match */ 01877 return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1; 01878 /* regexp match, takes [foo|bar] or {foo|bar} */ 01879 l = strlen(cmd); 01880 /* wildcard match - will extend in the future */ 01881 if (l > 0 && cli_word[0] == '%') { 01882 return 1; /* wildcard */ 01883 } 01884 pos = strcasestr(cli_word, cmd); 01885 if (pos == NULL) /* not found, say ok if optional */ 01886 return cli_word[0] == '[' ? 0 : -1; 01887 if (pos == cli_word) /* no valid match at the beginning */ 01888 return -1; 01889 if (strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) 01890 return 1; /* valid match */ 01891 return -1; /* not found */ 01892 }
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 [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" [static] |
CLI permissions config file.
Definition at line 70 of file cli.c.
Referenced by ast_cli_perms_init().
ast_mutex_t permsconfiglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
struct module_level_list verbose_modules [static] |