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