Standard Command Line Interface. More...
#include "asterisk.h"#include "asterisk/_private.h"#include "asterisk/paths.h"#include <sys/signal.h>#include <signal.h>#include <ctype.h>#include <regex.h>#include <pwd.h>#include <grp.h>#include <readline.h>#include "asterisk/cli.h"#include "asterisk/linkedlists.h"#include "asterisk/module.h"#include "asterisk/pbx.h"#include "asterisk/channel.h"#include "asterisk/utils.h"#include "asterisk/app.h"#include "asterisk/lock.h"#include "asterisk/threadstorage.h"
Go to the source code of this file.
Data Structures | |
| struct | ast_debug_file |
| map a debug or verbose value to a filename More... | |
| struct | cli_perm |
| List of restrictions per user. More... | |
| struct | cli_perm_head |
| struct | cli_perms |
| List of users and permissions. More... | |
| struct | debug_file_list |
| struct | helpers |
| 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!%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 %-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 %-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, 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_file (const char *file) |
| Get the debug level for a file. | |
| unsigned int | ast_verbose_get_by_file (const char *file) |
| Get the debug level for a file. | |
| 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 (char *argv[]) |
| static struct ast_cli_entry * | find_cli (char *const cmds[], int match_type) |
| static struct ast_debug_file * | find_debug_file (const char *fn, 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_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_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, char *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 (char *const *dst) |
| returns true if there are more words to match | |
| static char * | parse_args (const char *s, int *argc, 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 = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
| static struct debug_file_list | debug_files |
| static const char | perms_config [] = "cli_permissions.conf" |
| CLI permissions config file. | |
| static ast_mutex_t | permsconfiglock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
| mutex used to prevent a user from running the 'cli reload permissions' command while it is already running. | |
| static struct debug_file_list | verbose_files |
Standard Command Line Interface.
Definition in file cli.c.
| #define AST_CLI_INITLEN 256 |
| #define CONCISE_FORMAT_STRING "%s!%s!%s!%d!%s!%s!%s!%s!%s!%d!%s!%s!%s\n" |
Referenced by handle_chanlist().
| #define DAY (HOUR*24) |
Referenced by print_uptimestr().
| #define FORMAT_STRING "%-25s %-20s %-20s\n" |
| #define FORMAT_STRING "%-20.20s %-20.20s %-7.7s %-30.30s\n" |
Referenced by group_show_channels(), and handle_chanlist().
| #define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n" |
Referenced by handle_chanlist().
| #define HOUR (MINUTE*60) |
Referenced by print_uptimestr().
| #define MINUTE (SECOND*60) |
Referenced by print_uptimestr().
| #define MODLIST_FORMAT "%-30s %-40.40s %-10d\n" |
Definition at line 590 of file cli.c.
Referenced by modlist_modentry().
| #define MODLIST_FORMAT2 "%-30s %-40.40s %-10s\n" |
Definition at line 591 of file cli.c.
Referenced by handle_modlist().
| #define NEEDCOMMA | ( | x | ) | ((x)? ",": "") |
Referenced by print_uptimestr().
| #define SECOND (1) |
| #define VERBOSE_FORMAT_STRING "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-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 %-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 2171 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().
02172 { 02173 char *argv[AST_MAX_ARGS]; 02174 struct ast_cli_entry *e = NULL; 02175 int x = 0, argindex, matchlen; 02176 int matchnum=0; 02177 char *ret = NULL; 02178 char matchstr[80] = ""; 02179 int tws = 0; 02180 /* Split the argument into an array of words */ 02181 char *duplicate = parse_args(text, &x, argv, ARRAY_LEN(argv), &tws); 02182 02183 if (!duplicate) /* malloc error */ 02184 return NULL; 02185 02186 /* Compute the index of the last argument (could be an empty string) */ 02187 argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x; 02188 02189 /* rebuild the command, ignore terminating white space and flatten space */ 02190 ast_join(matchstr, sizeof(matchstr)-1, argv); 02191 matchlen = strlen(matchstr); 02192 if (tws) { 02193 strcat(matchstr, " "); /* XXX */ 02194 if (matchlen) 02195 matchlen++; 02196 } 02197 if (lock) 02198 AST_RWLIST_RDLOCK(&helpers); 02199 while ( (e = cli_next(e)) ) { 02200 /* XXX repeated code */ 02201 int src = 0, dst = 0, n = 0; 02202 02203 if (e->command[0] == '_') 02204 continue; 02205 02206 /* 02207 * Try to match words, up to and excluding the last word, which 02208 * is either a blank or something that we want to extend. 02209 */ 02210 for (;src < argindex; dst++, src += n) { 02211 n = word_match(argv[src], e->cmda[dst]); 02212 if (n < 0) 02213 break; 02214 } 02215 02216 if (src != argindex && more_words(e->cmda + dst)) /* not a match */ 02217 continue; 02218 ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n); 02219 matchnum += n; /* this many matches here */ 02220 if (ret) { 02221 /* 02222 * argv[src] is a valid prefix of the next word in this 02223 * command. If this is also the correct entry, return it. 02224 */ 02225 if (matchnum > state) 02226 break; 02227 ast_free(ret); 02228 ret = NULL; 02229 } else if (ast_strlen_zero(e->cmda[dst])) { 02230 /* 02231 * This entry is a prefix of the command string entered 02232 * (only one entry in the list should have this property). 02233 * Run the generator if one is available. In any case we are done. 02234 */ 02235 if (e->handler) { /* new style command */ 02236 struct ast_cli_args a = { 02237 .line = matchstr, .word = word, 02238 .pos = argindex, 02239 .n = state - matchnum, 02240 .argv = argv, 02241 .argc = x}; 02242 ret = e->handler(e, CLI_GENERATE, &a); 02243 } 02244 if (ret) 02245 break; 02246 } 02247 } 02248 if (lock) 02249 AST_RWLIST_UNLOCK(&helpers); 02250 ast_free(duplicate); 02251 return ret; 02252 }
| static int __ast_cli_register | ( | struct ast_cli_entry * | e, | |
| struct ast_cli_entry * | ed | |||
| ) | [static] |
Definition at line 1858 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, S_OR, and set_full_cmd().
Referenced by ast_cli_register().
01859 { 01860 struct ast_cli_entry *cur; 01861 int i, lf, ret = -1; 01862 01863 struct ast_cli_args a; /* fake argument */ 01864 char **dst = (char **)e->cmda; /* need to cast as the entry is readonly */ 01865 char *s; 01866 01867 memset(&a, '\0', sizeof(a)); 01868 e->handler(e, CLI_INIT, &a); 01869 /* XXX check that usage and command are filled up */ 01870 s = ast_skip_blanks(e->command); 01871 s = e->command = ast_strdup(s); 01872 for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) { 01873 *dst++ = s; /* store string */ 01874 s = ast_skip_nonblanks(s); 01875 if (*s == '\0') /* we are done */ 01876 break; 01877 *s++ = '\0'; 01878 s = ast_skip_blanks(s); 01879 } 01880 *dst++ = NULL; 01881 01882 AST_RWLIST_WRLOCK(&helpers); 01883 01884 if (find_cli(e->cmda, 1)) { 01885 ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", S_OR(e->_full_cmd, e->command)); 01886 goto done; 01887 } 01888 if (set_full_cmd(e)) 01889 goto done; 01890 01891 lf = e->cmdlen; 01892 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) { 01893 int len = cur->cmdlen; 01894 if (lf < len) 01895 len = lf; 01896 if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) { 01897 AST_RWLIST_INSERT_BEFORE_CURRENT(e, list); 01898 break; 01899 } 01900 } 01901 AST_RWLIST_TRAVERSE_SAFE_END; 01902 01903 if (!cur) 01904 AST_RWLIST_INSERT_TAIL(&helpers, e, list); 01905 ret = 0; /* success */ 01906 01907 done: 01908 AST_RWLIST_UNLOCK(&helpers); 01909 01910 return ret; 01911 }
| static int __ast_cli_unregister | ( | struct ast_cli_entry * | e, | |
| struct ast_cli_entry * | ed | |||
| ) | [static] |
Definition at line 1836 of file cli.c.
References ast_cli_entry::_full_cmd, ast_free, ast_log(), AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::handler, ast_cli_entry::inuse, LOG_WARNING, and ast_cli_entry::usage.
Referenced by ast_cli_unregister().
01837 { 01838 if (e->inuse) { 01839 ast_log(LOG_WARNING, "Can't remove command that is in use\n"); 01840 } else { 01841 AST_RWLIST_WRLOCK(&helpers); 01842 AST_RWLIST_REMOVE(&helpers, e, list); 01843 AST_RWLIST_UNLOCK(&helpers); 01844 ast_free(e->_full_cmd); 01845 e->_full_cmd = NULL; 01846 if (e->handler) { 01847 /* this is a new-style entry. Reset fields and free memory. */ 01848 char *cmda = (char *) e->cmda; 01849 memset(cmda, '\0', sizeof(e->cmda)); 01850 ast_free(e->command); 01851 e->command = NULL; 01852 e->usage = NULL; 01853 } 01854 } 01855 return 0; 01856 }
| void ast_builtins_init | ( | void | ) |
initialize the _full_cmd string in * each of the builtins.
Provided by cli.c
Definition at line 1678 of file cli.c.
References ARRAY_LEN, and ast_cli_register_multiple().
Referenced by main().
01679 { 01680 ast_cli_register_multiple(cli_cli, ARRAY_LEN(cli_cli)); 01681 }
| void ast_cli | ( | int | fd, | |
| const char * | fmt, | |||
| ... | ||||
| ) |
Definition at line 101 of file cli.c.
References ast_carefulwrite(), AST_CLI_INITLEN, AST_DYNSTR_BUILD_FAILED, ast_str_buffer(), ast_str_set_va(), ast_str_strlen(), ast_str_thread_get(), and buf.
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_do_reload(), aji_do_set_debug(), aji_show_buddies(), aji_show_clients(), aji_test(), alias_show(), ast_cli_command_full(), ast_cli_netstats(), ast_console_toggle_mute(), 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_list_available(), cli_list_devices(), cli_match_char_tree(), cli_odbc_read(), cli_odbc_write(), cli_realtime_destroy(), cli_realtime_load(), cli_realtime_store(), cli_realtime_update(), cli_realtime_update2(), cli_tps_ping(), cli_tps_report(), console_active(), console_answer(), console_autoanswer(), console_boost(), console_cmd(), console_dial(), console_do_answer(), console_flash(), console_hangup(), console_mute(), console_sendtext(), console_transfer(), dahdi_set_dnd(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), dahdi_show_status(), dahdi_show_version(), dialog_dump_func(), do_print(), 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(), group_show_channels(), gtalk_show_channels(), handle_chanlist(), handle_cli_agi_debug(), handle_cli_agi_dump_html(), handle_cli_agi_show(), handle_cli_check_permissions(), handle_cli_config_list(), handle_cli_core_show_channeltype(), handle_cli_core_show_channeltypes(), handle_cli_core_show_config_mappings(), handle_cli_core_show_file_formats(), handle_cli_core_show_translation(), handle_cli_database_del(), handle_cli_database_deltree(), handle_cli_database_get(), handle_cli_database_put(), handle_cli_database_show(), handle_cli_database_showkey(), handle_cli_devstate_change(), handle_cli_devstate_list(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_add_ignorepat(), handle_cli_dialplan_add_include(), handle_cli_dialplan_reload(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_remove_ignorepat(), handle_cli_dialplan_remove_include(), handle_cli_dialplan_save(), handle_cli_file_convert(), handle_cli_h323_set_debug(), handle_cli_h323_set_trace(), handle_cli_iax2_provision(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_set_debug_jb(), handle_cli_iax2_set_debug_trunk(), handle_cli_iax2_set_mtu(), handle_cli_iax2_show_cache(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_firmware(), handle_cli_iax2_show_netstats(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_stats(), handle_cli_iax2_show_threads(), handle_cli_iax2_show_users(), handle_cli_iax2_unregister(), handle_cli_indication_show(), handle_cli_keys_show(), handle_cli_misdn_reload(), handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_set_debug(), handle_cli_misdn_show_channels(), handle_cli_misdn_show_config(), handle_cli_misdn_show_port(), handle_cli_misdn_show_ports_stats(), handle_cli_misdn_show_stacks(), handle_cli_misdn_toggle_echocancel(), handle_cli_mixmonitor(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_cli_odbc_show(), handle_cli_osp_show(), handle_cli_realtime_pgsql_cache(), handle_cli_realtime_pgsql_status(), handle_cli_refresh(), handle_cli_rtcp_set_debug(), handle_cli_rtcp_set_stats(), handle_cli_rtp_set_debug(), handle_cli_show_permissions(), handle_cli_show_sqlite_status(), handle_cli_sqlite_show_tables(), handle_cli_status(), handle_cli_stun_set_debug(), handle_cli_submit(), handle_cli_transcoder_show(), handle_cli_udptl_set_debug(), handle_cli_ulimit(), handle_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_mandebug(), handle_memory_show(), handle_memory_show_summary(), handle_mgcp_audit_endpoint(), handle_mgcp_set_debug(), handle_mgcp_show_endpoints(), handle_minivm_list_templates(), handle_minivm_reload(), handle_minivm_show_settings(), handle_minivm_show_stats(), handle_minivm_show_users(), handle_minivm_show_zones(), handle_modlist(), handle_parkedcalls(), handle_pri_debug(), handle_pri_set_debug_file(), handle_pri_show_debug(), handle_pri_show_span(), handle_pri_show_spans(), 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_application(), handle_show_applications(), 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_ss7_block_cic(), handle_ss7_block_linkset(), handle_ss7_debug(), handle_ss7_show_linkset(), handle_ss7_unblock_cic(), handle_ss7_unblock_linkset(), handle_ss7_version(), 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(), print_app_docs(), print_bc_info(), print_codec_to_cli(), print_group(), print_uptimestr(), radio_active(), radio_set_debug(), radio_set_debug_off(), radio_set_xpmr_debug(), radio_tune(), realtime_ldap_status(), rpt_do_cmd(), rpt_do_debug(), rpt_do_dump(), rpt_do_fun(), rpt_do_local_nodes(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_chanstats_cb(), show_codec_n(), show_codecs(), show_config_description(), show_debug_helper(), show_dialplan_helper(), show_license(), show_users_realtime(), show_warranty(), 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(), timing_test(), tune_rxctcss(), tune_rxinput(), tune_rxvoice(), tune_txoutput(), unistim_do_debug(), unistim_info(), and unistim_sp().
00102 { 00103 int res; 00104 struct ast_str *buf; 00105 va_list ap; 00106 00107 if (!(buf = ast_str_thread_get(&ast_cli_buf, AST_CLI_INITLEN))) 00108 return; 00109 00110 va_start(ap, fmt); 00111 res = ast_str_set_va(&buf, 0, fmt, ap); 00112 va_end(ap); 00113 00114 if (res != AST_DYNSTR_BUILD_FAILED) { 00115 ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100); 00116 } 00117 }
| int ast_cli_command_full | ( | int | uid, | |
| int | gid, | |||
| int | fd, | |||
| const char * | s | |||
| ) |
Interprets a command Interpret a command s, sending output to fd if uid:gid has permissions to run this command. uid = CLI_NO_PERMS to avoid checking user permissions gid = CLI_NO_PERMS to avoid checking group permissions.
| uid | User ID that is trying to run the command. | |
| gid | Group ID that is trying to run the command. | |
| fd | pipe | |
| s | incoming string |
| 0 | on success | |
| -1 | on failure |
Definition at line 2259 of file cli.c.
References 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().
02260 { 02261 char *args[AST_MAX_ARGS + 1]; 02262 struct ast_cli_entry *e; 02263 int x; 02264 char *duplicate = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL); 02265 char tmp[AST_MAX_ARGS + 1]; 02266 char *retval = NULL; 02267 struct ast_cli_args a = { 02268 .fd = fd, .argc = x, .argv = args+1 }; 02269 02270 if (duplicate == NULL) 02271 return -1; 02272 02273 if (x < 1) /* We need at least one entry, otherwise ignore */ 02274 goto done; 02275 02276 AST_RWLIST_RDLOCK(&helpers); 02277 e = find_cli(args + 1, 0); 02278 if (e) 02279 ast_atomic_fetchadd_int(&e->inuse, 1); 02280 AST_RWLIST_UNLOCK(&helpers); 02281 if (e == NULL) { 02282 ast_cli(fd, "No such command '%s' (type 'core show help %s' for other possible commands)\n", s, find_best(args + 1)); 02283 goto done; 02284 } 02285 02286 ast_join(tmp, sizeof(tmp), args + 1); 02287 /* Check if the user has rights to run this command. */ 02288 if (!cli_has_permissions(uid, gid, tmp)) { 02289 ast_cli(fd, "You don't have permissions to run '%s' command\n", tmp); 02290 ast_free(duplicate); 02291 return 0; 02292 } 02293 02294 /* 02295 * Within the handler, argv[-1] contains a pointer to the ast_cli_entry. 02296 * Remember that the array returned by parse_args is NULL-terminated. 02297 */ 02298 args[0] = (char *)e; 02299 02300 retval = e->handler(e, CLI_HANDLER, &a); 02301 02302 if (retval == CLI_SHOWUSAGE) { 02303 ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n")); 02304 } else { 02305 if (retval == CLI_FAILURE) 02306 ast_cli(fd, "Command '%s' failed.\n", s); 02307 } 02308 ast_atomic_fetchadd_int(&e->inuse, -1); 02309 done: 02310 ast_free(duplicate); 02311 return 0; 02312 }
| 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 2314 of file cli.c.
References ast_cli_command_full().
Referenced by netconsole().
02315 { 02316 char cmd[512]; 02317 int x, y = 0, count = 0; 02318 02319 for (x = 0; x < size; x++) { 02320 cmd[y] = s[x]; 02321 y++; 02322 if (s[x] == '\0') { 02323 ast_cli_command_full(uid, gid, fd, cmd); 02324 y = 0; 02325 count++; 02326 } 02327 } 02328 return count; 02329 }
| char* ast_cli_complete | ( | const char * | word, | |
| 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 char *choices = { "one", "two", "three", NULL }; if (pos == 2) return ast_cli_complete(word, choices, n); else return NULL; }
Definition at line 1379 of file cli.c.
References ast_strdup, ast_strlen_zero(), and len().
Referenced by complete_meetmecmd(), handle_cli_devstate_change(), handle_cli_iax2_prune_realtime(), handle_orig(), handle_show_applications(), and sip_prune_realtime().
01380 { 01381 int i, which = 0, len; 01382 len = ast_strlen_zero(word) ? 0 : strlen(word); 01383 01384 for (i = 0; choices[i]; i++) { 01385 if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state) 01386 return ast_strdup(choices[i]); 01387 } 01388 return NULL; 01389 }
| 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 2110 of file cli.c.
References ast_cli_generator(), ast_copy_string(), ast_malloc, and ast_realloc.
Referenced by cli_complete(), and handle_commandmatchesarray().
02111 { 02112 char **match_list = NULL, *retstr, *prevstr; 02113 size_t match_list_len, max_equal, which, i; 02114 int matches = 0; 02115 02116 /* leave entry 0 free for the longest common substring */ 02117 match_list_len = 1; 02118 while ((retstr = ast_cli_generator(text, word, matches)) != NULL) { 02119 if (matches + 1 >= match_list_len) { 02120 match_list_len <<= 1; 02121 if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(*match_list)))) 02122 return NULL; 02123 } 02124 match_list[++matches] = retstr; 02125 } 02126 02127 if (!match_list) 02128 return match_list; /* NULL */ 02129 02130 /* Find the longest substring that is common to all results 02131 * (it is a candidate for completion), and store a copy in entry 0. 02132 */ 02133 prevstr = match_list[1]; 02134 max_equal = strlen(prevstr); 02135 for (which = 2; which <= matches; which++) { 02136 for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++) 02137 continue; 02138 max_equal = i; 02139 } 02140 02141 if (!(retstr = ast_malloc(max_equal + 1))) 02142 return NULL; 02143 02144 ast_copy_string(retstr, match_list[1], max_equal + 1); 02145 match_list[0] = retstr; 02146 02147 /* ensure that the array is NULL terminated */ 02148 if (matches + 1 >= match_list_len) { 02149 if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list)))) 02150 return NULL; 02151 } 02152 match_list[matches + 1] = NULL; 02153 02154 return match_list; 02155 }
| 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 2254 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().
02255 { 02256 return __ast_cli_generator(text, word, state, 1); 02257 }
| int ast_cli_generatornummatches | ( | const char * | text, | |
| const char * | word | |||
| ) |
Return the number of unique matches for the generator.
Definition at line 2093 of file cli.c.
References ast_cli_generator(), ast_free, and buf.
Referenced by handle_commandnummatches().
02094 { 02095 int matches = 0, i = 0; 02096 char *buf = NULL, *oldbuf = NULL; 02097 02098 while ((buf = ast_cli_generator(text, word, i++))) { 02099 if (!oldbuf || strcmp(buf,oldbuf)) 02100 matches++; 02101 if (oldbuf) 02102 ast_free(oldbuf); 02103 oldbuf = buf; 02104 } 02105 if (oldbuf) 02106 ast_free(oldbuf); 02107 return matches; 02108 }
| int ast_cli_perms_init | ( | int | reload | ) |
Provided by cli.c
Definition at line 1555 of file cli.c.
References ast_calloc, ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_strlen_zero(), ast_variable_browse(), cli_perm::command, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, destroy_user_perms(), usergroup_cli_perm::gid, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, cli_perm::permit, usergroup_cli_perm::perms, perms_config, usergroup_cli_perm::uid, and ast_variable::value.
Referenced by handle_cli_reload_permissions(), and main().
01556 { 01557 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 01558 struct ast_config *cfg; 01559 char *cat = NULL; 01560 struct ast_variable *v; 01561 struct usergroup_cli_perm *user_group, *cp_entry; 01562 struct cli_perm *perm = NULL; 01563 struct passwd *pw; 01564 struct group *gr; 01565 01566 if (ast_mutex_trylock(&permsconfiglock)) { 01567 ast_log(LOG_NOTICE, "You must wait until last 'cli reload permissions' command finish\n"); 01568 return 1; 01569 } 01570 01571 cfg = ast_config_load2(perms_config, "" /* core, can't reload */, config_flags); 01572 if (!cfg) { 01573 ast_mutex_unlock(&permsconfiglock); 01574 return 1; 01575 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 01576 ast_mutex_unlock(&permsconfiglock); 01577 return 0; 01578 } 01579 01580 /* free current structures. */ 01581 destroy_user_perms(); 01582 01583 while ((cat = ast_category_browse(cfg, cat))) { 01584 if (!strcasecmp(cat, "general")) { 01585 /* General options */ 01586 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 01587 if (!strcasecmp(v->name, "default_perm")) { 01588 cli_default_perm = (!strcasecmp(v->value, "permit")) ? 1: 0; 01589 } 01590 } 01591 continue; 01592 } 01593 01594 /* users or groups */ 01595 gr = NULL, pw = NULL; 01596 if (cat[0] == '@') { 01597 /* This is a group */ 01598 gr = getgrnam(&cat[1]); 01599 if (!gr) { 01600 ast_log (LOG_WARNING, "Unknown group '%s'\n", &cat[1]); 01601 continue; 01602 } 01603 } else { 01604 /* This is a user */ 01605 pw = getpwnam(cat); 01606 if (!pw) { 01607 ast_log (LOG_WARNING, "Unknown user '%s'\n", cat); 01608 continue; 01609 } 01610 } 01611 user_group = NULL; 01612 /* Check for duplicates */ 01613 AST_RWLIST_WRLOCK(&cli_perms); 01614 AST_LIST_TRAVERSE(&cli_perms, cp_entry, list) { 01615 if ((pw && cp_entry->uid == pw->pw_uid) || (gr && cp_entry->gid == gr->gr_gid)) { 01616 /* if it is duplicated, just added this new settings, to 01617 the current list. */ 01618 user_group = cp_entry; 01619 break; 01620 } 01621 } 01622 AST_RWLIST_UNLOCK(&cli_perms); 01623 01624 if (!user_group) { 01625 /* alloc space for the new user config. */ 01626 user_group = ast_calloc(1, sizeof(*user_group)); 01627 if (!user_group) { 01628 continue; 01629 } 01630 user_group->uid = (pw ? pw->pw_uid : -1); 01631 user_group->gid = (gr ? gr->gr_gid : -1); 01632 user_group->perms = ast_calloc(1, sizeof(*user_group->perms)); 01633 if (!user_group->perms) { 01634 ast_free(user_group); 01635 continue; 01636 } 01637 } 01638 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 01639 if (ast_strlen_zero(v->value)) { 01640 /* we need to check this condition cause it could break security. */ 01641 ast_log(LOG_WARNING, "Empty permit/deny option in user '%s'\n", cat); 01642 continue; 01643 } 01644 if (!strcasecmp(v->name, "permit")) { 01645 perm = ast_calloc(1, sizeof(*perm)); 01646 if (perm) { 01647 perm->permit = 1; 01648 perm->command = ast_strdup(v->value); 01649 } 01650 } else if (!strcasecmp(v->name, "deny")) { 01651 perm = ast_calloc(1, sizeof(*perm)); 01652 if (perm) { 01653 perm->permit = 0; 01654 perm->command = ast_strdup(v->value); 01655 } 01656 } else { 01657 /* up to now, only 'permit' and 'deny' are possible values. */ 01658 ast_log(LOG_WARNING, "Unknown '%s' option\n", v->name); 01659 continue; 01660 } 01661 if (perm) { 01662 /* Added the permission to the user's list. */ 01663 AST_LIST_INSERT_TAIL(user_group->perms, perm, list); 01664 perm = NULL; 01665 } 01666 } 01667 AST_RWLIST_WRLOCK(&cli_perms); 01668 AST_RWLIST_INSERT_TAIL(&cli_perms, user_group, list); 01669 AST_RWLIST_UNLOCK(&cli_perms); 01670 } 01671 01672 ast_config_destroy(cfg); 01673 ast_mutex_unlock(&permsconfiglock); 01674 return 0; 01675 }
| 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 1920 of file cli.c.
References __ast_cli_register().
Referenced by ast_cdr_engine_init(), ast_cli_register_multiple(), dnsmgr_init(), do_reload(), load_config(), and load_module().
01921 { 01922 return __ast_cli_register(e, NULL); 01923 }
| 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 1928 of file cli.c.
References ast_cli_register().
Referenced by __ast_mm_init(), __ast_register_translator(), __init_manager(), ast_ais_clm_load_module(), ast_ais_evt_load_module(), ast_builtins_init(), ast_channels_init(), ast_features_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_rtp_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().
01929 { 01930 int i, res = 0; 01931 01932 for (i = 0; i < len; i++) 01933 res |= ast_cli_register(e + i); 01934 01935 return res; 01936 }
| 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 1914 of file cli.c.
References __ast_cli_unregister().
Referenced by alias_destroy(), ast_cli_unregister_multiple(), do_reload(), load_module(), and unload_module().
01915 { 01916 return __ast_cli_unregister(e, NULL); 01917 }
| 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 1938 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().
01939 { 01940 int i, res = 0; 01941 01942 for (i = 0; i < len; i++) 01943 res |= ast_cli_unregister(e + i); 01944 01945 return res; 01946 }
| 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 1391 of file cli.c.
References ast_channel_unlock, ast_channel_walk_locked(), ast_strdup, and ast_channel::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().
01392 { 01393 struct ast_channel *c = NULL; 01394 int which = 0; 01395 int wordlen; 01396 char notfound = '\0'; 01397 char *ret = ¬found; /* so NULL can break the loop */ 01398 01399 if (pos != rpos) 01400 return NULL; 01401 01402 wordlen = strlen(word); 01403 01404 while (ret == ¬found && (c = ast_channel_walk_locked(c))) { 01405 if (!strncasecmp(word, c->name, wordlen) && ++which > state) 01406 ret = ast_strdup(c->name); 01407 ast_channel_unlock(c); 01408 } 01409 return ret == ¬found ? NULL : ret; 01410 }
| unsigned int ast_debug_get_by_file | ( | const char * | file | ) |
Get the debug level for a file.
| file | the filename |
Definition at line 119 of file cli.c.
References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_debug_file::filename, and ast_debug_file::level.
00120 { 00121 struct ast_debug_file *adf; 00122 unsigned int res = 0; 00123 00124 AST_RWLIST_RDLOCK(&debug_files); 00125 AST_LIST_TRAVERSE(&debug_files, adf, entry) { 00126 if (!strncasecmp(adf->filename, file, strlen(adf->filename))) { 00127 res = adf->level; 00128 break; 00129 } 00130 } 00131 AST_RWLIST_UNLOCK(&debug_files); 00132 00133 return res; 00134 }
| unsigned int ast_verbose_get_by_file | ( | const char * | file | ) |
Get the debug level for a file.
| file | the filename |
Definition at line 136 of file cli.c.
References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_debug_file::filename, and ast_debug_file::level.
00137 { 00138 struct ast_debug_file *adf; 00139 unsigned int res = 0; 00140 00141 AST_RWLIST_RDLOCK(&verbose_files); 00142 AST_LIST_TRAVERSE(&verbose_files, adf, entry) { 00143 if (!strncasecmp(adf->filename, file, strlen(file))) { 00144 res = adf->level; 00145 break; 00146 } 00147 } 00148 AST_RWLIST_UNLOCK(&verbose_files); 00149 00150 return res; 00151 }
| static int cli_has_permissions | ( | int | uid, | |
| int | gid, | |||
| const char * | command | |||
| ) | [static] |
Definition at line 166 of file cli.c.
References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_NO_PERMS, cli_perm::command, usergroup_cli_perm::gid, cli_perm::permit, usergroup_cli_perm::perms, and usergroup_cli_perm::uid.
Referenced by ast_cli_command_full(), and handle_cli_check_permissions().
00167 { 00168 struct usergroup_cli_perm *user_perm; 00169 struct cli_perm *perm; 00170 /* set to the default permissions general option. */ 00171 int isallowg = cli_default_perm, isallowu = -1, ispattern; 00172 regex_t regexbuf; 00173 00174 /* if uid == -1 or gid == -1 do not check permissions. 00175 if uid == -2 and gid == -2 is because rasterisk client didn't send 00176 the credentials, so the cli_default_perm will be applied. */ 00177 if ((uid == CLI_NO_PERMS && gid == CLI_NO_PERMS) || command[0] == '_') { 00178 return 1; 00179 } 00180 00181 if (gid < 0 && uid < 0) { 00182 return cli_default_perm; 00183 } 00184 00185 AST_RWLIST_RDLOCK(&cli_perms); 00186 AST_LIST_TRAVERSE(&cli_perms, user_perm, list) { 00187 if (user_perm->gid != gid && user_perm->uid != uid) { 00188 continue; 00189 } 00190 AST_LIST_TRAVERSE(user_perm->perms, perm, list) { 00191 if (strcasecmp(perm->command, "all") && strncasecmp(perm->command, command, strlen(perm->command))) { 00192 /* if the perm->command is a pattern, check it against command. */ 00193 ispattern = !regcomp(®exbuf, perm->command, REG_EXTENDED | REG_NOSUB | REG_ICASE); 00194 if (ispattern && regexec(®exbuf, command, 0, NULL, 0)) { 00195 regfree(®exbuf); 00196 continue; 00197 } 00198 if (!ispattern) { 00199 continue; 00200 } 00201 regfree(®exbuf); 00202 } 00203 if (user_perm->uid == uid) { 00204 /* this is a user definition. */ 00205 isallowu = perm->permit; 00206 } else { 00207 /* otherwise is a group definition. */ 00208 isallowg = perm->permit; 00209 } 00210 } 00211 } 00212 AST_RWLIST_UNLOCK(&cli_perms); 00213 if (isallowu > -1) { 00214 /* user definition override group definition. */ 00215 isallowg = isallowu; 00216 } 00217 00218 return isallowg; 00219 }
| static struct ast_cli_entry* cli_next | ( | struct ast_cli_entry * | e | ) | [static, read] |
Definition at line 657 of file cli.c.
References AST_LIST_FIRST, and AST_LIST_NEXT.
Referenced by __ast_cli_generator(), find_cli(), handle_cli_check_permissions(), and help1().
00658 { 00659 if (e) { 00660 return AST_LIST_NEXT(e, list); 00661 } else { 00662 return AST_LIST_FIRST(&helpers); 00663 } 00664 }
| static char* complete_fn | ( | const char * | word, | |
| int | state | |||
| ) | [static] |
Definition at line 223 of file cli.c.
References ast_config_AST_MODULE_DIR, ast_copy_string(), ast_strdup, and free.
Referenced by handle_load().
00224 { 00225 char *c, *d; 00226 char filename[PATH_MAX]; 00227 00228 if (word[0] == '/') 00229 ast_copy_string(filename, word, sizeof(filename)); 00230 else 00231 snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word); 00232 00233 c = d = filename_completion_function(filename, state); 00234 00235 if (c && word[0] != '/') 00236 c += (strlen(ast_config_AST_MODULE_DIR) + 1); 00237 if (c) 00238 c = ast_strdup(c); 00239 00240 free(d); 00241 00242 return c; 00243 }
| static char* complete_number | ( | const char * | partial, | |
| unsigned int | min, | |||
| unsigned int | max, | |||
| int | n | |||
| ) | [static] |
Definition at line 322 of file cli.c.
References ast_strdup, ast_strlen_zero(), and cli_perm::next.
Referenced by handle_verbose().
00323 { 00324 int i, count = 0; 00325 unsigned int prospective[2]; 00326 unsigned int part = strtoul(partial, NULL, 10); 00327 char next[12]; 00328 00329 if (part < min || part > max) { 00330 return NULL; 00331 } 00332 00333 for (i = 0; i < 21; i++) { 00334 if (i == 0) { 00335 prospective[0] = prospective[1] = part; 00336 } else if (part == 0 && !ast_strlen_zero(partial)) { 00337 break; 00338 } else if (i < 11) { 00339 prospective[0] = prospective[1] = part * 10 + (i - 1); 00340 } else { 00341 prospective[0] = (part * 10 + (i - 11)) * 10; 00342 prospective[1] = prospective[0] + 9; 00343 } 00344 if (i < 11 && (prospective[0] < min || prospective[0] > max)) { 00345 continue; 00346 } else if (prospective[1] < min || prospective[0] > max) { 00347 continue; 00348 } 00349 00350 if (++count > n) { 00351 if (i < 11) { 00352 snprintf(next, sizeof(next), "%u", prospective[0]); 00353 } else { 00354 snprintf(next, sizeof(next), "%u...", prospective[0] / 10); 00355 } 00356 return ast_strdup(next); 00357 } 00358 } 00359 return NULL; 00360 }
| static void destroy_user_perms | ( | void | ) | [static] |
cleanup (free) cli_perms linkedlist.
Definition at line 1539 of file cli.c.
References ast_free, AST_LIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cli_perm::command, and usergroup_cli_perm::perms.
Referenced by ast_cli_perms_init().
01540 { 01541 struct cli_perm *perm; 01542 struct usergroup_cli_perm *user_perm; 01543 01544 AST_RWLIST_WRLOCK(&cli_perms); 01545 while ((user_perm = AST_LIST_REMOVE_HEAD(&cli_perms, list))) { 01546 while ((perm = AST_LIST_REMOVE_HEAD(user_perm->perms, list))) { 01547 ast_free(perm->command); 01548 ast_free(perm); 01549 } 01550 ast_free(user_perm); 01551 } 01552 AST_RWLIST_UNLOCK(&cli_perms); 01553 }
| static char* find_best | ( | char * | argv[] | ) | [static] |
Definition at line 1817 of file cli.c.
References ast_join(), AST_MAX_CMD_LEN, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and find_cli().
Referenced by ast_cli_command_full().
01818 { 01819 static char cmdline[80]; 01820 int x; 01821 /* See how close we get, then print the candidate */ 01822 char *myargv[AST_MAX_CMD_LEN]; 01823 for (x=0;x<AST_MAX_CMD_LEN;x++) 01824 myargv[x]=NULL; 01825 AST_RWLIST_RDLOCK(&helpers); 01826 for (x=0;argv[x];x++) { 01827 myargv[x] = argv[x]; 01828 if (!find_cli(myargv, -1)) 01829 break; 01830 } 01831 AST_RWLIST_UNLOCK(&helpers); 01832 ast_join(cmdline, sizeof(cmdline), myargv); 01833 return cmdline; 01834 }
| static struct ast_cli_entry* find_cli | ( | char *const | cmds[], | |
| int | match_type | |||
| ) | [static, read] |
Definition at line 1773 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().
01774 { 01775 int matchlen = -1; /* length of longest match so far */ 01776 struct ast_cli_entry *cand = NULL, *e=NULL; 01777 01778 while ( (e = cli_next(e)) ) { 01779 /* word-by word regexp comparison */ 01780 char * const *src = cmds; 01781 char * const *dst = e->cmda; 01782 int n = 0; 01783 for (;; dst++, src += n) { 01784 n = word_match(*src, *dst); 01785 if (n < 0) 01786 break; 01787 } 01788 if (ast_strlen_zero(*dst) || ((*dst)[0] == '[' && ast_strlen_zero(dst[1]))) { 01789 /* no more words in 'e' */ 01790 if (ast_strlen_zero(*src)) /* exact match, cannot do better */ 01791 break; 01792 /* Here, cmds has more words than the entry 'e' */ 01793 if (match_type != 0) /* but we look for almost exact match... */ 01794 continue; /* so we skip this one. */ 01795 /* otherwise we like it (case 0) */ 01796 } else { /* still words in 'e' */ 01797 if (ast_strlen_zero(*src)) 01798 continue; /* cmds is shorter than 'e', not good */ 01799 /* Here we have leftover words in cmds and 'e', 01800 * but there is a mismatch. We only accept this one if match_type == -1 01801 * and this is the last word for both. 01802 */ 01803 if (match_type != -1 || !ast_strlen_zero(src[1]) || 01804 !ast_strlen_zero(dst[1])) /* not the one we look for */ 01805 continue; 01806 /* good, we are in case match_type == -1 and mismatch on last word */ 01807 } 01808 if (src - cmds > matchlen) { /* remember the candidate */ 01809 matchlen = src - cmds; 01810 cand = e; 01811 } 01812 } 01813 01814 return e ? e : cand; 01815 }
| static struct ast_debug_file* find_debug_file | ( | const char * | fn, | |
| unsigned int | debug | |||
| ) | [static, read] |
Find the debug or verbose file setting.
Definition at line 309 of file cli.c.
References AST_LIST_TRAVERSE, and ast_debug_file::filename.
Referenced by handle_verbose().
00310 { 00311 struct ast_debug_file *df = NULL; 00312 struct debug_file_list *dfl = debug ? &debug_files : &verbose_files; 00313 00314 AST_LIST_TRAVERSE(dfl, df, entry) { 00315 if (!strcasecmp(df->filename, fn)) 00316 break; 00317 } 00318 00319 return df; 00320 }
| static char* group_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1412 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.
01413 { 01414 #define FORMAT_STRING "%-25s %-20s %-20s\n" 01415 01416 struct ast_group_info *gi = NULL; 01417 int numchans = 0; 01418 regex_t regexbuf; 01419 int havepattern = 0; 01420 01421 switch (cmd) { 01422 case CLI_INIT: 01423 e->command = "group show channels"; 01424 e->usage = 01425 "Usage: group show channels [pattern]\n" 01426 " Lists all currently active channels with channel group(s) specified.\n" 01427 " Optional regular expression pattern is matched to group names for each\n" 01428 " channel.\n"; 01429 return NULL; 01430 case CLI_GENERATE: 01431 return NULL; 01432 } 01433 01434 if (a->argc < 3 || a->argc > 4) 01435 return CLI_SHOWUSAGE; 01436 01437 if (a->argc == 4) { 01438 if (regcomp(®exbuf, a->argv[3], REG_EXTENDED | REG_NOSUB)) 01439 return CLI_SHOWUSAGE; 01440 havepattern = 1; 01441 } 01442 01443 ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category"); 01444 01445 ast_app_group_list_rdlock(); 01446 01447 gi = ast_app_group_list_head(); 01448 while (gi) { 01449 if (!havepattern || !regexec(®exbuf, gi->group, 0, NULL, 0)) { 01450 ast_cli(a->fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category)); 01451 numchans++; 01452 } 01453 gi = AST_LIST_NEXT(gi, group_list); 01454 } 01455 01456 ast_app_group_list_unlock(); 01457 01458 if (havepattern) 01459 regfree(®exbuf); 01460 01461 ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans)); 01462 return CLI_SUCCESS; 01463 #undef FORMAT_STRING 01464 }
| static char* handle_chanlist | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 791 of file cli.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::amaflags, ast_channel::appl, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_bridged_channel(), ast_channel_unlock, ast_channel_walk_locked(), ast_cli(), ast_processed_calls(), ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, CONCISE_FORMAT_STRING, ast_channel::context, ast_channel::data, ESS, ast_channel::exten, ast_cli_args::fd, FORMAT_STRING, FORMAT_STRING2, ast_channel::name, option_maxcalls, ast_channel::priority, S_OR, ast_cdr::start, ast_channel::uniqueid, ast_cli_entry::usage, VERBOSE_FORMAT_STRING, and VERBOSE_FORMAT_STRING2.
00792 { 00793 #define FORMAT_STRING "%-20.20s %-20.20s %-7.7s %-30.30s\n" 00794 #define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n" 00795 #define CONCISE_FORMAT_STRING "%s!%s!%s!%d!%s!%s!%s!%s!%s!%d!%s!%s!%s\n" 00796 #define VERBOSE_FORMAT_STRING "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n" 00797 #define VERBOSE_FORMAT_STRING2 "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n" 00798 00799 struct ast_channel *c = NULL; 00800 int numchans = 0, concise = 0, verbose = 0, count = 0; 00801 int fd, argc; 00802 char **argv; 00803 00804 switch (cmd) { 00805 case CLI_INIT: 00806 e->command = "core show channels [concise|verbose|count]"; 00807 e->usage = 00808 "Usage: core show channels [concise|verbose|count]\n" 00809 " Lists currently defined channels and some information about them. If\n" 00810 " 'concise' is specified, the format is abridged and in a more easily\n" 00811 " machine parsable format. If 'verbose' is specified, the output includes\n" 00812 " more and longer fields. If 'count' is specified only the channel and call\n" 00813 " count is output.\n" 00814 " The 'concise' option is deprecated and will be removed from future versions\n" 00815 " of Asterisk.\n"; 00816 return NULL; 00817 00818 case CLI_GENERATE: 00819 return NULL; 00820 } 00821 fd = a->fd; 00822 argc = a->argc; 00823 argv = a->argv; 00824 00825 if (a->argc == e->args) { 00826 if (!strcasecmp(argv[e->args-1],"concise")) 00827 concise = 1; 00828 else if (!strcasecmp(argv[e->args-1],"verbose")) 00829 verbose = 1; 00830 else if (!strcasecmp(argv[e->args-1],"count")) 00831 count = 1; 00832 else 00833 return CLI_SHOWUSAGE; 00834 } else if (a->argc != e->args - 1) 00835 return CLI_SHOWUSAGE; 00836 00837 if (!count) { 00838 if (!concise && !verbose) 00839 ast_cli(fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)"); 00840 else if (verbose) 00841 ast_cli(fd, VERBOSE_FORMAT_STRING2, "Channel", "Context", "Extension", "Priority", "State", "Application", "Data", 00842 "CallerID", "Duration", "Accountcode", "BridgedTo"); 00843 } 00844 00845 while ((c = ast_channel_walk_locked(c)) != NULL) { 00846 struct ast_channel *bc = ast_bridged_channel(c); 00847 char durbuf[10] = "-"; 00848 00849 if (!count) { 00850 if ((concise || verbose) && c->cdr && !ast_tvzero(c->cdr->start)) { 00851 int duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 00852 if (verbose) { 00853 int durh = duration / 3600; 00854 int durm = (duration % 3600) / 60; 00855 int durs = duration % 60; 00856 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 00857 } else { 00858 snprintf(durbuf, sizeof(durbuf), "%d", duration); 00859 } 00860 } 00861 if (concise) { 00862 ast_cli(fd, CONCISE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state), 00863 c->appl ? c->appl : "(None)", 00864 S_OR(c->data, ""), /* XXX different from verbose ? */ 00865 S_OR(c->cid.cid_num, ""), 00866 S_OR(c->accountcode, ""), 00867 c->amaflags, 00868 durbuf, 00869 bc ? bc->name : "(None)", 00870 c->uniqueid); 00871 } else if (verbose) { 00872 ast_cli(fd, VERBOSE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state), 00873 c->appl ? c->appl : "(None)", 00874 c->data ? S_OR(c->data, "(Empty)" ): "(None)", 00875 S_OR(c->cid.cid_num, ""), 00876 durbuf, 00877 S_OR(c->accountcode, ""), 00878 bc ? bc->name : "(None)"); 00879 } else { 00880 char locbuf[40] = "(None)"; 00881 char appdata[40] = "(None)"; 00882 00883 if (!ast_strlen_zero(c->context) && !ast_strlen_zero(c->exten)) 00884 snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority); 00885 if (c->appl) 00886 snprintf(appdata, sizeof(appdata), "%s(%s)", c->appl, S_OR(c->data, "")); 00887 ast_cli(fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata); 00888 } 00889 } 00890 numchans++; 00891 ast_channel_unlock(c); 00892 } 00893 if (!concise) { 00894 ast_cli(fd, "%d active channel%s\n", numchans, ESS(numchans)); 00895 if (option_maxcalls) 00896 ast_cli(fd, "%d of %d max active call%s (%5.2f%% of capacity)\n", 00897 ast_active_calls(), option_maxcalls, ESS(ast_active_calls()), 00898 ((double)ast_active_calls() / (double)option_maxcalls) * 100.0); 00899 else 00900 ast_cli(fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls())); 00901 00902 ast_cli(fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls())); 00903 } 00904 return CLI_SUCCESS; 00905 00906 #undef FORMAT_STRING 00907 #undef FORMAT_STRING2 00908 #undef CONCISE_FORMAT_STRING 00909 #undef VERBOSE_FORMAT_STRING 00910 #undef VERBOSE_FORMAT_STRING2 00911 }
| 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 1005 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_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.
01006 { 01007 struct passwd *pw = NULL; 01008 struct group *gr; 01009 int gid = -1, uid = -1; 01010 char command[AST_MAX_ARGS] = ""; 01011 struct ast_cli_entry *ce = NULL; 01012 int found = 0; 01013 char *group, *tmp; 01014 01015 switch (cmd) { 01016 case CLI_INIT: 01017 e->command = "cli check permissions"; 01018 e->usage = 01019 "Usage: cli check permissions {<username>|@<groupname>|<username>@<groupname>} [<command>]\n" 01020 " Check permissions config for a user@group or list the allowed commands for the specified user.\n" 01021 " The username or the groupname may be omitted.\n"; 01022 return NULL; 01023 case CLI_GENERATE: 01024 if (a->pos >= 4) { 01025 return ast_cli_generator(a->line + strlen("cli check permissions") + strlen(a->argv[3]) + 1, a->word, a->n); 01026 } 01027 return NULL; 01028 } 01029 01030 if (a->argc < 4) { 01031 return CLI_SHOWUSAGE; 01032 } 01033 01034 tmp = ast_strdupa(a->argv[3]); 01035 group = strchr(tmp, '@'); 01036 if (group) { 01037 gr = getgrnam(&group[1]); 01038 if (!gr) { 01039 ast_cli(a->fd, "Unknown group '%s'\n", &group[1]); 01040 return CLI_FAILURE; 01041 } 01042 group[0] = '\0'; 01043 gid = gr->gr_gid; 01044 } 01045 01046 if (!group && ast_strlen_zero(tmp)) { 01047 ast_cli(a->fd, "You didn't supply a username\n"); 01048 } else if (!ast_strlen_zero(tmp) && !(pw = getpwnam(tmp))) { 01049 ast_cli(a->fd, "Unknown user '%s'\n", tmp); 01050 return CLI_FAILURE; 01051 } else if (pw) { 01052 uid = pw->pw_uid; 01053 } 01054 01055 if (a->argc == 4) { 01056 while ((ce = cli_next(ce))) { 01057 /* Hide commands that start with '_' */ 01058 if (ce->_full_cmd[0] == '_') { 01059 continue; 01060 } 01061 if (cli_has_permissions(uid, gid, ce->_full_cmd)) { 01062 ast_cli(a->fd, "%30.30s %s\n", ce->_full_cmd, S_OR(ce->summary, "<no description available>")); 01063 found++; 01064 } 01065 } 01066 if (!found) { 01067 ast_cli(a->fd, "You are not allowed to run any command on Asterisk\n"); 01068 } 01069 } else { 01070 ast_join(command, sizeof(command), a->argv + 4); 01071 ast_cli(a->fd, "%s '%s%s%s' is %s to run command: '%s'\n", uid >= 0 ? "User" : "Group", tmp, 01072 group && uid >= 0 ? "@" : "", 01073 group ? &group[1] : "", 01074 cli_has_permissions(uid, gid, command) ? "allowed" : "not allowed", command); 01075 } 01076 01077 return CLI_SUCCESS; 01078 }
| 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 986 of file cli.c.
References ast_cli_perms_init(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
00987 { 00988 switch (cmd) { 00989 case CLI_INIT: 00990 e->command = "cli reload permissions"; 00991 e->usage = 00992 "Usage: cli reload permissions\n" 00993 " Reload the 'cli_permissions.conf' file.\n"; 00994 return NULL; 00995 case CLI_GENERATE: 00996 return NULL; 00997 } 00998 00999 ast_cli_perms_init(1); 01000 01001 return CLI_SUCCESS; 01002 }
| 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 941 of file cli.c.
References ast_cli(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, cli_perm::command, ast_cli_entry::command, ast_cli_args::fd, usergroup_cli_perm::gid, cli_perm::permit, usergroup_cli_perm::perms, usergroup_cli_perm::uid, and ast_cli_entry::usage.
00942 { 00943 struct usergroup_cli_perm *cp; 00944 struct cli_perm *perm; 00945 struct passwd *pw = NULL; 00946 struct group *gr = NULL; 00947 00948 switch (cmd) { 00949 case CLI_INIT: 00950 e->command = "cli show permissions"; 00951 e->usage = 00952 "Usage: cli show permissions\n" 00953 " Shows CLI configured permissions.\n"; 00954 return NULL; 00955 case CLI_GENERATE: 00956 return NULL; 00957 } 00958 00959 AST_RWLIST_RDLOCK(&cli_perms); 00960 AST_LIST_TRAVERSE(&cli_perms, cp, list) { 00961 if (cp->uid >= 0) { 00962 pw = getpwuid(cp->uid); 00963 if (pw) { 00964 ast_cli(a->fd, "user: %s [uid=%d]\n", pw->pw_name, cp->uid); 00965 } 00966 } else { 00967 gr = getgrgid(cp->gid); 00968 if (gr) { 00969 ast_cli(a->fd, "group: %s [gid=%d]\n", gr->gr_name, cp->gid); 00970 } 00971 } 00972 ast_cli(a->fd, "Permissions:\n"); 00973 if (cp->perms) { 00974 AST_LIST_TRAVERSE(cp->perms, perm, list) { 00975 ast_cli(a->fd, "\t%s -> %s\n", perm->permit ? "permit" : "deny", perm->command); 00976 } 00977 } 00978 ast_cli(a->fd, "\n"); 00979 } 00980 AST_RWLIST_UNLOCK(&cli_perms); 00981 00982 return CLI_SUCCESS; 00983 }
| static char* handle_commandcomplete | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1163 of file cli.c.
References __ast_cli_generator(), ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_free, buf, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
01164 { 01165 char *buf; 01166 switch (cmd) { 01167 case CLI_INIT: 01168 e->command = "_command complete"; 01169 e->usage = 01170 "Usage: _command complete \"<line>\" text state\n" 01171 " This function is used internally to help with command completion and should.\n" 01172 " never be called by the user directly.\n"; 01173 return NULL; 01174 case CLI_GENERATE: 01175 return NULL; 01176 } 01177 if (a->argc != 5) 01178 return CLI_SHOWUSAGE; 01179 buf = __ast_cli_generator(a->argv[2], a->argv[3], atoi(a->argv[4]), 0); 01180 if (buf) { 01181 ast_cli(a->fd, "%s", buf); 01182 ast_free(buf); 01183 } else 01184 ast_cli(a->fd, "NULL\n"); 01185 return CLI_SUCCESS; 01186 }
| static char* handle_commandmatchesarray | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1082 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, buf, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, len(), and ast_cli_entry::usage.
01083 { 01084 char *buf, *obuf; 01085 int buflen = 2048; 01086 int len = 0; 01087 char **matches; 01088 int x, matchlen; 01089 01090 switch (cmd) { 01091 case CLI_INIT: 01092 e->command = "_command matchesarray"; 01093 e->usage = 01094 "Usage: _command matchesarray \"<line>\" text \n" 01095 " This function is used internally to help with command completion and should.\n" 01096 " never be called by the user directly.\n"; 01097 return NULL; 01098 case CLI_GENERATE: 01099 return NULL; 01100 } 01101 01102 if (a->argc != 4) 01103 return CLI_SHOWUSAGE; 01104 if (!(buf = ast_malloc(buflen))) 01105 return CLI_FAILURE; 01106 buf[len] = '\0'; 01107 matches = ast_cli_completion_matches(a->argv[2], a->argv[3]); 01108 if (matches) { 01109 for (x=0; matches[x]; x++) { 01110 matchlen = strlen(matches[x]) + 1; 01111 if (len + matchlen >= buflen) { 01112 buflen += matchlen * 3; 01113 obuf = buf; 01114 if (!(buf = ast_realloc(obuf, buflen))) 01115 /* Memory allocation failure... Just free old buffer and be done */ 01116 ast_free(obuf); 01117 } 01118 if (buf) 01119 len += sprintf( buf + len, "%s ", matches[x]); 01120 ast_free(matches[x]); 01121 matches[x] = NULL; 01122 } 01123 ast_free(matches); 01124 } 01125 01126 if (buf) { 01127 ast_cli(a->fd, "%s%s",buf, AST_CLI_COMPLETE_EOF); 01128 ast_free(buf); 01129 } else 01130 ast_cli(a->fd, "NULL\n"); 01131 01132 return CLI_SUCCESS; 01133 }
| static char* handle_commandnummatches | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1137 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.
01138 { 01139 int matches = 0; 01140 01141 switch (cmd) { 01142 case CLI_INIT: 01143 e->command = "_command nummatches"; 01144 e->usage = 01145 "Usage: _command nummatches \"<line>\" text \n" 01146 " This function is used internally to help with command completion and should.\n" 01147 " never be called by the user directly.\n"; 01148 return NULL; 01149 case CLI_GENERATE: 01150 return NULL; 01151 } 01152 01153 if (a->argc != 4) 01154 return CLI_SHOWUSAGE; 01155 01156 matches = ast_cli_generatornummatches(a->argv[2], a->argv[3]); 01157 01158 ast_cli(a->fd, "%d", matches); 01159 01160 return CLI_SUCCESS; 01161 }
| static char* handle_core_set_debug_channel | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1188 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_unlock, ast_channel_walk_locked(), ast_cli(), ast_complete_channels(), ast_get_channel_by_name_locked(), ast_strdup, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEBUGCHAN_FLAG, ast_cli_args::fd, ast_channel::fin, ast_channel::fout, global_fin, global_fout, ast_cli_args::line, ast_cli_args::n, ast_channel::name, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
Referenced by handle_nodebugchan_deprecated().
01189 { 01190 struct ast_channel *c = NULL; 01191 int is_all, is_off = 0; 01192 01193 switch (cmd) { 01194 case CLI_INIT: 01195 e->command = "core set debug channel"; 01196 e->usage = 01197 "Usage: core set debug channel <all|channel> [off]\n" 01198 " Enables/disables debugging on all or on a specific channel.\n"; 01199 return NULL; 01200 01201 case CLI_GENERATE: 01202 /* XXX remember to handle the optional "off" */ 01203 if (a->pos != e->args) 01204 return NULL; 01205 return a->n == 0 ? ast_strdup("all") : ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args); 01206 } 01207 /* 'core set debug channel {all|chan_id}' */ 01208 if (a->argc == e->args + 2) { 01209 if (!strcasecmp(a->argv[e->args + 1], "off")) 01210 is_off = 1; 01211 else 01212 return CLI_SHOWUSAGE; 01213 } else if (a->argc != e->args + 1) 01214 return CLI_SHOWUSAGE; 01215 01216 is_all = !strcasecmp("all", a->argv[e->args]); 01217 if (is_all) { 01218 if (is_off) { 01219 global_fin &= ~DEBUGCHAN_FLAG; 01220 global_fout &= ~DEBUGCHAN_FLAG; 01221 } else { 01222 global_fin |= DEBUGCHAN_FLAG; 01223 global_fout |= DEBUGCHAN_FLAG; 01224 } 01225 c = ast_channel_walk_locked(NULL); 01226 } else { 01227 c = ast_get_channel_by_name_locked(a->argv[e->args]); 01228 if (c == NULL) 01229 ast_cli(a->fd, "No such channel %s\n", a->argv[e->args]); 01230 } 01231 while (c) { 01232 if (!(c->fin & DEBUGCHAN_FLAG) || !(c->fout & DEBUGCHAN_FLAG)) { 01233 if (is_off) { 01234 c->fin &= ~DEBUGCHAN_FLAG; 01235 c->fout &= ~DEBUGCHAN_FLAG; 01236 } else { 01237 c->fin |= DEBUGCHAN_FLAG; 01238 c->fout |= DEBUGCHAN_FLAG; 01239 } 01240 ast_cli(a->fd, "Debugging %s on channel %s\n", is_off ? "disabled" : "enabled", c->name); 01241 } 01242 ast_channel_unlock(c); 01243 if (!is_all) 01244 break; 01245 c = ast_channel_walk_locked(c); 01246 } 01247 ast_cli(a->fd, "Debugging on new channels is %s\n", is_off ? "disabled" : "enabled"); 01248 return CLI_SUCCESS; 01249 }
| static char * handle_help | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1981 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.
01982 { 01983 char fullcmd[80]; 01984 struct ast_cli_entry *my_e; 01985 char *res = CLI_SUCCESS; 01986 01987 if (cmd == CLI_INIT) { 01988 e->command = "core show help"; 01989 e->usage = 01990 "Usage: core show help [topic]\n" 01991 " When called with a topic as an argument, displays usage\n" 01992 " information on the given command. If called without a\n" 01993 " topic, it provides a list of commands.\n"; 01994 return NULL; 01995 01996 } else if (cmd == CLI_GENERATE) { 01997 /* skip first 14 or 15 chars, "core show help " */ 01998 int l = strlen(a->line); 01999 02000 if (l > 15) { 02001 l = 15; 02002 } 02003 /* XXX watch out, should stop to the non-generator parts */ 02004 return __ast_cli_generator(a->line + l, a->word, a->n, 0); 02005 } 02006 if (a->argc == e->args) { 02007 return help1(a->fd, NULL, 0); 02008 } 02009 02010 AST_RWLIST_RDLOCK(&helpers); 02011 my_e = find_cli(a->argv + 3, 1); /* try exact match first */ 02012 if (!my_e) { 02013 res = help1(a->fd, a->argv + 3, 1 /* locked */); 02014 AST_RWLIST_UNLOCK(&helpers); 02015 return res; 02016 } 02017 if (my_e->usage) 02018 ast_cli(a->fd, "%s", my_e->usage); 02019 else { 02020 ast_join(fullcmd, sizeof(fullcmd), a->argv + 3); 02021 ast_cli(a->fd, "No help text available for '%s'.\n", fullcmd); 02022 } 02023 AST_RWLIST_UNLOCK(&helpers); 02024 return res; 02025 }
| static char* handle_load | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 245 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_load_resource(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_fn(), ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
00246 { 00247 /* "module load <mod>" */ 00248 switch (cmd) { 00249 case CLI_INIT: 00250 e->command = "module load"; 00251 e->usage = 00252 "Usage: module load <module name>\n" 00253 " Loads the specified module into Asterisk.\n"; 00254 return NULL; 00255 00256 case CLI_GENERATE: 00257 if (a->pos != e->args) 00258 return NULL; 00259 return complete_fn(a->word, a->n); 00260 } 00261 if (a->argc != e->args + 1) 00262 return CLI_SHOWUSAGE; 00263 if (ast_load_resource(a->argv[e->args])) { 00264 ast_cli(a->fd, "Unable to load module %s\n", a->argv[e->args]); 00265 return CLI_FAILURE; 00266 } 00267 return CLI_SUCCESS; 00268 }
| static char* handle_logger_mute | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 518 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.
00519 { 00520 switch (cmd) { 00521 case CLI_INIT: 00522 e->command = "logger mute"; 00523 e->usage = 00524 "Usage: logger mute\n" 00525 " Disables logging output to the current console, making it possible to\n" 00526 " gather information without being disturbed by scrolling lines.\n"; 00527 return NULL; 00528 case CLI_GENERATE: 00529 return NULL; 00530 } 00531 00532 if (a->argc < 2 || a->argc > 3) 00533 return CLI_SHOWUSAGE; 00534 00535 if (a->argc == 3 && !strcasecmp(a->argv[2], "silent")) 00536 ast_console_toggle_mute(a->fd, 1); 00537 else 00538 ast_console_toggle_mute(a->fd, 0); 00539 00540 return CLI_SUCCESS; 00541 }
| static char* handle_modlist | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 697 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.
00698 { 00699 char *like; 00700 00701 switch (cmd) { 00702 case CLI_INIT: 00703 e->command = "module show [like]"; 00704 e->usage = 00705 "Usage: module show [like keyword]\n" 00706 " Shows Asterisk modules currently in use, and usage statistics.\n"; 00707 return NULL; 00708 00709 case CLI_GENERATE: 00710 if (a->pos == e->args) 00711 return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0); 00712 else 00713 return NULL; 00714 } 00715 /* all the above return, so we proceed with the handler. 00716 * we are guaranteed to have argc >= e->args 00717 */ 00718 if (a->argc == e->args - 1) 00719 like = ""; 00720 else if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args-1], "like") ) 00721 like = a->argv[e->args]; 00722 else 00723 return CLI_SHOWUSAGE; 00724 00725 ast_mutex_lock(&climodentrylock); 00726 climodentryfd = a->fd; /* global, protected by climodentrylock */ 00727 ast_cli(a->fd, MODLIST_FORMAT2, "Module", "Description", "Use Count"); 00728 ast_cli(a->fd,"%d modules loaded\n", ast_update_module_list(modlist_modentry, like)); 00729 climodentryfd = -1; 00730 ast_mutex_unlock(&climodentrylock); 00731 return CLI_SUCCESS; 00732 }
| static char* handle_nodebugchan_deprecated | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1251 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, and handle_core_set_debug_channel().
01252 { 01253 char *res; 01254 if (cmd == CLI_HANDLER) { 01255 if (a->argc != e->args + 1) 01256 return CLI_SHOWUSAGE; 01257 /* pretend we have an extra "off" at the end. We can do this as the array 01258 * is NULL terminated so we overwrite that entry. 01259 */ 01260 a->argv[e->args+1] = "off"; 01261 a->argc++; 01262 } 01263 res = handle_core_set_debug_channel(e, cmd, a); 01264 if (cmd == CLI_INIT) 01265 e->command = "no debug channel"; 01266 return res; 01267 }
| static char* handle_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 270 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.
00271 { 00272 int x; 00273 00274 switch (cmd) { 00275 case CLI_INIT: 00276 e->command = "module reload"; 00277 e->usage = 00278 "Usage: module reload [module ...]\n" 00279 " Reloads configuration files for all listed modules which support\n" 00280 " reloading, or for all supported modules if none are listed.\n"; 00281 return NULL; 00282 00283 case CLI_GENERATE: 00284 return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 1); 00285 } 00286 if (a->argc == e->args) { 00287 ast_module_reload(NULL); 00288 return CLI_SUCCESS; 00289 } 00290 for (x = e->args; x < a->argc; x++) { 00291 int res = ast_module_reload(a->argv[x]); 00292 /* XXX reload has multiple error returns, including -1 on error and 2 on success */ 00293 switch (res) { 00294 case 0: 00295 ast_cli(a->fd, "No such module '%s'\n", a->argv[x]); 00296 break; 00297 case 1: 00298 ast_cli(a->fd, "Module '%s' does not support reload\n", a->argv[x]); 00299 break; 00300 } 00301 } 00302 return CLI_SUCCESS; 00303 }
| static char* handle_showcalls | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 736 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.
00737 { 00738 struct timeval curtime = ast_tvnow(); 00739 int showuptime, printsec; 00740 00741 switch (cmd) { 00742 case CLI_INIT: 00743 e->command = "core show calls [uptime]"; 00744 e->usage = 00745 "Usage: core show calls [uptime] [seconds]\n" 00746 " Lists number of currently active calls and total number of calls\n" 00747 " processed through PBX since last restart. If 'uptime' is specified\n" 00748 " the system uptime is also displayed. If 'seconds' is specified in\n" 00749 " addition to 'uptime', the system uptime is displayed in seconds.\n"; 00750 return NULL; 00751 00752 case CLI_GENERATE: 00753 if (a->pos != e->args) 00754 return NULL; 00755 return a->n == 0 ? ast_strdup("seconds") : NULL; 00756 } 00757 00758 /* regular handler */ 00759 if (a->argc >= e->args && !strcasecmp(a->argv[e->args-1],"uptime")) { 00760 showuptime = 1; 00761 00762 if (a->argc == e->args+1 && !strcasecmp(a->argv[e->args],"seconds")) 00763 printsec = 1; 00764 else if (a->argc == e->args) 00765 printsec = 0; 00766 else 00767 return CLI_SHOWUSAGE; 00768 } else if (a->argc == e->args-1) { 00769 showuptime = 0; 00770 printsec = 0; 00771 } else 00772 return CLI_SHOWUSAGE; 00773 00774 if (option_maxcalls) { 00775 ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n", 00776 ast_active_calls(), option_maxcalls, ESS(ast_active_calls()), 00777 ((double)ast_active_calls() / (double)option_maxcalls) * 100.0); 00778 } else { 00779 ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls())); 00780 } 00781 00782 ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls())); 00783 00784 if (ast_startuptime.tv_sec && showuptime) { 00785 print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec); 00786 } 00787 00788 return RESULT_SUCCESS; 00789 }
| static char* handle_showchan | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1269 of file cli.c.
References ast_channel::_bridge, ast_channel::_state, ast_channel::appl, ast_cli_args::argc, ast_cli_args::argv, ast_bridged_channel(), ast_cdr_serialize_variables(), ast_channel_unlock, ast_cli(), ast_complete_channels(), AST_FLAG_BLOCKING, ast_get_channel_by_name_locked(), ast_getformatname_multiple(), ast_state2str(), ast_str_buffer(), ast_str_thread_get(), ast_test_flag, ast_tvnow(), ast_channel::blockproc, ast_channel::callgroup, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel::context, ast_channel::data, DEBUGCHAN_FLAG, ast_channel::exten, ast_cli_args::fd, ast_channel::fds, ast_channel::fin, ast_channel::fout, ast_channel::language, ast_cli_args::line, ast_cli_args::n, name, ast_channel::name, ast_channel::nativeformats, pbx_builtin_serialize_variables(), ast_channel::pickupgroup, ast_cli_args::pos, ast_channel::priority, ast_channel::readformat, ast_channel::readtrans, ast_channel::rings, S_OR, sec, ast_cdr::start, ast_channel::tech, ast_channel_tech::type, ast_channel::uniqueid, ast_cli_entry::usage, ast_channel::whentohangup, ast_cli_args::word, ast_channel::writeformat, and ast_channel::writetrans.
01270 { 01271 struct ast_channel *c=NULL; 01272 struct timeval now; 01273 struct ast_str *out = ast_str_thread_get(&ast_str_thread_global_buf, 16); 01274 char cdrtime[256]; 01275 char nf[256], wf[256], rf[256]; 01276 long elapsed_seconds=0; 01277 int hour=0, min=0, sec=0; 01278 #ifdef CHANNEL_TRACE 01279 int trace_enabled; 01280 #endif 01281 01282 switch (cmd) { 01283 case CLI_INIT: 01284 e->command = "core show channel"; 01285 e->usage = 01286 "Usage: core show channel <channel>\n" 01287 " Shows lots of information about the specified channel.\n"; 01288 return NULL; 01289 case CLI_GENERATE: 01290 return ast_complete_channels(a->line, a->word, a->pos, a->n, 3); 01291 } 01292 01293 if (a->argc != 4) 01294 return CLI_SHOWUSAGE; 01295 now = ast_tvnow(); 01296 c = ast_get_channel_by_name_locked(a->argv[3]); 01297 if (!c) { 01298 ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); 01299 return CLI_SUCCESS; 01300 } 01301 if (c->cdr) { 01302 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01303 hour = elapsed_seconds / 3600; 01304 min = (elapsed_seconds % 3600) / 60; 01305 sec = elapsed_seconds % 60; 01306 snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec); 01307 } else 01308 strcpy(cdrtime, "N/A"); 01309 ast_cli(a->fd, 01310 " -- General --\n" 01311 " Name: %s\n" 01312 " Type: %s\n" 01313 " UniqueID: %s\n" 01314 " Caller ID: %s\n" 01315 " Caller ID Name: %s\n" 01316 " DNID Digits: %s\n" 01317 " Language: %s\n" 01318 " State: %s (%d)\n" 01319 " Rings: %d\n" 01320 " NativeFormats: %s\n" 01321 " WriteFormat: %s\n" 01322 " ReadFormat: %s\n" 01323 " WriteTranscode: %s\n" 01324 " ReadTranscode: %s\n" 01325 "1st File Descriptor: %d\n" 01326 " Frames in: %d%s\n" 01327 " Frames out: %d%s\n" 01328 " Time to Hangup: %ld\n" 01329 " Elapsed Time: %s\n" 01330 " Direct Bridge: %s\n" 01331 "Indirect Bridge: %s\n" 01332 " -- PBX --\n" 01333 " Context: %s\n" 01334 " Extension: %s\n" 01335 " Priority: %d\n" 01336 " Call Group: %llu\n" 01337 " Pickup Group: %llu\n" 01338 " Application: %s\n" 01339 " Data: %s\n" 01340 " Blocking in: %s\n", 01341 c->name, c->tech->type, c->uniqueid, 01342 S_OR(c->cid.cid_num, "(N/A)"), 01343 S_OR(c->cid.cid_name, "(N/A)"), 01344 S_OR(c->cid.cid_dnid, "(N/A)"), 01345 c->language, 01346 ast_state2str(c->_state), c->_state, c->rings, 01347 ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats), 01348 ast_getformatname_multiple(wf, sizeof(wf), c->writeformat), 01349 ast_getformatname_multiple(rf, sizeof(rf), c->readformat), 01350 c->writetrans ? "Yes" : "No", 01351 c->readtrans ? "Yes" : "No", 01352 c->fds[0], 01353 c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", 01354 c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", 01355 (long)c->whentohangup.tv_sec, 01356 cdrtime, c->_bridge ? c->_bridge->name : "<none>", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "<none>", 01357 c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ), 01358 ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"), 01359 (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)")); 01360 01361 if (pbx_builtin_serialize_variables(c, &out)) 01362 ast_cli(a->fd," Variables:\n%s\n", ast_str_buffer(out)); 01363 if (c->cdr && ast_cdr_serialize_variables(c->cdr, &out, '=', '\n', 1)) 01364 ast_cli(a->fd," CDR Variables:\n%s\n", ast_str_buffer(out)); 01365 #ifdef CHANNEL_TRACE 01366 trace_enabled = ast_channel_trace_is_enabled(c); 01367 ast_cli(a->fd, " Context Trace: %s\n", trace_enabled ? "Enabled" : "Disabled"); 01368 if (trace_enabled && ast_channel_trace_serialize(c, &out)) 01369 ast_cli(a->fd, " Trace:\n%s\n", ast_str_buffer(out)); 01370 #endif 01371 ast_channel_unlock(c); 01372 return CLI_SUCCESS; 01373 }
| static char* handle_showuptime | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 666 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.
00667 { 00668 struct timeval curtime = ast_tvnow(); 00669 int printsec; 00670 00671 switch (cmd) { 00672 case CLI_INIT: 00673 e->command = "core show uptime [seconds]"; 00674 e->usage = 00675 "Usage: core show uptime [seconds]\n" 00676 " Shows Asterisk uptime information.\n" 00677 " The seconds word returns the uptime in seconds only.\n"; 00678 return NULL; 00679 00680 case CLI_GENERATE: 00681 return NULL; 00682 } 00683 /* regular handler */ 00684 if (a->argc == e->args && !strcasecmp(a->argv[e->args-1],"seconds")) 00685 printsec = 1; 00686 else if (a->argc == e->args-1) 00687 printsec = 0; 00688 else 00689 return CLI_SHOWUSAGE; 00690 if (ast_startuptime.tv_sec) 00691 print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec); 00692 if (ast_lastreloadtime.tv_sec) 00693 print_uptimestr(a->fd, ast_tvsub(curtime, ast_lastreloadtime), "Last reload", printsec); 00694 return CLI_SUCCESS; 00695 }
| static char* handle_softhangup | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 913 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_unlock, ast_cli(), ast_complete_channels(), ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, 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.
00914 { 00915 struct ast_channel *c=NULL; 00916 00917 switch (cmd) { 00918 case CLI_INIT: 00919 e->command = "channel request hangup"; 00920 e->usage = 00921 "Usage: channel request hangup <channel>\n" 00922 " Request that a channel be hung up. The hangup takes effect\n" 00923 " the next time the driver reads or writes from the channel\n"; 00924 return NULL; 00925 case CLI_GENERATE: 00926 return ast_complete_channels(a->line, a->word, a->pos, a->n, e->args); 00927 } 00928 if (a->argc != 4) 00929 return CLI_SHOWUSAGE; 00930 c = ast_get_channel_by_name_locked(a->argv[3]); 00931 if (c) { 00932 ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name); 00933 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 00934 ast_channel_unlock(c); 00935 } else 00936 ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); 00937 return CLI_SUCCESS; 00938 }
| static char* handle_unload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 543 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), AST_FORCE_FIRM, AST_FORCE_HARD, AST_FORCE_SOFT, ast_module_helper(), ast_unload_resource(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, s, ast_cli_entry::usage, and ast_cli_args::word.
00544 { 00545 /* "module unload mod_1 [mod_2 .. mod_N]" */ 00546 int x; 00547 int force = AST_FORCE_SOFT; 00548 char *s; 00549 00550 switch (cmd) { 00551 case CLI_INIT: 00552 e->command = "module unload"; 00553 e->usage = 00554 "Usage: module unload [-f|-h] <module_1> [<module_2> ... ]\n" 00555 " Unloads the specified module from Asterisk. The -f\n" 00556 " option causes the module to be unloaded even if it is\n" 00557 " in use (may cause a crash) and the -h module causes the\n" 00558 " module to be unloaded even if the module says it cannot, \n" 00559 " which almost always will cause a crash.\n"; 00560 return NULL; 00561 00562 case CLI_GENERATE: 00563 return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0); 00564 } 00565 if (a->argc < e->args + 1) 00566 return CLI_SHOWUSAGE; 00567 x = e->args; /* first argument */ 00568 s = a->argv[x]; 00569 if (s[0] == '-') { 00570 if (s[1] == 'f') 00571 force = AST_FORCE_FIRM; 00572 else if (s[1] == 'h') 00573 force = AST_FORCE_HARD; 00574 else 00575 return CLI_SHOWUSAGE; 00576 if (a->argc < e->args + 2) /* need at least one module name */ 00577 return CLI_SHOWUSAGE; 00578 x++; /* skip this argument */ 00579 } 00580 00581 for (; x < a->argc; x++) { 00582 if (ast_unload_resource(a->argv[x], force)) { 00583 ast_cli(a->fd, "Unable to unload resource %s\n", a->argv[x]); 00584 return CLI_FAILURE; 00585 } 00586 } 00587 return CLI_SUCCESS; 00588 }
| static char* handle_verbose | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 362 of file cli.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_calloc, ast_clear_flag, ast_cli(), ast_complete_source_filename(), ast_free, AST_OPT_FLAG_DEBUG_FILE, AST_OPT_FLAG_VERBOSE_FILE, 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_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_number(), debug, ast_cli_args::fd, ast_debug_file::filename, find_debug_file(), ast_debug_file::level, ast_cli_args::n, option_debug, option_verbose, ast_cli_args::pos, S_OR, and ast_cli_entry::usage.
00363 { 00364 int oldval; 00365 int newlevel; 00366 int atleast = 0; 00367 int fd = a->fd; 00368 int argc = a->argc; 00369 char **argv = a->argv; 00370 char *argv3 = a->argv ? S_OR(a->argv[3], "") : ""; 00371 int *dst; 00372 char *what; 00373 struct debug_file_list *dfl; 00374 struct ast_debug_file *adf; 00375 char *fn; 00376 00377 switch (cmd) { 00378 case CLI_INIT: 00379 e->command = "core set {debug|verbose}"; 00380 e->usage = 00381 #if !defined(LOW_MEMORY) 00382 "Usage: core set {debug|verbose} [atleast] <level> [filename]\n" 00383 #else 00384 "Usage: core set {debug|verbose} [atleast] <level>\n" 00385 #endif 00386 " core set {debug|verbose} off\n" 00387 #if !defined(LOW_MEMORY) 00388 " Sets level of debug or verbose messages to be displayed or \n" 00389 " sets a filename to display debug messages from.\n" 00390 #else 00391 " Sets level of debug or verbose messages to be displayed.\n" 00392 #endif 00393 " 0 or off means no messages should be displayed.\n" 00394 " Equivalent to -d[d[...]] or -v[v[v...]] on startup\n"; 00395 return NULL; 00396 00397 case CLI_GENERATE: 00398 if (a->pos == 3 || (a->pos == 4 && !strcasecmp(a->argv[3], "atleast"))) { 00399 char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], ""); 00400 int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21; 00401 if (a->n < 21 && numbermatch == 0) { 00402 return complete_number(pos, 0, 0x7fffffff, a->n); 00403 } else if (pos[0] == '0') { 00404 if (a->n == 0) { 00405 return ast_strdup("0"); 00406 } else { 00407 return NULL; 00408 } 00409 } else if (a->n == (21 - numbermatch)) { 00410 if (a->pos == 3 && !strncasecmp(argv3, "off", strlen(argv3))) { 00411 return ast_strdup("off"); 00412 } else if (a->pos == 3 && !strncasecmp(argv3, "atleast", strlen(argv3))) { 00413 return ast_strdup("atleast"); 00414 } 00415 } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) { 00416 return ast_strdup("atleast"); 00417 } 00418 #if !defined(LOW_MEMORY) 00419 } else if (a->pos == 4 || (a->pos == 5 && !strcasecmp(argv3, "atleast"))) { 00420 return ast_complete_source_filename(a->pos == 4 ? S_OR(a->argv[4], "") : S_OR(a->argv[5], ""), a->n); 00421 #endif 00422 } 00423 return NULL; 00424 } 00425 /* all the above return, so we proceed with the handler. 00426 * we are guaranteed to be called with argc >= e->args; 00427 */ 00428 00429 if (argc <= e->args) 00430 return CLI_SHOWUSAGE; 00431 if (!strcasecmp(argv[e->args - 1], "debug")) { 00432 dst = &option_debug; 00433 oldval = option_debug; 00434 what = "Core debug"; 00435 } else { 00436 dst = &option_verbose; 00437 oldval = option_verbose; 00438 what = "Verbosity"; 00439 } 00440 if (argc == e->args + 1 && !strcasecmp(argv[e->args], "off")) { 00441 unsigned int debug = (*what == 'C'); 00442 newlevel = 0; 00443 00444 dfl = debug ? &debug_files : &verbose_files; 00445 00446 AST_RWLIST_WRLOCK(dfl); 00447 while ((adf = AST_RWLIST_REMOVE_HEAD(dfl, entry))) 00448 ast_free(adf); 00449 ast_clear_flag(&ast_options, debug ? AST_OPT_FLAG_DEBUG_FILE : AST_OPT_FLAG_VERBOSE_FILE); 00450 AST_RWLIST_UNLOCK(dfl); 00451 00452 goto done; 00453 } 00454 if (!strcasecmp(argv[e->args], "atleast")) 00455 atleast = 1; 00456 if (argc != e->args + atleast + 1 && argc != e->args + atleast + 2) 00457 return CLI_SHOWUSAGE; 00458 if (sscanf(argv[e->args + atleast], "%30d", &newlevel) != 1) 00459 return CLI_SHOWUSAGE; 00460 if (argc == e->args + atleast + 2) { 00461 unsigned int debug = (*what == 'C'); 00462 dfl = debug ? &debug_files : &verbose_files; 00463 00464 fn = argv[e->args + atleast + 1]; 00465 00466 AST_RWLIST_WRLOCK(dfl); 00467 00468 if ((adf = find_debug_file(fn, debug)) && !newlevel) { 00469 AST_RWLIST_REMOVE(dfl, adf, entry); 00470 if (AST_RWLIST_EMPTY(dfl)) 00471 ast_clear_flag(&ast_options, debug ? AST_OPT_FLAG_DEBUG_FILE : AST_OPT_FLAG_VERBOSE_FILE); 00472 AST_RWLIST_UNLOCK(dfl); 00473 ast_cli(fd, "%s was %d and has been set to 0 for '%s'\n", what, adf->level, fn); 00474 ast_free(adf); 00475 return CLI_SUCCESS; 00476 } 00477 00478 if (adf) { 00479 if ((atleast && newlevel < adf->level) || adf->level == newlevel) { 00480 ast_cli(fd, "%s is %d for '%s'\n", what, adf->level, fn); 00481 AST_RWLIST_UNLOCK(dfl); 00482 return CLI_SUCCESS; 00483 } 00484 } else if (!(adf = ast_calloc(1, sizeof(*adf) + strlen(fn) + 1))) { 00485 AST_RWLIST_UNLOCK(dfl); 00486 return CLI_FAILURE; 00487 } 00488 00489 oldval = adf->level; 00490 adf->level = newlevel; 00491 strcpy(adf->filename, fn); 00492 00493 ast_set_flag(&ast_options, debug ? AST_OPT_FLAG_DEBUG_FILE : AST_OPT_FLAG_VERBOSE_FILE); 00494 00495 AST_RWLIST_INSERT_TAIL(dfl, adf, entry); 00496 AST_RWLIST_UNLOCK(dfl); 00497 00498 ast_cli(fd, "%s was %d and has been set to %d for '%s'\n", what, oldval, adf->level, adf->filename); 00499 00500 return CLI_SUCCESS; 00501 } 00502 00503 done: 00504 if (!atleast || newlevel > *dst) 00505 *dst = newlevel; 00506 if (oldval > 0 && *dst == 0) 00507 ast_cli(fd, "%s is now OFF\n", what); 00508 else if (*dst > 0) { 00509 if (oldval == *dst) 00510 ast_cli(fd, "%s is at least %d\n", what, *dst); 00511 else 00512 ast_cli(fd, "%s was %d and is now %d\n", what, oldval, *dst); 00513 } 00514 00515 return CLI_SUCCESS; 00516 }
| static char* help1 | ( | int | fd, | |
| char * | match[], | |||
| int | locked | |||
| ) | [static] |
helper for final part of handle_help if locked = 1, assume the list is already locked
Definition at line 1952 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().
01953 { 01954 char matchstr[80] = ""; 01955 struct ast_cli_entry *e = NULL; 01956 int len = 0; 01957 int found = 0; 01958 01959 if (match) { 01960 ast_join(matchstr, sizeof(matchstr), match); 01961 len = strlen(matchstr); 01962 } 01963 if (!locked) 01964 AST_RWLIST_RDLOCK(&helpers); 01965 while ( (e = cli_next(e)) ) { 01966 /* Hide commands that start with '_' */ 01967 if (e->_full_cmd[0] == '_') 01968 continue; 01969 if (match && strncasecmp(matchstr, e->_full_cmd, len)) 01970 continue; 01971 ast_cli(fd, "%30.30s %s\n", e->_full_cmd, S_OR(e->summary, "<no description available>")); 01972 found++; 01973 } 01974 if (!locked) 01975 AST_RWLIST_UNLOCK(&helpers); 01976 if (!found && matchstr[0]) 01977 ast_cli(fd, "No such command '%s'.\n", matchstr); 01978 return CLI_SUCCESS; 01979 }
| 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 1723 of file cli.c.
References ast_strdup, ast_strlen_zero(), and s.
Referenced by __ast_cli_generator().
01725 { 01726 int lw; 01727 char *s, *t1; 01728 01729 *actual = 0; 01730 if (ast_strlen_zero(token)) 01731 return NULL; 01732 if (ast_strlen_zero(word)) 01733 word = ""; /* dummy */ 01734 lw = strlen(word); 01735 if (strcspn(word, cli_rsvd) != lw) 01736 return NULL; /* no match if word has reserved chars */ 01737 if (strchr(cli_rsvd, token[0]) == NULL) { /* regular match */ 01738 if (strncasecmp(token, word, lw)) /* no match */ 01739 return NULL; 01740 *actual = 1; 01741 return (pos != 0) ? NULL : ast_strdup(token); 01742 } 01743 /* now handle regexp match */ 01744 01745 /* Wildcard always matches, so we never do is_prefix on them */ 01746 01747 t1 = ast_strdupa(token + 1); /* copy, skipping first char */ 01748 while (pos >= 0 && (s = strsep(&t1, cli_rsvd)) && *s) { 01749 if (*s == '%') /* wildcard */ 01750 continue; 01751 if (strncasecmp(s, word, lw)) /* no match */ 01752 continue; 01753 (*actual)++; 01754 if (pos-- == 0) 01755 return ast_strdup(s); 01756 } 01757 return NULL; 01758 }
| static int modlist_modentry | ( | const char * | module, | |
| const char * | description, | |||
| int | usecnt, | |||
| const char * | like | |||
| ) | [static] |
Definition at line 596 of file cli.c.
References ast_cli(), and MODLIST_FORMAT.
Referenced by handle_modlist().
00597 { 00598 /* Comparing the like with the module */ 00599 if (strcasestr(module, like) ) { 00600 ast_cli(climodentryfd, MODLIST_FORMAT, module, description, usecnt); 00601 return 1; 00602 } 00603 return 0; 00604 }
| static int more_words | ( | char *const * | dst | ) | [static] |
returns true if there are more words to match
Definition at line 2158 of file cli.c.
Referenced by __ast_cli_generator().
| static char* parse_args | ( | const char * | s, | |
| int * | argc, | |||
| char * | argv[], | |||
| int | max, | |||
| int * | trailingwhitespace | |||
| ) | [static] |
Definition at line 2027 of file cli.c.
References ast_log(), ast_strdup, dummy(), and LOG_WARNING.
Referenced by __ast_cli_generator(), and ast_cli_command_full().
02028 { 02029 char *duplicate, *cur; 02030 int x = 0; 02031 int quoted = 0; 02032 int escaped = 0; 02033 int whitespace = 1; 02034 int dummy = 0; 02035 02036 if (trailingwhitespace == NULL) 02037 trailingwhitespace = &dummy; 02038 *trailingwhitespace = 0; 02039 if (s == NULL) /* invalid, though! */ 02040 return NULL; 02041 /* make a copy to store the parsed string */ 02042 if (!(duplicate = ast_strdup(s))) 02043 return NULL; 02044 02045 cur = duplicate; 02046 /* scan the original string copying into cur when needed */ 02047 for (; *s ; s++) { 02048 if (x >= max - 1) { 02049 ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s); 02050 break; 02051 } 02052 if (*s == '"' && !escaped) { 02053 quoted = !quoted; 02054 if (quoted && whitespace) { 02055 /* start a quoted string from previous whitespace: new argument */ 02056 argv[x++] = cur; 02057 whitespace = 0; 02058 } 02059 } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) { 02060 /* If we are not already in whitespace, and not in a quoted string or 02061 processing an escape sequence, and just entered whitespace, then 02062 finalize the previous argument and remember that we are in whitespace 02063 */ 02064 if (!whitespace) { 02065 *cur++ = '\0'; 02066 whitespace = 1; 02067 } 02068 } else if (*s == '\\' && !escaped) { 02069 escaped = 1; 02070 } else { 02071 if (whitespace) { 02072 /* we leave whitespace, and are not quoted. So it's a new argument */ 02073 argv[x++] = cur; 02074 whitespace = 0; 02075 } 02076 *cur++ = *s; 02077 escaped = 0; 02078 } 02079 } 02080 /* Null terminate */ 02081 *cur++ = '\0'; 02082 /* XXX put a NULL in the last argument, because some functions that take 02083 * the array may want a null-terminated array. 02084 * argc still reflects the number of non-NULL entries. 02085 */ 02086 argv[x] = NULL; 02087 *argc = x; 02088 *trailingwhitespace = whitespace; 02089 return duplicate; 02090 }
| static void print_uptimestr | ( | int | fd, | |
| struct timeval | timeval, | |||
| const char * | prefix, | |||
| int | printsec | |||
| ) | [static] |
Definition at line 606 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().
00607 { 00608 int x; /* the main part - years, weeks, etc. */ 00609 struct ast_str *out; 00610 00611 #define SECOND (1) 00612 #define MINUTE (SECOND*60) 00613 #define HOUR (MINUTE*60) 00614 #define DAY (HOUR*24) 00615 #define WEEK (DAY*7) 00616 #define YEAR (DAY*365) 00617 #define NEEDCOMMA(x) ((x)? ",": "") /* define if we need a comma */ 00618 if (timeval.tv_sec < 0) /* invalid, nothing to show */ 00619 return; 00620 00621 if (printsec) { /* plain seconds output */ 00622 ast_cli(fd, "%s: %lu\n", prefix, (u_long)timeval.tv_sec); 00623 return; 00624 } 00625 out = ast_str_alloca(256); 00626 if (timeval.tv_sec > YEAR) { 00627 x = (timeval.tv_sec / YEAR); 00628 timeval.tv_sec -= (x * YEAR); 00629 ast_str_append(&out, 0, "%d year%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00630 } 00631 if (timeval.tv_sec > WEEK) { 00632 x = (timeval.tv_sec / WEEK); 00633 timeval.tv_sec -= (x * WEEK); 00634 ast_str_append(&out, 0, "%d week%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00635 } 00636 if (timeval.tv_sec > DAY) { 00637 x = (timeval.tv_sec / DAY); 00638 timeval.tv_sec -= (x * DAY); 00639 ast_str_append(&out, 0, "%d day%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00640 } 00641 if (timeval.tv_sec > HOUR) { 00642 x = (timeval.tv_sec / HOUR); 00643 timeval.tv_sec -= (x * HOUR); 00644 ast_str_append(&out, 0, "%d hour%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00645 } 00646 if (timeval.tv_sec > MINUTE) { 00647 x = (timeval.tv_sec / MINUTE); 00648 timeval.tv_sec -= (x * MINUTE); 00649 ast_str_append(&out, 0, "%d minute%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec)); 00650 } 00651 x = timeval.tv_sec; 00652 if (x > 0 || ast_str_strlen(out) == 0) /* if there is nothing, print 0 seconds */ 00653 ast_str_append(&out, 0, "%d second%s ", x, ESS(x)); 00654 ast_cli(fd, "%s: %s\n", prefix, ast_str_buffer(out)); 00655 }
| 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 1520 of file cli.c.
References ast_cli_entry::_full_cmd, ast_cli_entry::args, ast_join(), ast_log(), ast_strdup, buf, ast_cli_entry::cmda, ast_cli_entry::cmdlen, and LOG_WARNING.
Referenced by __ast_cli_register().
01521 { 01522 int i; 01523 char buf[80]; 01524 01525 ast_join(buf, sizeof(buf), e->cmda); 01526 e->_full_cmd = ast_strdup(buf); 01527 if (!e->_full_cmd) { 01528 ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf); 01529 return -1; 01530 } 01531 e->cmdlen = strcspn(e->_full_cmd, cli_rsvd); 01532 for (i = 0; e->cmda[i]; i++) 01533 ; 01534 e->args = i; 01535 return 0; 01536 }
| 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 1694 of file cli.c.
References ast_strlen_zero().
Referenced by __ast_cli_generator(), and find_cli().
01695 { 01696 int l; 01697 char *pos; 01698 01699 if (ast_strlen_zero(cmd) || ast_strlen_zero(cli_word)) 01700 return -1; 01701 if (!strchr(cli_rsvd, cli_word[0])) /* normal match */ 01702 return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1; 01703 /* regexp match, takes [foo|bar] or {foo|bar} */ 01704 l = strlen(cmd); 01705 /* wildcard match - will extend in the future */ 01706 if (l > 0 && cli_word[0] == '%') { 01707 return 1; /* wildcard */ 01708 } 01709 pos = strcasestr(cli_word, cmd); 01710 if (pos == NULL) /* not found, say ok if optional */ 01711 return cli_word[0] == '[' ? 0 : -1; 01712 if (pos == cli_word) /* no valid match at the beginning */ 01713 return -1; 01714 if (strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) 01715 return 1; /* valid match */ 01716 return -1; /* not found */ 01717 }
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 = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 593 of file cli.c.
Referenced by handle_modlist().
struct debug_file_list debug_files [static] |
const char perms_config[] = "cli_permissions.conf" [static] |
CLI permissions config file.
Definition at line 70 of file cli.c.
Referenced by ast_cli_perms_init().
ast_mutex_t permsconfiglock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
struct debug_file_list verbose_files [static] |
1.6.2