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