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