Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
main/cli.c File Reference

Standard Command Line Interface. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include <signal.h>
#include <ctype.h>
#include <regex.h>
#include <pwd.h>
#include <grp.h>
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/lock.h"
#include "asterisk/threadstorage.h"
#include "asterisk/logger_category.h"
#include "asterisk/translate.h"
#include "asterisk/bridge.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/vector.h"
#include "asterisk/stream.h"
Include dependency graph for main/cli.c:

Go to the source code of this file.

Data Structures

struct  channel_set_debug_args
 
struct  cli_perm
 List of restrictions per user. More...
 
struct  cli_perm_head
 
struct  cli_perms
 List of users and permissions. More...
 
struct  helpers
 
struct  module_level
 map a debug or verbose level to a module name More...
 
struct  module_level_list
 
struct  usergroup_cli_perm
 list of users to apply restrictions. More...
 

Macros

#define AST_CLI_INITLEN   256
 
#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
 
#define DAY   (HOUR*24)
 
#define DEBUG_HANDLER   0
 
#define FORMAT_STRING   "%-20.20s %-20.20s %-7.7s %-30.30s\n"
 
#define FORMAT_STRING   "%-25s %-20s %-20s\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 %-11s %13s\n"
 
#define MODLIST_FORMAT2   "%-30s %-40.40s %-10s %-11s %13s\n"
 
#define NEEDCOMMA(x)   ((x) ? ", " : "") /* define if we need a comma */
 
#define SECOND   (1)
 
#define TRACE_HANDLER   1
 
#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
 
#define VERBOSE_FORMAT_STRING2   "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
 
#define VERBOSE_HANDLER   2
 
#define WEEK   (DAY*7)
 
#define YEAR   (DAY*365)
 

Functions

static char * __ast_cli_generator (const char *text, const char *word, int state, int lock)
 
int __ast_cli_register (struct ast_cli_entry *e, struct ast_module *module)
 
int __ast_cli_register_multiple (struct ast_cli_entry *e, int len, struct ast_module *module)
 
static void __init_ast_cli_buf (void)
 
static int allowed_on_shutdown (struct ast_cli_entry *e)
 
void ast_builtins_init (void)
 initialize the _full_cmd string in * each of the builtins. More...
 
int ast_cli_allow_at_shutdown (struct ast_cli_entry *e)
 
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. More...
 
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. More...
 
char * ast_cli_complete (const char *word, const char *const choices[], int state)
 
int ast_cli_completion_add (char *value)
 Add a result to a request for completion options. More...
 
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. More...
 
struct ast_vector_string * ast_cli_completion_vector (const char *text, const char *word)
 Generates a vector of strings for CLI completion. More...
 
char * ast_cli_generator (const char *text, const char *word, int state)
 Readline madness Useful for readline, that's about it. More...
 
int ast_cli_perms_init (int reload)
 
void ast_cli_print_timestr_fromseconds (int fd, int seconds, const char *prefix)
 Print on cli a duration in seconds in format s year(s), s week(s), s day(s), s hour(s), s second(s) More...
 
int ast_cli_unregister (struct ast_cli_entry *e)
 Unregisters a command or an array of commands. More...
 
int ast_cli_unregister_multiple (struct ast_cli_entry *e, int len)
 Unregister multiple commands. More...
 
char * ast_complete_channels (const char *line, const char *word, int pos, int state, int rpos)
 Command completion for the list of active channels. More...
 
unsigned int ast_debug_get_by_module (const char *module)
 Get the debug level for a module. More...
 
 AST_THREADSTORAGE_RAW (completion_storage)
 
unsigned int ast_trace_get_by_module (const char *module)
 Get the trace level for a module. More...
 
static AST_VECTOR (struct ast_cli_entry *)
 
static int channel_set_debug (void *obj, void *arg, void *data, int flags)
 
static int cli_completion_vector_add (struct ast_vector_string *vec, char *value)
 
static int cli_has_permissions (int uid, int gid, const char *command)
 
static int cli_is_registered (struct ast_cli_entry *e)
 
static struct ast_cli_entrycli_next (struct ast_cli_entry *e)
 
static void cli_shutdown (void)
 
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. More...
 
static char * find_best (const char *argv[])
 
static struct ast_cli_entryfind_cli (const char *const cmds[], int match_type)
 
static struct module_levelfind_module_level (const char *module, struct module_level_list *mll)
 Find the module level setting. More...
 
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' More...
 
static char * handle_cli_malloc_trim (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_reload_permissions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handles CLI command 'cli reload permissions' More...
 
static char * handle_cli_show_permissions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handles CLI command 'cli show permissions' More...
 
static char * handle_cli_wait_fullybooted (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_core_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_core_set_debug_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_debug_category (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_debug_or_trace (int handler, 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_trace (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_unload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_verbose (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * help1 (int fd, const char *const match[], int locked)
 helper for final part of handle_help if locked = 1, assume the list is already locked More...
 
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. More...
 
static int modlist_modentry (const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level)
 
static int more_words (const char *const *dst)
 returns true if there are more words to match More...
 
static char * parse_args (const char *s, int *argc, const char *argv[], int max, int *trailingwhitespace)
 
static void print_uptimestr (int fd, struct timeval timeval, const char *prefix, int printsec)
 
static void remove_shutdown_command (struct ast_cli_entry *e)
 
static int set_full_cmd (struct ast_cli_entry *e)
 
static void status_debug_verbose (struct ast_cli_args *a, int handler, int old_val, int cur_val)
 
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. More...
 
static struct cli_perms cli_perms = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static const char cli_rsvd [] = "[]{}|*%"
 
static int climodentryfd = -1
 
static ast_mutex_t climodentrylock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static struct module_level_list debug_modules = AST_RWLIST_HEAD_INIT_VALUE
 
static struct helpers helpers = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static const char perms_config [] = "cli_permissions.conf"
 CLI permissions config file. More...
 
static ast_mutex_t permsconfiglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 mutex used to prevent a user from running the 'cli reload permissions' command while it is already running. More...
 
static ast_rwlock_t shutdown_commands_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
 
static struct module_level_list trace_modules = AST_RWLIST_HEAD_INIT_VALUE
 

Detailed Description

Standard Command Line Interface.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file main/cli.c.

Macro Definition Documentation

◆ AST_CLI_INITLEN

#define AST_CLI_INITLEN   256

Referenced by AST_VECTOR().

◆ CONCISE_FORMAT_STRING

#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"

Referenced by handle_chanlist().

◆ DAY

#define DAY   (HOUR*24)

Referenced by print_uptimestr().

◆ DEBUG_HANDLER

#define DEBUG_HANDLER   0

Definition at line 403 of file main/cli.c.

Referenced by handle_debug(), handle_debug_or_trace(), and status_debug_verbose().

◆ FORMAT_STRING [1/2]

#define FORMAT_STRING   "%-20.20s %-20.20s %-7.7s %-30.30s\n"

◆ FORMAT_STRING [2/2]

#define FORMAT_STRING   "%-25s %-20s %-20s\n"

◆ FORMAT_STRING2

#define FORMAT_STRING2   "%-20.20s %-20.20s %-7.7s %-30.30s\n"

Referenced by handle_chanlist().

◆ HOUR

#define HOUR   (MINUTE*60)

Referenced by print_uptimestr().

◆ MINUTE

#define MINUTE   (SECOND*60)

Referenced by print_uptimestr().

◆ MODLIST_FORMAT

#define MODLIST_FORMAT   "%-30s %-40.40s %-10d %-11s %13s\n"

Definition at line 857 of file main/cli.c.

Referenced by modlist_modentry().

◆ MODLIST_FORMAT2

#define MODLIST_FORMAT2   "%-30s %-40.40s %-10s %-11s %13s\n"

Definition at line 858 of file main/cli.c.

Referenced by handle_modlist().

◆ NEEDCOMMA

#define NEEDCOMMA (   x)    ((x) ? ", " : "") /* define if we need a comma */

Referenced by print_uptimestr().

◆ SECOND

#define SECOND   (1)

◆ TRACE_HANDLER

#define TRACE_HANDLER   1

Definition at line 404 of file main/cli.c.

Referenced by handle_trace(), and status_debug_verbose().

◆ VERBOSE_FORMAT_STRING

#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"

Referenced by handle_chanlist().

◆ VERBOSE_FORMAT_STRING2

#define VERBOSE_FORMAT_STRING2   "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"

Referenced by handle_chanlist().

◆ VERBOSE_HANDLER

#define VERBOSE_HANDLER   2

Definition at line 405 of file main/cli.c.

Referenced by handle_verbose(), and status_debug_verbose().

◆ WEEK

#define WEEK   (DAY*7)

Referenced by print_uptimestr().

◆ YEAR

#define YEAR   (DAY*365)

Referenced by print_uptimestr().

Function Documentation

◆ __ast_cli_generator()

static char * __ast_cli_generator ( const char *  text,
const char *  word,
int  state,
int  lock 
)
static

Definition at line 2829 of file main/cli.c.

References ast_cli_args::argv, ARRAY_LEN, ast_free, ast_join, AST_MAX_ARGS, ast_module_running_ref, ast_module_unref, 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, ast_cli_entry::module, more_words(), NULL, parse_args(), and word_match().

Referenced by ast_cli_generator(), handle_cli_check_permissions(), and handle_help().

2830 {
2831  const char *argv[AST_MAX_ARGS];
2832  struct ast_cli_entry *e = NULL;
2833  int x = 0, argindex, matchlen;
2834  int matchnum=0;
2835  char *ret = NULL;
2836  char matchstr[80] = "";
2837  int tws = 0;
2838  /* Split the argument into an array of words */
2839  char *duplicate = parse_args(text, &x, argv, ARRAY_LEN(argv), &tws);
2840 
2841  if (!duplicate) /* malloc error */
2842  return NULL;
2843 
2844  /* Compute the index of the last argument (could be an empty string) */
2845  argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x;
2846 
2847  /* rebuild the command, ignore terminating white space and flatten space */
2848  ast_join(matchstr, sizeof(matchstr)-1, argv);
2849  matchlen = strlen(matchstr);
2850  if (tws) {
2851  strcat(matchstr, " "); /* XXX */
2852  if (matchlen)
2853  matchlen++;
2854  }
2855  if (lock)
2857  while ( (e = cli_next(e)) ) {
2858  /* XXX repeated code */
2859  int src = 0, dst = 0, n = 0;
2860 
2861  if (e->command[0] == '_')
2862  continue;
2863 
2864  /*
2865  * Try to match words, up to and excluding the last word, which
2866  * is either a blank or something that we want to extend.
2867  */
2868  for (;src < argindex; dst++, src += n) {
2869  n = word_match(argv[src], e->cmda[dst]);
2870  if (n < 0)
2871  break;
2872  }
2873 
2874  if (src != argindex && more_words(e->cmda + dst)) /* not a match */
2875  continue;
2876  ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n);
2877  matchnum += n; /* this many matches here */
2878  if (ret) {
2879  /*
2880  * argv[src] is a valid prefix of the next word in this
2881  * command. If this is also the correct entry, return it.
2882  */
2883  if (matchnum > state)
2884  break;
2885  ast_free(ret);
2886  ret = NULL;
2887  } else if (ast_strlen_zero(e->cmda[dst])) {
2888  /*
2889  * This entry is a prefix of the command string entered
2890  * (only one entry in the list should have this property).
2891  * Run the generator if one is available. In any case we are done.
2892  */
2893  if (e->handler) { /* new style command */
2894  struct ast_cli_args a = {
2895  .line = matchstr, .word = word,
2896  .pos = argindex,
2897  .n = state - matchnum,
2898  .argv = argv,
2899  .argc = x};
2900 
2901  /* If the command is in a module it must be running. */
2902  if (!e->module || ast_module_running_ref(e->module)) {
2903  ret = e->handler(e, CLI_GENERATE, &a);
2905  }
2906  }
2907  if (ret)
2908  break;
2909  }
2910  }
2911  if (lock)
2913  ast_free(duplicate);
2914  return ret;
2915 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define ast_join(s, len, w)
Definition: strings.h:483
descriptor for a cli entry.
Definition: cli.h:171
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static int more_words(const char *const *dst)
returns true if there are more words to match
Definition: main/cli.c:2816
char * text
Definition: app_queue.c:1508
#define NULL
Definition: resample.c:96
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
char *(* handler)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cli.h:187
ast_mutex_t lock
Definition: app_meetme.c:1091
const char *const * argv
Definition: cli.h:161
static char * parse_args(const char *s, int *argc, const char *argv[], int max, int *trailingwhitespace)
Definition: main/cli.c:2598
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
#define AST_MAX_ARGS
Definition: cli.h:50
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
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.
Definition: main/cli.c:2266
static int word_match(const char *cmd, const char *cli_word)
Definition: main/cli.c:2227
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:172
struct ast_module * module
Definition: cli.h:180
short word
static struct test_val a
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: main/cli.c:929

◆ __ast_cli_register()

int __ast_cli_register ( struct ast_cli_entry e,
struct ast_module module 
)

Definition at line 2420 of file main/cli.c.

References ast_cli_entry::_full_cmd, ast_free, ast_log, AST_MAX_CMD_LEN, AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_skip_blanks(), ast_skip_nonblanks(), ast_strdup, ast_strlen_zero, CLI_INIT, cli_is_registered(), ast_cli_entry::cmda, ast_cli_entry::cmdlen, ast_cli_entry::command, done, find_cli(), ast_cli_entry::handler, len(), cli_perm::list, LOG_WARNING, ast_cli_entry::module, NULL, S_OR, and set_full_cmd().

Referenced by __ast_cli_register_multiple().

2421 {
2422  struct ast_cli_entry *cur;
2423  int i, lf, ret = -1;
2424 
2425  struct ast_cli_args a; /* fake argument */
2426  char **dst = (char **)e->cmda; /* need to cast as the entry is readonly */
2427  char *s;
2428 
2430 
2431  if (cli_is_registered(e)) {
2432  ast_log(LOG_WARNING, "Command '%s' already registered (the same ast_cli_entry)\n",
2433  S_OR(e->_full_cmd, e->command));
2434  ret = 0; /* report success */
2435  goto done;
2436  }
2437 
2438  memset(&a, '\0', sizeof(a));
2439 
2440  e->module = module;
2441  /* No module reference needed here, the module called us. */
2442  e->handler(e, CLI_INIT, &a);
2443 
2444  /* XXX check that usage and command are filled up */
2445  s = ast_skip_blanks(e->command);
2446  s = e->command = ast_strdup(s);
2447  for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) {
2448  *dst++ = s; /* store string */
2449  s = ast_skip_nonblanks(s);
2450  if (*s == '\0') /* we are done */
2451  break;
2452  *s++ = '\0';
2453  s = ast_skip_blanks(s);
2454  }
2455  *dst++ = NULL;
2456 
2457  if (find_cli(e->cmda, 1)) {
2458  ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n",
2459  S_OR(e->_full_cmd, e->command));
2460  goto done;
2461  }
2462  if (set_full_cmd(e)) {
2463  ast_log(LOG_WARNING, "Error registering CLI Command '%s'\n",
2464  S_OR(e->_full_cmd, e->command));
2465  goto done;
2466  }
2467 
2468  lf = e->cmdlen;
2470  int len = cur->cmdlen;
2471  if (lf < len)
2472  len = lf;
2473  if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) {
2475  break;
2476  }
2477  }
2479 
2480  if (!cur)
2481  AST_RWLIST_INSERT_TAIL(&helpers, e, list);
2482  ret = 0; /* success */
2483 
2484 done:
2486  if (ret) {
2487  ast_free(e->command);
2488  e->command = NULL;
2489  }
2490 
2491  return ret;
2492 }
char * _full_cmd
Definition: cli.h:181
int cmdlen
Definition: cli.h:182
static int cli_is_registered(struct ast_cli_entry *e)
Definition: main/cli.c:2378
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
descriptor for a cli entry.
Definition: cli.h:171
#define LOG_WARNING
Definition: logger.h:274
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:152
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
char * ast_skip_nonblanks(const char *str)
Gets a pointer to first whitespace character in a string.
Definition: strings.h:200
#define ast_strlen_zero(foo)
Definition: strings.h:52
int done
Definition: test_amihooks.c:48
#define ast_log
Definition: astobj2.c:42
char *(* handler)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cli.h:187
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:609
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
static struct ast_cli_entry * find_cli(const char *const cmds[], int match_type)
Definition: main/cli.c:2316
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:172
#define AST_MAX_CMD_LEN
Definition: cli.h:48
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616
static int set_full_cmd(struct ast_cli_entry *e)
Definition: main/cli.c:2046
struct ast_module * module
Definition: cli.h:180
static struct test_val a

◆ __ast_cli_register_multiple()

int __ast_cli_register_multiple ( struct ast_cli_entry e,
int  len,
struct ast_module module 
)

Definition at line 2497 of file main/cli.c.

References __ast_cli_register(), and len().

2498 {
2499  int i, res = 0;
2500 
2501  for (i = 0; i < len; i++) {
2502  res |= __ast_cli_register(e + i, module);
2503  }
2504 
2505  return res;
2506 }
int __ast_cli_register(struct ast_cli_entry *e, struct ast_module *module)
Definition: main/cli.c:2420
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ __init_ast_cli_buf()

static void __init_ast_cli_buf ( void  )
static

Definition at line 110 of file main/cli.c.

119 {

◆ allowed_on_shutdown()

static int allowed_on_shutdown ( struct ast_cli_entry e)
static

Definition at line 2922 of file main/cli.c.

References ast_rwlock_rdlock, ast_rwlock_unlock, AST_VECTOR_GET, AST_VECTOR_SIZE, and shutdown_commands_lock.

Referenced by ast_cli_command_full().

2923 {
2924  int found = 0;
2925  int i;
2926 
2928  for (i = 0; i < AST_VECTOR_SIZE(&shutdown_commands); ++i) {
2929  if (e == AST_VECTOR_GET(&shutdown_commands, i)) {
2930  found = 1;
2931  break;
2932  }
2933  }
2935 
2936  return found;
2937 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static ast_rwlock_t shutdown_commands_lock
Definition: main/cli.c:112
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_builtins_init()

void ast_builtins_init ( void  )

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 2209 of file main/cli.c.

References ARRAY_LEN, ast_cli_register_multiple, ast_register_cleanup(), AST_VECTOR_INIT, and cli_shutdown().

Referenced by asterisk_daemon().

2210 {
2211  AST_VECTOR_INIT(&shutdown_commands, 0);
2214 }
static void cli_shutdown(void)
Definition: main/cli.c:2203
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static struct ast_cli_entry cli_cli[]
Definition: main/cli.c:1984

◆ ast_cli_allow_at_shutdown()

int ast_cli_allow_at_shutdown ( struct ast_cli_entry e)

Definition at line 3026 of file main/cli.c.

References ast_rwlock_unlock, ast_rwlock_wrlock, AST_VECTOR_APPEND, and shutdown_commands_lock.

Referenced by handle_abort_shutdown(), handle_restart_gracefully(), handle_restart_now(), handle_restart_when_convenient(), handle_show_locks(), handle_stop_gracefully(), handle_stop_now(), and handle_stop_when_convenient().

3027 {
3028  int res;
3029 
3031  res = AST_VECTOR_APPEND(&shutdown_commands, e);
3033 
3034  return res;
3035 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define ast_rwlock_unlock(a)
Definition: lock.h:232
static ast_rwlock_t shutdown_commands_lock
Definition: main/cli.c:112
#define ast_rwlock_wrlock(a)
Definition: lock.h:234

◆ ast_cli_command_full()

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.

Parameters
uidUser ID that is trying to run the command.
gidGroup ID that is trying to run the command.
fdpipe
sincoming string
Return values
0on success
-1on failure

Definition at line 2939 of file main/cli.c.

References allowed_on_shutdown(), args, ast_atomic_fetchadd_int(), ast_cli(), ast_free, ast_join, AST_MAX_ARGS, ast_module_running_ref, ast_module_unref, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_shutting_down(), CLI_FAILURE, CLI_HANDLER, cli_has_permissions(), CLI_SHOWUSAGE, CLI_SUCCESS, done, ast_cli_args::fd, find_best(), find_cli(), ast_cli_entry::handler, ast_cli_entry::inuse, ast_cli_entry::module, NULL, parse_args(), RESULT_FAILURE, RESULT_SUCCESS, retval, S_OR, tmp(), and ast_cli_entry::usage.

Referenced by ast_cli_command_multiple_full().

2940 {
2941  const char *args[AST_MAX_ARGS + 1];
2942  struct ast_cli_entry *e = NULL;
2943  int x;
2944  char *duplicate = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL);
2945  char tmp[AST_MAX_ARGS + 1];
2946  char *retval = CLI_FAILURE;
2947  struct ast_cli_args a = {
2948  .fd = fd, .argc = x, .argv = args+1 };
2949 
2950  if (duplicate == NULL)
2951  return RESULT_FAILURE;
2952 
2953  if (x < 1) /* We need at least one entry, otherwise ignore */
2954  goto done;
2955 
2957  e = find_cli(args + 1, 0);
2958  if (e)
2961  if (e == NULL) {
2962  ast_cli(fd, "No such command '%s' (type 'core show help %s' for other possible commands)\n", s, find_best(args + 1));
2963  goto done;
2964  }
2965 
2966  if (ast_shutting_down() && !allowed_on_shutdown(e)) {
2967  ast_cli(fd, "Command '%s' cannot be run during shutdown\n", s);
2968  goto done;
2969  }
2970 
2971  ast_join(tmp, sizeof(tmp), args + 1);
2972  /* Check if the user has rights to run this command. */
2973  if (!cli_has_permissions(uid, gid, tmp)) {
2974  ast_cli(fd, "You don't have permissions to run '%s' command\n", tmp);
2975  goto done;
2976  }
2977 
2978  /*
2979  * Within the handler, argv[-1] contains a pointer to the ast_cli_entry.
2980  * Remember that the array returned by parse_args is NULL-terminated.
2981  */
2982  args[0] = (char *)e;
2983 
2984  /* If the command is in a module it must be running. */
2985  if (!e->module || ast_module_running_ref(e->module)) {
2986  retval = e->handler(e, CLI_HANDLER, &a);
2988  }
2989 
2990  if (retval == CLI_SHOWUSAGE) {
2991  ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
2992  } else if (retval == CLI_FAILURE) {
2993  ast_cli(fd, "Command '%s' failed.\n", s);
2994  }
2995 
2996 done:
2997  if (e) {
2998  ast_atomic_fetchadd_int(&e->inuse, -1);
2999  }
3000  ast_free(duplicate);
3001  return retval == CLI_SUCCESS ? RESULT_SUCCESS : RESULT_FAILURE;
3002 }
int ast_shutting_down(void)
Definition: asterisk.c:1834
#define ast_join(s, len, w)
Definition: strings.h:483
descriptor for a cli entry.
Definition: cli.h:171
static int tmp()
Definition: bt_open.c:389
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * args
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
static int allowed_on_shutdown(struct ast_cli_entry *e)
Definition: main/cli.c:2922
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
int done
Definition: test_amihooks.c:48
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
int inuse
Definition: cli.h:179
char *(* handler)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cli.h:187
const int fd
Definition: cli.h:159
static struct ast_cli_entry * find_cli(const char *const cmds[], int match_type)
Definition: main/cli.c:2316
static char * parse_args(const char *s, int *argc, const char *argv[], int max, int *trailingwhitespace)
Definition: main/cli.c:2598
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
#define AST_MAX_ARGS
Definition: cli.h:50
const char * usage
Definition: cli.h:177
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
#define CLI_SUCCESS
Definition: cli.h:44
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static ENTRY retval
Definition: hsearch.c:50
#define RESULT_SUCCESS
Definition: cli.h:40
static int cli_has_permissions(int uid, int gid, const char *command)
Definition: main/cli.c:183
static char * find_best(const char *argv[])
Definition: main/cli.c:2360
struct ast_module * module
Definition: cli.h:180
#define RESULT_FAILURE
Definition: cli.h:42
static struct test_val a

◆ ast_cli_command_multiple_full()

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.

Parameters
uidUser ID that is trying to run the command.
gidGroup ID that is trying to run the command.
fdpipe
sizeis the total size of the string
sincoming string
Return values
numberof commands executed

Definition at line 3004 of file main/cli.c.

References ast_cli_command_full().

Referenced by netconsole().

3005 {
3006  char cmd[512];
3007  int x, y = 0, count = 0;
3008 
3009  for (x = 0; x < size; x++) {
3010  cmd[y] = s[x];
3011  y++;
3012  if (s[x] == '\0') {
3013  ast_cli_command_full(uid, gid, fd, cmd);
3014  y = 0;
3015  count++;
3016  }
3017  }
3018  return count;
3019 }
const int fd
Definition: cli.h:159
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 th...
Definition: main/cli.c:2939

◆ ast_cli_complete()

char* ast_cli_complete ( const char *  word,
const char *const  choices[],
int  pos 
)

Helper function to generate cli entries from a NULL-terminated array. Returns the n-th matching entry from the array, or NULL if not found. Can be used to implement generate() for static entries as below (in this example we complete the word in position 2):

char *my_generate(const char *line, const char *word, int pos, int n)
{
static const char * const choices[] = { "one", "two", "three", NULL };
if (pos == 2)
return ast_cli_complete(word, choices, n);
else
return NULL;
}

Definition at line 1811 of file main/cli.c.

References ast_cli_completion_add(), ast_strdup, ast_strlen_zero, len(), and NULL.

Referenced by cli_odbc_read(), cli_odbc_write(), complete_skinny_reset(), complete_skinny_show_line(), handle_bridge_kick_channel(), handle_cli_core_show_translation(), handle_cli_devstate_change(), handle_cli_iax2_prune_realtime(), handle_cli_presencestate_change(), handle_cli_rtp_drop_incoming_packets(), handle_core_set_debug_channel(), handle_orig(), handle_showcalls(), handle_softhangup(), sip_prune_realtime(), sip_qualify_peer(), sip_show_peer(), sip_show_user(), sorcery_memory_cache_stale(), test_cli_execute_registered(), test_cli_generate_results(), test_cli_show_registered(), and test_cli_show_results().

1812 {
1813  int i, which = 0, len;
1814  len = ast_strlen_zero(word) ? 0 : strlen(word);
1815 
1816  for (i = 0; choices[i]; i++) {
1817  if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state) {
1818  if (state != -1) {
1819  return ast_strdup(choices[i]);
1820  }
1821 
1822  if (ast_cli_completion_add(ast_strdup(choices[i]))) {
1823  return NULL;
1824  }
1825  }
1826  }
1827  return NULL;
1828 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
short word
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726

◆ ast_cli_completion_add()

int ast_cli_completion_add ( char *  value)

Add a result to a request for completion options.

Parameters
valueA completion option text.
Return values
0Success
-1Failure

This is an alternative to returning individual values from CLI_GENERATE. Instead of repeatedly being asked for the next match and having to start over, you can call this function repeatedly from your own stateful loop. When all matches have been added you can return NULL from the CLI_GENERATE function.

Note
This function always eventually results in calling ast_free on value.

Definition at line 2726 of file main/cli.c.

References ast_threadstorage_get_ptr(), and cli_completion_vector_add().

Referenced by ao2_container_unregister(), ast_cli_complete(), ast_complete_applications(), ast_complete_channels(), category_complete(), cli_complete_endpoint(), cli_complete_show(), cli_complete_uri(), complete_bridge_live_search(), complete_bridge_participant(), complete_bridge_technology(), complete_channeltypes(), complete_config_module(), complete_config_option(), complete_config_type(), complete_core_id(), complete_country(), complete_indications(), complete_show_sorcery_object(), complete_test_category(), complete_test_name(), complete_trans_path_choice(), handle_cli_config_reload(), handle_cli_rtp_drop_incoming_packets(), handle_cli_sound_show(), handle_debug_category(), handle_manager_show_event(), handle_show_named_acl_cmd(), handle_showmanager(), handle_showmancmd(), module_load_helper_on_file(), stir_shaken_tab_complete_name(), topic_complete_name(), and tps_taskprocessor_tab_complete().

2727 {
2728  return cli_completion_vector_add(ast_threadstorage_get_ptr(&completion_storage), value);
2729 }
static int cli_completion_vector_add(struct ast_vector_string *vec, char *value)
Definition: main/cli.c:2705
int value
Definition: syslog.c:37
void * ast_threadstorage_get_ptr(struct ast_threadstorage *ts)
Retrieve a raw pointer from threadstorage.

◆ ast_cli_completion_matches()

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.

Warning
This function cannot be called recursively so it will always fail if called from a CLI_GENERATE callback.

Definition at line 2670 of file main/cli.c.

References ast_cli_completion_vector(), ast_free, AST_THREADSTORAGE_RAW(), AST_VECTOR_APPEND, AST_VECTOR_CALLBACK_VOID, AST_VECTOR_PTR_FREE, AST_VECTOR_STEAL_ELEMENTS, and NULL.

Referenced by handle_commandmatchesarray().

2671 {
2672  struct ast_vector_string *vec = ast_cli_completion_vector(text, word);
2673  char **match_list;
2674 
2675  if (!vec) {
2676  return NULL;
2677  }
2678 
2679  if (AST_VECTOR_APPEND(vec, NULL)) {
2680  /* We failed to NULL terminate the elements */
2682  AST_VECTOR_PTR_FREE(vec);
2683 
2684  return NULL;
2685  }
2686 
2687  match_list = AST_VECTOR_STEAL_ELEMENTS(vec);
2688  AST_VECTOR_PTR_FREE(vec);
2689 
2690  return match_list;
2691 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
char * text
Definition: app_queue.c:1508
#define NULL
Definition: resample.c:96
#define AST_VECTOR_STEAL_ELEMENTS(vec)
Steal the elements from a vector and reinitialize.
Definition: vector.h:140
struct ast_vector_string * ast_cli_completion_vector(const char *text, const char *word)
Generates a vector of strings for CLI completion.
Definition: main/cli.c:2731
#define ast_free(a)
Definition: astmm.h:182
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
Definition: vector.h:189
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865
short word

◆ ast_cli_completion_vector()

struct ast_vector_string* ast_cli_completion_vector ( const char *  text,
const char *  word 
)

Generates a vector of strings for CLI completion.

Parameters
textComplete input being matched.
wordCurrent word being matched

The results contain strings that both: 1) Begin with the string in word. 2) Are valid in a command after the string in text.

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.

Note
All strings and the vector itself are malloc'ed and must be freed by the caller.
The vector is sorted and does not contain any duplicates.
Warning
This function cannot be called recursively so it will always fail if called from a CLI_GENERATE callback.

Definition at line 2731 of file main/cli.c.

References ast_assert, ast_calloc, ast_cli_generator(), ast_free, ast_log, ast_strndup, ast_threadstorage_get_ptr(), ast_threadstorage_set_ptr(), AST_VECTOR_CALLBACK_VOID, AST_VECTOR_GET, AST_VECTOR_INSERT_AT, AST_VECTOR_PTR_FREE, AST_VECTOR_REMOVE, AST_VECTOR_SIZE, cli_completion_vector_add(), LOG_ERROR, and NULL.

Referenced by ast_cli_completion_matches(), AST_TEST_DEFINE(), and cli_complete().

2732 {
2733  char *retstr, *prevstr;
2734  size_t max_equal;
2735  size_t which = 0;
2736  struct ast_vector_string *vec = ast_calloc(1, sizeof(*vec));
2737 
2738  /* Recursion into this function is a coding error. */
2739  ast_assert(!ast_threadstorage_get_ptr(&completion_storage));
2740 
2741  if (!vec) {
2742  return NULL;
2743  }
2744 
2745  if (ast_threadstorage_set_ptr(&completion_storage, vec)) {
2746  ast_log(LOG_ERROR, "Failed to initialize threadstorage for completion.\n");
2747  ast_free(vec);
2748 
2749  return NULL;
2750  }
2751 
2752  while ((retstr = ast_cli_generator(text, word, which)) != NULL) {
2753  if (cli_completion_vector_add(vec, retstr)) {
2754  ast_threadstorage_set_ptr(&completion_storage, NULL);
2755 
2756  goto vector_cleanup;
2757  }
2758 
2759  ++which;
2760  }
2761 
2762  ast_threadstorage_set_ptr(&completion_storage, NULL);
2763 
2764  if (!AST_VECTOR_SIZE(vec)) {
2765  AST_VECTOR_PTR_FREE(vec);
2766 
2767  return NULL;
2768  }
2769 
2770  prevstr = AST_VECTOR_GET(vec, 0);
2771  max_equal = strlen(prevstr);
2772  which = 1;
2773 
2774  /* Find the longest substring that is common to all results
2775  * (it is a candidate for completion), and store a copy in entry 0.
2776  */
2777  while (which < AST_VECTOR_SIZE(vec)) {
2778  size_t i = 0;
2779 
2780  retstr = AST_VECTOR_GET(vec, which);
2781  /* Check for and remove duplicate strings. */
2782  if (!strcasecmp(prevstr, retstr)) {
2783  AST_VECTOR_REMOVE(vec, which, 1);
2784  ast_free(retstr);
2785 
2786  continue;
2787  }
2788 
2789  while (i < max_equal && toupper(prevstr[i]) == toupper(retstr[i])) {
2790  i++;
2791  }
2792 
2793  max_equal = i;
2794  prevstr = retstr;
2795  ++which;
2796  }
2797 
2798  /* Insert longest match to position 0. */
2799  retstr = ast_strndup(AST_VECTOR_GET(vec, 0), max_equal);
2800  if (!retstr || AST_VECTOR_INSERT_AT(vec, 0, retstr)) {
2801  ast_free(retstr);
2802 
2803  goto vector_cleanup;
2804  }
2805 
2806  return vec;
2807 
2808 vector_cleanup:
2810  AST_VECTOR_PTR_FREE(vec);
2811 
2812  return NULL;
2813 }
char * ast_cli_generator(const char *text, const char *word, int state)
Readline madness Useful for readline, that&#39;s about it.
Definition: main/cli.c:2917
static int cli_completion_vector_add(struct ast_vector_string *vec, char *value)
Definition: main/cli.c:2705
#define ast_assert(a)
Definition: utils.h:695
char * text
Definition: app_queue.c:1508
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
int ast_threadstorage_set_ptr(struct ast_threadstorage *ts, void *ptr)
Set a raw pointer from threadstorage.
#define LOG_ERROR
Definition: logger.h:285
#define ast_strndup(str, len)
A wrapper for strndup()
Definition: astmm.h:258
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void * ast_threadstorage_get_ptr(struct ast_threadstorage *ts)
Retrieve a raw pointer from threadstorage.
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
Definition: vector.h:189
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_VECTOR_INSERT_AT(vec, idx, elem)
Insert an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:338
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered)
Remove an element from a vector by index.
Definition: vector.h:412
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865
short word

◆ ast_cli_generator()

char* ast_cli_generator ( const char *  ,
const char *  ,
int   
)

Readline madness Useful for readline, that's about it.

Return values
0on success
-1on failure

Only call this function to proxy the CLI generator to another.

Definition at line 2917 of file main/cli.c.

References __ast_cli_generator().

Referenced by ast_cli_completion_vector(), cli_alias_passthrough(), and handle_cli_check_permissions().

2918 {
2919  return __ast_cli_generator(text, word, state, 1);
2920 }
char * text
Definition: app_queue.c:1508
static char * __ast_cli_generator(const char *text, const char *word, int state, int lock)
Definition: main/cli.c:2829
short word

◆ ast_cli_perms_init()

int ast_cli_perms_init ( int  reload)

Provided by cli.c

Definition at line 2081 of file main/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_default_perm, cli_perm::command, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, destroy_user_perms(), usergroup_cli_perm::gid, cli_perm::list, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, cli_perm::permit, usergroup_cli_perm::perms, perms_config, permsconfiglock, usergroup_cli_perm::uid, and ast_variable::value.

Referenced by asterisk_daemon(), and handle_cli_reload_permissions().

2082 {
2083  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2084  struct ast_config *cfg;
2085  char *cat = NULL;
2086  struct ast_variable *v;
2087  struct usergroup_cli_perm *user_group, *cp_entry;
2088  struct cli_perm *perm = NULL;
2089  struct passwd *pw;
2090  struct group *gr;
2091 
2093  ast_log(LOG_NOTICE, "You must wait until last 'cli reload permissions' command finish\n");
2094  return 1;
2095  }
2096 
2097  cfg = ast_config_load2(perms_config, "" /* core, can't reload */, config_flags);
2098  if (!cfg) {
2100  return 1;
2101  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
2103  return 0;
2104  }
2105 
2106  /* free current structures. */
2108 
2109  while ((cat = ast_category_browse(cfg, cat))) {
2110  if (!strcasecmp(cat, "general")) {
2111  /* General options */
2112  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
2113  if (!strcasecmp(v->name, "default_perm")) {
2114  cli_default_perm = (!strcasecmp(v->value, "permit")) ? 1: 0;
2115  }
2116  }
2117  continue;
2118  }
2119 
2120  /* users or groups */
2121  gr = NULL, pw = NULL;
2122  if (cat[0] == '@') {
2123  /* This is a group */
2124  gr = getgrnam(&cat[1]);
2125  if (!gr) {
2126  ast_log (LOG_WARNING, "Unknown group '%s'\n", &cat[1]);
2127  continue;
2128  }
2129  } else {
2130  /* This is a user */
2131  pw = getpwnam(cat);
2132  if (!pw) {
2133  ast_log (LOG_WARNING, "Unknown user '%s'\n", cat);
2134  continue;
2135  }
2136  }
2137  user_group = NULL;
2138  /* Check for duplicates */
2140  AST_LIST_TRAVERSE(&cli_perms, cp_entry, list) {
2141  if ((pw && cp_entry->uid == pw->pw_uid) || (gr && cp_entry->gid == gr->gr_gid)) {
2142  /* if it is duplicated, just added this new settings, to
2143  the current list. */
2144  user_group = cp_entry;
2145  break;
2146  }
2147  }
2149 
2150  if (!user_group) {
2151  /* alloc space for the new user config. */
2152  user_group = ast_calloc(1, sizeof(*user_group));
2153  if (!user_group) {
2154  continue;
2155  }
2156  user_group->uid = (pw ? pw->pw_uid : -1);
2157  user_group->gid = (gr ? gr->gr_gid : -1);
2158  user_group->perms = ast_calloc(1, sizeof(*user_group->perms));
2159  if (!user_group->perms) {
2160  ast_free(user_group);
2161  continue;
2162  }
2163  }
2164  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
2165  if (ast_strlen_zero(v->value)) {
2166  /* we need to check this condition cause it could break security. */
2167  ast_log(LOG_WARNING, "Empty permit/deny option in user '%s'\n", cat);
2168  continue;
2169  }
2170  if (!strcasecmp(v->name, "permit")) {
2171  perm = ast_calloc(1, sizeof(*perm));
2172  if (perm) {
2173  perm->permit = 1;
2174  perm->command = ast_strdup(v->value);
2175  }
2176  } else if (!strcasecmp(v->name, "deny")) {
2177  perm = ast_calloc(1, sizeof(*perm));
2178  if (perm) {
2179  perm->permit = 0;
2180  perm->command = ast_strdup(v->value);
2181  }
2182  } else {
2183  /* up to now, only 'permit' and 'deny' are possible values. */
2184  ast_log(LOG_WARNING, "Unknown '%s' option\n", v->name);
2185  continue;
2186  }
2187  if (perm) {
2188  /* Added the permission to the user's list. */
2189  AST_LIST_INSERT_TAIL(user_group->perms, perm, list);
2190  perm = NULL;
2191  }
2192  }
2194  AST_RWLIST_INSERT_TAIL(&cli_perms, user_group, list);
2196  }
2197 
2198  ast_config_destroy(cfg);
2200  return 0;
2201 }
struct ast_variable * next
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:274
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3154
static ast_mutex_t permsconfiglock
mutex used to prevent a user from running the &#39;cli reload permissions&#39; command while it is already ru...
Definition: main/cli.c:91
Structure for variables, used for configurations and for channel variables.
static const char perms_config[]
CLI permissions config file.
Definition: main/cli.c:85
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int cli_default_perm
Default permissions value 1=Permit 0=Deny.
Definition: main/cli.c:87
#define ast_log
Definition: astobj2.c:42
#define ast_mutex_trylock(a)
Definition: lock.h:189
struct cli_perm_head * perms
Definition: main/cli.c:81
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define CONFIG_STATUS_FILEUNCHANGED
List of restrictions per user.
Definition: main/cli.c:69
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
list of users to apply restrictions.
Definition: main/cli.c:78
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int reload(void)
Definition: cdr_mysql.c:741
Structure used to handle boolean flags.
Definition: utils.h:199
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
List of users and permissions.
Definition: main/cli.c:93
char * command
Definition: main/cli.c:71
unsigned int permit
Definition: main/cli.c:70
static void destroy_user_perms(void)
cleanup (free) cli_perms linkedlist.
Definition: main/cli.c:2065
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_cli_print_timestr_fromseconds()

void ast_cli_print_timestr_fromseconds ( int  fd,
int  seconds,
const char *  prefix 
)

Print on cli a duration in seconds in format s year(s), s week(s), s day(s), s hour(s), s second(s)

Since
13.8
Parameters
ast_cli_argsfd to print by ast_cli
durationThe time (in seconds) to print
prefixA Prefix string to add before of duration formatted

Definition at line 3021 of file main/cli.c.

References ast_tv(), and print_uptimestr().

Referenced by handle_cdr_pgsql_status(), handle_cli_cdr_mysql_status(), handle_cli_realtime_pgsql_status(), and realtime_ldap_status().

3022 {
3023  print_uptimestr(fd, ast_tv(seconds, 0), prefix, 0);
3024 }
static void print_uptimestr(int fd, struct timeval timeval, const char *prefix, int printsec)
Definition: main/cli.c:876
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:226
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ ast_cli_unregister()

int ast_cli_unregister ( struct ast_cli_entry e)

Unregisters a command or an array of commands.

Parameters
ewhich cli entry to unregister Unregister your own command. You must pass a completed ast_cli_entry structure
Returns
0

Definition at line 2397 of file main/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, cli_perm::list, LOG_WARNING, NULL, remove_shutdown_command(), and ast_cli_entry::usage.

Referenced by aco_deinit(), alias_unregister_cb(), ast_cli_unregister_multiple(), unload_module(), and xmldoc_unload_documentation().

2398 {
2399  if (e->inuse) {
2400  ast_log(LOG_WARNING, "Can't remove command that is in use\n");
2401  } else {
2403  AST_RWLIST_REMOVE(&helpers, e, list);
2406  ast_free(e->_full_cmd);
2407  e->_full_cmd = NULL;
2408  if (e->handler) {
2409  /* this is a new-style entry. Reset fields and free memory. */
2410  char *cmda = (char *) e->cmda;
2411  memset(cmda, '\0', sizeof(e->cmda));
2412  ast_free(e->command);
2413  e->command = NULL;
2414  e->usage = NULL;
2415  }
2416  }
2417  return 0;
2418 }
char * _full_cmd
Definition: cli.h:181
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:274
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
int inuse
Definition: cli.h:179
char *(* handler)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cli.h:187
static void remove_shutdown_command(struct ast_cli_entry *e)
Definition: main/cli.c:2390
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:884
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:172

◆ ast_cli_unregister_multiple()

int ast_cli_unregister_multiple ( struct ast_cli_entry e,
int  len 
)

Unregister multiple commands.

Parameters
epointer to first cli entry to unregister
lennumber of entries to unregister

Definition at line 2508 of file main/cli.c.

References ast_cli_unregister(), and len().

Referenced by cli_shutdown().

2509 {
2510  int i, res = 0;
2511 
2512  for (i = 0; i < len; i++)
2513  res |= ast_cli_unregister(e + i);
2514 
2515  return res;
2516 }
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: main/cli.c:2397
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ ast_complete_channels()

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 1830 of file main/cli.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_cache_all(), ast_cli_completion_add(), ast_strdup, ast_channel_snapshot::base, ast_channel_snapshot_base::name, NULL, and state.

Referenced by complete_ch(), handle_cli_agi_add_cmd(), handle_cli_mixmonitor(), handle_core_set_debug_channel(), handle_redirect(), handle_remb_set(), handle_set_chanvar(), handle_show_chanvar(), handle_show_hangup_channel(), handle_showchan(), and handle_softhangup().

1831 {
1832  int wordlen = strlen(word), which = 0;
1833  struct ao2_container *cached_channels;
1834  char *ret = NULL;
1835  struct ao2_iterator iter;
1836  struct ast_channel_snapshot *snapshot;
1837 
1838  if (pos != rpos) {
1839  return NULL;
1840  }
1841 
1842  cached_channels = ast_channel_cache_all();
1843 
1844  iter = ao2_iterator_init(cached_channels, 0);
1845  for (; (snapshot = ao2_iterator_next(&iter)); ao2_ref(snapshot, -1)) {
1846  if (!strncasecmp(word, snapshot->base->name, wordlen) && (++which > state)) {
1847  if (state != -1) {
1848  ret = ast_strdup(snapshot->base->name);
1849  ao2_ref(snapshot, -1);
1850  break;
1851  }
1852 
1853  if (ast_cli_completion_add(ast_strdup(snapshot->base->name))) {
1854  ao2_ref(snapshot, -1);
1855  break;
1856  }
1857  }
1858  }
1859  ao2_iterator_destroy(&iter);
1860  ao2_ref(cached_channels, -1);
1861 
1862  return ret;
1863 }
enum sip_cc_notify_state state
Definition: chan_sip.c:959
struct ast_channel_snapshot_base * base
Structure representing a snapshot of channel state.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ao2_container * ast_channel_cache_all(void)
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
Generic container type.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field name
short word
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726

◆ ast_debug_get_by_module()

unsigned int ast_debug_get_by_module ( const char *  module)

Get the debug level for a module.

Parameters
modulethe name of module
Returns
the debug level

Definition at line 136 of file main/cli.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and module_level::level.

137 {
138  struct module_level *ml;
139  unsigned int res = 0;
140 
143  if (!strcasecmp(ml->module, module)) {
144  res = ml->level;
145  break;
146  }
147  }
149 
150  return res;
151 }
static struct module_level_list debug_modules
Definition: main/cli.c:107
unsigned int level
Definition: main/cli.c:99
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
map a debug or verbose level to a module name
Definition: main/cli.c:98
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40

◆ AST_THREADSTORAGE_RAW()

AST_THREADSTORAGE_RAW ( completion_storage  )

◆ ast_trace_get_by_module()

unsigned int ast_trace_get_by_module ( const char *  module)

Get the trace level for a module.

Parameters
modulethe name of module
Returns
the trace level

Definition at line 153 of file main/cli.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and module_level::level.

154 {
155  struct module_level *ml;
156  unsigned int res = 0;
157 
160  if (!strcasecmp(ml->module, module)) {
161  res = ml->level;
162  break;
163  }
164  }
166 
167  return res;
168 }
unsigned int level
Definition: main/cli.c:99
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
map a debug or verbose level to a module name
Definition: main/cli.c:98
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static struct module_level_list trace_modules
Definition: main/cli.c:108
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40

◆ AST_VECTOR()

static AST_VECTOR ( struct ast_cli_entry )
static

Definition at line 113 of file main/cli.c.

References ast_carefulwrite(), ast_cli_buf, AST_CLI_INITLEN, AST_DYNSTR_BUILD_FAILED, ast_str_buffer(), ast_str_set_va(), ast_str_strlen(), ast_str_thread_get(), and buf.

119 {
120  int res;
121  struct ast_str *buf;
122  va_list ap;
123 
125  return;
126 
127  va_start(ap, fmt);
128  res = ast_str_set_va(&buf, 0, fmt, ap);
129  va_end(ap);
130 
131  if (res != AST_DYNSTR_BUILD_FAILED) {
132  ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
133  }
134 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
Try to write string, but wait no more than ms milliseconds before timing out.
Definition: main/utils.c:1592
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Set a dynamic string from a va_list.
Definition: strings.h:982
#define AST_CLI_INITLEN
static struct ast_threadstorage ast_cli_buf
Definition: main/cli.c:110
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861

◆ channel_set_debug()

static int channel_set_debug ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 1452 of file main/cli.c.

References args, ast_channel_fin(), ast_channel_fin_set(), ast_channel_fout(), ast_channel_fout_set(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_cli(), DEBUGCHAN_FLAG, channel_set_debug_args::fd, and channel_set_debug_args::is_off.

Referenced by handle_core_set_debug_channel().

1453 {
1454  struct ast_channel *chan = obj;
1455  struct channel_set_debug_args *args = data;
1456 
1457  ast_channel_lock(chan);
1458 
1459  if (!(ast_channel_fin(chan) & DEBUGCHAN_FLAG) || !(ast_channel_fout(chan) & DEBUGCHAN_FLAG)) {
1460  if (args->is_off) {
1461  ast_channel_fin_set(chan, ast_channel_fin(chan) & ~DEBUGCHAN_FLAG);
1462  ast_channel_fout_set(chan, ast_channel_fout(chan) & ~DEBUGCHAN_FLAG);
1463  } else {
1464  ast_channel_fin_set(chan, ast_channel_fin(chan) | DEBUGCHAN_FLAG);
1465  ast_channel_fout_set(chan, ast_channel_fout(chan) | DEBUGCHAN_FLAG);
1466  }
1467  ast_cli(args->fd, "Debugging %s on channel %s\n", args->is_off ? "disabled" : "enabled",
1468  ast_channel_name(chan));
1469  }
1470 
1471  ast_channel_unlock(chan);
1472 
1473  return 0;
1474 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define DEBUGCHAN_FLAG
Definition: channel.h:858
unsigned int ast_channel_fout(const struct ast_channel *chan)
const char * args
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
unsigned int ast_channel_fin(const struct ast_channel *chan)
void ast_channel_fout_set(struct ast_channel *chan, unsigned int value)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
const char * ast_channel_name(const struct ast_channel *chan)
void ast_channel_fin_set(struct ast_channel *chan, unsigned int value)

◆ cli_completion_vector_add()

static int cli_completion_vector_add ( struct ast_vector_string *  vec,
char *  value 
)
static

Definition at line 2705 of file main/cli.c.

References ast_free, ast_threadstorage_set_ptr(), AST_VECTOR_ADD_SORTED, AST_VECTOR_CALLBACK_VOID, AST_VECTOR_FREE, and NULL.

Referenced by ast_cli_completion_add(), and ast_cli_completion_vector().

2706 {
2707  if (!value) {
2708  return 0;
2709  }
2710 
2711  if (!vec || AST_VECTOR_ADD_SORTED(vec, value, strcasecmp)) {
2712  if (vec) {
2713  ast_threadstorage_set_ptr(&completion_storage, NULL);
2714 
2716  AST_VECTOR_FREE(vec);
2717  }
2718  ast_free(value);
2719 
2720  return -1;
2721  }
2722 
2723  return 0;
2724 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp)
Add an element into a sorted vector.
Definition: vector.h:371
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
int ast_threadstorage_set_ptr(struct ast_threadstorage *ts, void *ptr)
Set a raw pointer from threadstorage.
#define ast_free(a)
Definition: astmm.h:182
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865

◆ cli_has_permissions()

static int cli_has_permissions ( int  uid,
int  gid,
const char *  command 
)
static

Definition at line 183 of file main/cli.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, cli_default_perm, CLI_NO_PERMS, cli_perm::command, usergroup_cli_perm::gid, cli_perm::list, NULL, cli_perm::permit, usergroup_cli_perm::perms, and usergroup_cli_perm::uid.

Referenced by ast_cli_command_full(), and handle_cli_check_permissions().

184 {
185  struct usergroup_cli_perm *user_perm;
186  struct cli_perm *perm;
187  /* set to the default permissions general option. */
188  int isallowg = cli_default_perm, isallowu = -1, ispattern;
189  regex_t regexbuf;
190 
191  /* if uid == -1 or gid == -1 do not check permissions.
192  if uid == -2 and gid == -2 is because rasterisk client didn't send
193  the credentials, so the cli_default_perm will be applied. */
194  if ((uid == CLI_NO_PERMS && gid == CLI_NO_PERMS) || command[0] == '_') {
195  return 1;
196  }
197 
198  if (gid < 0 && uid < 0) {
199  return cli_default_perm;
200  }
201 
203  AST_LIST_TRAVERSE(&cli_perms, user_perm, list) {
204  if (user_perm->gid != gid && user_perm->uid != uid) {
205  continue;
206  }
207  AST_LIST_TRAVERSE(user_perm->perms, perm, list) {
208  if (strcasecmp(perm->command, "all") && strncasecmp(perm->command, command, strlen(perm->command))) {
209  /* if the perm->command is a pattern, check it against command. */
210  ispattern = !regcomp(&regexbuf, perm->command, REG_EXTENDED | REG_NOSUB | REG_ICASE);
211  if (ispattern && regexec(&regexbuf, command, 0, NULL, 0)) {
212  regfree(&regexbuf);
213  continue;
214  }
215  if (!ispattern) {
216  continue;
217  }
218  regfree(&regexbuf);
219  }
220  if (user_perm->uid == uid) {
221  /* this is a user definition. */
222  isallowu = perm->permit;
223  } else {
224  /* otherwise is a group definition. */
225  isallowg = perm->permit;
226  }
227  }
228  }
230  if (isallowu > -1) {
231  /* user definition override group definition. */
232  isallowg = isallowu;
233  }
234 
235  return isallowg;
236 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
static int cli_default_perm
Default permissions value 1=Permit 0=Deny.
Definition: main/cli.c:87
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define CLI_NO_PERMS
Definition: cli.h:38
struct cli_perm_head * perms
Definition: main/cli.c:81
List of restrictions per user.
Definition: main/cli.c:69
list of users to apply restrictions.
Definition: main/cli.c:78
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct cli_perm::@371 list
List of users and permissions.
Definition: main/cli.c:93
char * command
Definition: main/cli.c:71
unsigned int permit
Definition: main/cli.c:70

◆ cli_is_registered()

static int cli_is_registered ( struct ast_cli_entry e)
static

Definition at line 2378 of file main/cli.c.

References cli_next(), and NULL.

Referenced by __ast_cli_register().

2379 {
2380  struct ast_cli_entry *cur = NULL;
2381 
2382  while ((cur = cli_next(cur))) {
2383  if (cur == e) {
2384  return 1;
2385  }
2386  }
2387  return 0;
2388 }
descriptor for a cli entry.
Definition: cli.h:171
#define NULL
Definition: resample.c:96
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: main/cli.c:929

◆ cli_next()

static struct ast_cli_entry* cli_next ( struct ast_cli_entry e)
static

Definition at line 929 of file main/cli.c.

References AST_LIST_FIRST, AST_LIST_NEXT, and cli_perm::list.

Referenced by __ast_cli_generator(), cli_is_registered(), find_cli(), handle_cli_check_permissions(), and help1().

930 {
931  if (e) {
932  return AST_LIST_NEXT(e, list);
933  } else {
934  return AST_LIST_FIRST(&helpers);
935  }
936 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
struct ast_cli_entry::@250 list

◆ cli_shutdown()

static void cli_shutdown ( void  )
static

Definition at line 2203 of file main/cli.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by ast_builtins_init().

2204 {
2206 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: main/cli.c:2508
static struct ast_cli_entry cli_cli[]
Definition: main/cli.c:1984

◆ complete_number()

static char* complete_number ( const char *  partial,
unsigned int  min,
unsigned int  max,
int  n 
)
static

Definition at line 363 of file main/cli.c.

References ast_strdup, ast_strlen_zero, cli_perm::next, and NULL.

Referenced by handle_debug(), handle_trace(), and handle_verbose().

364 {
365  int i, count = 0;
366  unsigned int prospective[2];
367  unsigned int part = strtoul(partial, NULL, 10);
368  char next[13];
369 
370  if (part < min || part > max) {
371  return NULL;
372  }
373 
374  for (i = 0; i < 21; i++) {
375  if (i == 0) {
376  prospective[0] = prospective[1] = part;
377  } else if (part == 0 && !ast_strlen_zero(partial)) {
378  break;
379  } else if (i < 11) {
380  prospective[0] = prospective[1] = part * 10 + (i - 1);
381  } else {
382  prospective[0] = (part * 10 + (i - 11)) * 10;
383  prospective[1] = prospective[0] + 9;
384  }
385  if (i < 11 && (prospective[0] < min || prospective[0] > max)) {
386  continue;
387  } else if (prospective[1] < min || prospective[0] > max) {
388  continue;
389  }
390 
391  if (++count > n) {
392  if (i < 11) {
393  snprintf(next, sizeof(next), "%u", prospective[0]);
394  } else {
395  snprintf(next, sizeof(next), "%u...", prospective[0] / 10);
396  }
397  return ast_strdup(next);
398  }
399  }
400  return NULL;
401 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_cli_entry * next
Definition: cli.h:189
#define min(a, b)
Definition: f2c.h:197
#define max(a, b)
Definition: f2c.h:198

◆ destroy_user_perms()

static void destroy_user_perms ( void  )
static

cleanup (free) cli_perms linkedlist.

Definition at line 2065 of file main/cli.c.

References ast_free, AST_LIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, cli_perm::command, cli_perm::list, and usergroup_cli_perm::perms.

Referenced by ast_cli_perms_init().

2066 {
2067  struct cli_perm *perm;
2068  struct usergroup_cli_perm *user_perm;
2069 
2071  while ((user_perm = AST_LIST_REMOVE_HEAD(&cli_perms, list))) {
2072  while ((perm = AST_LIST_REMOVE_HEAD(user_perm->perms, list))) {
2073  ast_free(perm->command);
2074  ast_free(perm);
2075  }
2076  ast_free(user_perm);
2077  }
2079 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct cli_perm_head * perms
Definition: main/cli.c:81
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct usergroup_cli_perm::@372 list
List of restrictions per user.
Definition: main/cli.c:69
list of users to apply restrictions.
Definition: main/cli.c:78
#define ast_free(a)
Definition: astmm.h:182
List of users and permissions.
Definition: main/cli.c:93
char * command
Definition: main/cli.c:71

◆ find_best()

static char* find_best ( const char *  argv[])
static

Definition at line 2360 of file main/cli.c.

References ast_join, AST_MAX_CMD_LEN, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, find_cli(), and NULL.

Referenced by ast_cli_command_full().

2361 {
2362  static char cmdline[80];
2363  int x;
2364  /* See how close we get, then print the candidate */
2365  const char *myargv[AST_MAX_CMD_LEN] = { NULL, };
2366 
2368  for (x = 0; argv[x]; x++) {
2369  myargv[x] = argv[x];
2370  if (!find_cli(myargv, -1))
2371  break;
2372  }
2374  ast_join(cmdline, sizeof(cmdline), myargv);
2375  return cmdline;
2376 }
#define ast_join(s, len, w)
Definition: strings.h:483
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static struct ast_cli_entry * find_cli(const char *const cmds[], int match_type)
Definition: main/cli.c:2316
#define AST_MAX_CMD_LEN
Definition: cli.h:48

◆ find_cli()

static struct ast_cli_entry* find_cli ( const char *const  cmds[],
int  match_type 
)
static

Definition at line 2316 of file main/cli.c.

References ast_strlen_zero, cli_next(), NULL, and word_match().

Referenced by __ast_cli_register(), ast_cli_command_full(), find_best(), and handle_help().

2317 {
2318  int matchlen = -1; /* length of longest match so far */
2319  struct ast_cli_entry *cand = NULL, *e=NULL;
2320 
2321  while ( (e = cli_next(e)) ) {
2322  /* word-by word regexp comparison */
2323  const char * const *src = cmds;
2324  const char * const *dst = e->cmda;
2325  int n = 0;
2326  for (;; dst++, src += n) {
2327  n = word_match(*src, *dst);
2328  if (n < 0)
2329  break;
2330  }
2331  if (ast_strlen_zero(*dst) || ((*dst)[0] == '[' && ast_strlen_zero(dst[1]))) {
2332  /* no more words in 'e' */
2333  if (ast_strlen_zero(*src)) /* exact match, cannot do better */
2334  break;
2335  /* Here, cmds has more words than the entry 'e' */
2336  if (match_type != 0) /* but we look for almost exact match... */
2337  continue; /* so we skip this one. */
2338  /* otherwise we like it (case 0) */
2339  } else { /* still words in 'e' */
2340  if (ast_strlen_zero(*src))
2341  continue; /* cmds is shorter than 'e', not good */
2342  /* Here we have leftover words in cmds and 'e',
2343  * but there is a mismatch. We only accept this one if match_type == -1
2344  * and this is the last word for both.
2345  */
2346  if (match_type != -1 || !ast_strlen_zero(src[1]) ||
2347  !ast_strlen_zero(dst[1])) /* not the one we look for */
2348  continue;
2349  /* good, we are in case match_type == -1 and mismatch on last word */
2350  }
2351  if (src - cmds > matchlen) { /* remember the candidate */
2352  matchlen = src - cmds;
2353  cand = e;
2354  }
2355  }
2356 
2357  return e ? e : cand;
2358 }
descriptor for a cli entry.
Definition: cli.h:171
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int word_match(const char *cmd, const char *cli_word)
Definition: main/cli.c:2227
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: main/cli.c:929

◆ find_module_level()

static struct module_level* find_module_level ( const char *  module,
struct module_level_list mll 
)
static

Find the module level setting.

Parameters
moduleModule name to look for.
mllList to search.
Return values
levelstruct found on success.
NULLnot found.

Definition at line 351 of file main/cli.c.

References AST_LIST_TRAVERSE, and NULL.

Referenced by handle_debug_or_trace().

352 {
353  struct module_level *ml;
354 
355  AST_LIST_TRAVERSE(mll, ml, entry) {
356  if (!strcasecmp(ml->module, module))
357  return ml;
358  }
359 
360  return NULL;
361 }
map a debug or verbose level to a module name
Definition: main/cli.c:98
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40

◆ group_show_channels()

static char* group_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1865 of file main/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_channel_name(), 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, NULL, and ast_cli_entry::usage.

1866 {
1867 #define FORMAT_STRING "%-25s %-20s %-20s\n"
1868 
1869  struct ast_group_info *gi = NULL;
1870  int numchans = 0;
1871  regex_t regexbuf;
1872  int havepattern = 0;
1873 
1874  switch (cmd) {
1875  case CLI_INIT:
1876  e->command = "group show channels";
1877  e->usage =
1878  "Usage: group show channels [pattern]\n"
1879  " Lists all currently active channels with channel group(s) specified.\n"
1880  " Optional regular expression pattern is matched to group names for each\n"
1881  " channel.\n";
1882  return NULL;
1883  case CLI_GENERATE:
1884  return NULL;
1885  }
1886 
1887  if (a->argc < 3 || a->argc > 4)
1888  return CLI_SHOWUSAGE;
1889 
1890  if (a->argc == 4) {
1891  if (regcomp(&regexbuf, a->argv[3], REG_EXTENDED | REG_NOSUB))
1892  return CLI_SHOWUSAGE;
1893  havepattern = 1;
1894  }
1895 
1896  ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category");
1897 
1899 
1900  gi = ast_app_group_list_head();
1901  while (gi) {
1902  if (!havepattern || !regexec(&regexbuf, gi->group, 0, NULL, 0)) {
1903  ast_cli(a->fd, FORMAT_STRING, ast_channel_name(gi->chan), gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category));
1904  numchans++;
1905  }
1906  gi = AST_LIST_NEXT(gi, group_list);
1907  }
1908 
1910 
1911  if (havepattern)
1912  regfree(&regexbuf);
1913 
1914  ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
1915  return CLI_SUCCESS;
1916 #undef FORMAT_STRING
1917 }
#define FORMAT_STRING
channel group info
Definition: channel.h:2938
struct ast_group_info * ast_app_group_list_head(void)
Get the head of the group count list.
Definition: main/app.c:2189
const int argc
Definition: cli.h:160
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define ast_strlen_zero(foo)
Definition: strings.h:52
const int fd
Definition: cli.h:159
char * group
Definition: channel.h:2941
struct ast_channel * chan
Definition: channel.h:2939
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int ast_app_group_list_unlock(void)
Unlock the group count list.
Definition: main/app.c:2194
#define ESS(x)
Definition: cli.h:59
char * command
Definition: cli.h:186
char * category
Definition: channel.h:2940
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
int ast_app_group_list_rdlock(void)
Read Lock the group count list.
Definition: main/app.c:2184
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_group_info::@248 group_list

◆ handle_chanlist()

static char* handle_chanlist ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1067 of file main/cli.c.

References ast_channel_snapshot_peer::account, ast_channel_snapshot_base::accountcode, ast_channel_snapshot::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_snapshot_dialplan::appl, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_active_channels(), ast_channel_cache_by_name(), ast_cli(), ast_option_maxcalls, ast_processed_calls(), ast_state2str(), ast_strlen_zero, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_channel_snapshot::base, ast_channel_snapshot::bridge, ast_channel_snapshot::caller, channels, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, CONCISE_FORMAT_STRING, ast_channel_snapshot_dialplan::context, ast_channel_snapshot_base::creationtime, ast_channel_snapshot_dialplan::data, ast_channel_snapshot::dialplan, ESS, ast_channel_snapshot_dialplan::exten, ast_cli_args::fd, FORMAT_STRING, FORMAT_STRING2, ast_channel_snapshot_bridge::id, ast_channel_snapshot_base::name, NULL, ast_channel_snapshot_caller::number, ast_channel_snapshot::peer, ast_channel_snapshot_dialplan::priority, S_OR, ast_channel_snapshot::state, ast_channel_snapshot_base::uniqueid, ast_cli_entry::usage, VERBOSE_FORMAT_STRING, and VERBOSE_FORMAT_STRING2.

1068 {
1069 #define FORMAT_STRING "%-20.20s %-20.20s %-7.7s %-30.30s\n"
1070 #define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n"
1071 #define CONCISE_FORMAT_STRING "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
1072 #define VERBOSE_FORMAT_STRING "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
1073 #define VERBOSE_FORMAT_STRING2 "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
1074 
1075  struct ao2_container *channels;
1076  struct ao2_iterator it_chans;
1077  struct ast_channel_snapshot *cs;
1078  int numchans = 0, concise = 0, verbose = 0, count = 0;
1079 
1080  switch (cmd) {
1081  case CLI_INIT:
1082  e->command = "core show channels [concise|verbose|count]";
1083  e->usage =
1084  "Usage: core show channels [concise|verbose|count]\n"
1085  " Lists currently defined channels and some information about them. If\n"
1086  " 'concise' is specified, the format is abridged and in a more easily\n"
1087  " machine parsable format. If 'verbose' is specified, the output includes\n"
1088  " more and longer fields. If 'count' is specified only the channel and call\n"
1089  " count is output.\n"
1090  " The 'concise' option is deprecated and will be removed from future versions\n"
1091  " of Asterisk.\n";
1092  return NULL;
1093 
1094  case CLI_GENERATE:
1095  return NULL;
1096  }
1097 
1098  if (a->argc == e->args) {
1099  if (!strcasecmp(a->argv[e->args-1],"concise"))
1100  concise = 1;
1101  else if (!strcasecmp(a->argv[e->args-1],"verbose"))
1102  verbose = 1;
1103  else if (!strcasecmp(a->argv[e->args-1],"count"))
1104  count = 1;
1105  else
1106  return CLI_SHOWUSAGE;
1107  } else if (a->argc != e->args - 1)
1108  return CLI_SHOWUSAGE;
1109 
1110  channels = ast_channel_cache_by_name();
1111 
1112  if (!count) {
1113  if (!concise && !verbose)
1114  ast_cli(a->fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)");
1115  else if (verbose)
1116  ast_cli(a->fd, VERBOSE_FORMAT_STRING2, "Channel", "Context", "Extension", "Priority", "State", "Application", "Data",
1117  "CallerID", "Duration", "Accountcode", "PeerAccount", "BridgeID");
1118  }
1119 
1120  it_chans = ao2_iterator_init(channels, 0);
1121  for (; (cs = ao2_iterator_next(&it_chans)); ao2_ref(cs, -1)) {
1122  char durbuf[16] = "-";
1123 
1124  if (!count) {
1125  if ((concise || verbose) && !ast_tvzero(cs->base->creationtime)) {
1126  int duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->base->creationtime) / 1000);
1127  if (verbose) {
1128  int durh = duration / 3600;
1129  int durm = (duration % 3600) / 60;
1130  int durs = duration % 60;
1131  snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
1132  } else {
1133  snprintf(durbuf, sizeof(durbuf), "%d", duration);
1134  }
1135  }
1136  if (concise) {
1138  S_OR(cs->dialplan->appl, "(None)"),
1139  cs->dialplan->data,
1140  cs->caller->number,
1141  cs->base->accountcode,
1142  cs->peer->account,
1143  cs->amaflags,
1144  durbuf,
1145  cs->bridge->id,
1146  cs->base->uniqueid);
1147  } else if (verbose) {
1149  S_OR(cs->dialplan->appl, "(None)"),
1150  S_OR(cs->dialplan->data, "(Empty)"),
1151  cs->caller->number,
1152  durbuf,
1153  cs->base->accountcode,
1154  cs->peer->account,
1155  cs->bridge->id);
1156  } else {
1157  char locbuf[40] = "(None)";
1158  char appdata[40] = "(None)";
1159 
1161  snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", cs->dialplan->exten, cs->dialplan->context, cs->dialplan->priority);
1162  }
1163  if (!ast_strlen_zero(cs->dialplan->appl)) {
1164  snprintf(appdata, sizeof(appdata), "%s(%s)", cs->dialplan->appl, S_OR(cs->dialplan->data, ""));
1165  }
1166  ast_cli(a->fd, FORMAT_STRING, cs->base->name, locbuf, ast_state2str(cs->state), appdata);
1167  }
1168  }
1169  }
1170  ao2_iterator_destroy(&it_chans);
1171 
1172  if (!concise) {
1173  numchans = ast_active_channels();
1174  ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
1175  if (ast_option_maxcalls)
1176  ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
1178  ((double)ast_active_calls() / (double)ast_option_maxcalls) * 100.0);
1179  else
1180  ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
1181 
1182  ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
1183  }
1184  ao2_ref(channels, -1);
1185 
1186  return CLI_SUCCESS;
1187 
1188 #undef FORMAT_STRING
1189 #undef FORMAT_STRING2
1190 #undef CONCISE_FORMAT_STRING
1191 #undef VERBOSE_FORMAT_STRING
1192 #undef VERBOSE_FORMAT_STRING2
1193 }
struct ao2_container * ast_channel_cache_by_name(void)
Secondary channel cache, indexed by name.
const ast_string_field data
#define FORMAT_STRING
struct ast_channel_snapshot_base * base
int ast_active_calls(void)
Retrieve the number of active calls.
Definition: pbx.c:4764
const int argc
Definition: cli.h:160
#define VERBOSE_FORMAT_STRING2
Structure representing a snapshot of channel state.
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
Definition: cli.h:152
const ast_string_field accountcode
const ast_string_field uniqueid
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:98
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
Definition: channel.c:642
#define NULL
Definition: resample.c:96
#define FORMAT_STRING2
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct ast_channel_snapshot_dialplan * dialplan
int ast_option_maxcalls
Definition: options.c:79
int args
This gets set in ast_cli_register()
Definition: cli.h:185
#define ast_strlen_zero(foo)
Definition: strings.h:52
const ast_string_field context
const ast_string_field appl
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const ast_string_field exten
#define CONCISE_FORMAT_STRING
static struct channel_usage channels
struct ast_channel_snapshot_caller * caller
const char *const * argv
Definition: cli.h:161
int ast_processed_calls(void)
Retrieve the total number of calls processed through the PBX since last restart.
Definition: pbx.c:4769
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define ESS(x)
Definition: cli.h:59
char * command
Definition: cli.h:186
enum ast_channel_state state
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
const ast_string_field number
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
struct ast_channel_snapshot_bridge * bridge
#define VERBOSE_FORMAT_STRING
Generic container type.
struct ast_channel_snapshot_peer * peer
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
const ast_string_field name

◆ handle_cli_check_permissions()

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 1316 of file main/cli.c.

References __ast_cli_generator(), ast_cli_entry::_full_cmd, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_generator(), ast_join, AST_MAX_ARGS, ast_strdupa, ast_strlen_zero, CLI_FAILURE, CLI_GENERATE, cli_has_permissions(), CLI_INIT, cli_next(), CLI_SHOWUSAGE, CLI_SUCCESS, cli_perm::command, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, lock, ast_cli_args::n, NULL, ast_cli_args::pos, S_OR, ast_cli_entry::summary, text, tmp(), ast_cli_entry::usage, and ast_cli_args::word.

1317 {
1318  struct passwd *pw = NULL;
1319  struct group *gr;
1320  int gid = -1, uid = -1;
1321  char command[AST_MAX_ARGS] = "";
1322  struct ast_cli_entry *ce = NULL;
1323  int found = 0;
1324  char *group, *tmp;
1325 
1326  switch (cmd) {
1327  case CLI_INIT:
1328  e->command = "cli check permissions";
1329  e->usage =
1330  "Usage: cli check permissions {<username>|@<groupname>|<username>@<groupname>} [<command>]\n"
1331  " Check permissions config for a user@group or list the allowed commands for the specified user.\n"
1332  " The username or the groupname may be omitted.\n";
1333  return NULL;
1334  case CLI_GENERATE:
1335  if (a->pos >= 4) {
1336  return ast_cli_generator(a->line + strlen("cli check permissions") + strlen(a->argv[3]) + 1, a->word, a->n);
1337  }
1338  return NULL;
1339  }
1340 
1341  if (a->argc < 4) {
1342  return CLI_SHOWUSAGE;
1343  }
1344 
1345  tmp = ast_strdupa(a->argv[3]);
1346  group = strchr(tmp, '@');
1347  if (group) {
1348  gr = getgrnam(&group[1]);
1349  if (!gr) {
1350  ast_cli(a->fd, "Unknown group '%s'\n", &group[1]);
1351  return CLI_FAILURE;
1352  }
1353  group[0] = '\0';
1354  gid = gr->gr_gid;
1355  }
1356 
1357  if (!group && ast_strlen_zero(tmp)) {
1358  ast_cli(a->fd, "You didn't supply a username\n");
1359  } else if (!ast_strlen_zero(tmp) && !(pw = getpwnam(tmp))) {
1360  ast_cli(a->fd, "Unknown user '%s'\n", tmp);
1361  return CLI_FAILURE;
1362  } else if (pw) {
1363  uid = pw->pw_uid;
1364  }
1365 
1366  if (a->argc == 4) {
1367  while ((ce = cli_next(ce))) {
1368  /* Hide commands that start with '_' */
1369  if (ce->_full_cmd[0] == '_') {
1370  continue;
1371  }
1372  if (cli_has_permissions(uid, gid, ce->_full_cmd)) {
1373  ast_cli(a->fd, "%30.30s %s\n", ce->_full_cmd, S_OR(ce->summary, "<no description available>"));
1374  found++;
1375  }
1376  }
1377  if (!found) {
1378  ast_cli(a->fd, "You are not allowed to run any command on Asterisk\n");
1379  }
1380  } else {
1381  ast_join(command, sizeof(command), a->argv + 4);
1382  ast_cli(a->fd, "%s '%s%s%s' is %s to run command: '%s'\n", uid >= 0 ? "User" : "Group", tmp,
1383  group && uid >= 0 ? "@" : "",
1384  group ? &group[1] : "",
1385  cli_has_permissions(uid, gid, command) ? "allowed" : "not allowed", command);
1386  }
1387 
1388  return CLI_SUCCESS;
1389 }
char * ast_cli_generator(const char *text, const char *word, int state)
Readline madness Useful for readline, that&#39;s about it.
Definition: main/cli.c:2917
char * _full_cmd
Definition: cli.h:181
#define ast_join(s, len, w)
Definition: strings.h:483
descriptor for a cli entry.
Definition: cli.h:171
const int argc
Definition: cli.h:160
static int tmp()
Definition: bt_open.c:389
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
#define ast_strlen_zero(foo)
Definition: strings.h:52
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
#define AST_MAX_ARGS
Definition: cli.h:50
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const char *const summary
Definition: cli.h:176
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const int pos
Definition: cli.h:164
static int cli_has_permissions(int uid, int gid, const char *command)
Definition: main/cli.c:183
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: main/cli.c:929

◆ handle_cli_malloc_trim()

static char* handle_cli_malloc_trim ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1956 of file main/cli.c.

References a, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, handle_help(), NULL, and ast_cli_entry::usage.

1957 {
1958  extern int malloc_trim(size_t __pad) __THROW;
1959 
1960  switch (cmd) {
1961  case CLI_INIT:
1962  e->command = "malloc trim";
1963  e->usage =
1964  "Usage: malloc trim\n"
1965  " Try to give excess memory back to the OS.\n";
1966  return NULL;
1967  case CLI_GENERATE:
1968  return NULL;
1969  }
1970 
1971  if (malloc_trim(0)) {
1972  ast_cli(a->fd, "Returned some memory to the OS.\n");
1973  } else {
1974  ast_cli(a->fd, "No memory returned to the OS.\n");
1975  }
1976 
1977  return CLI_SUCCESS;
1978 }
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_cli_reload_permissions()

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 1297 of file main/cli.c.

References ast_cli_perms_init(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

1298 {
1299  switch (cmd) {
1300  case CLI_INIT:
1301  e->command = "cli reload permissions";
1302  e->usage =
1303  "Usage: cli reload permissions\n"
1304  " Reload the 'cli_permissions.conf' file.\n";
1305  return NULL;
1306  case CLI_GENERATE:
1307  return NULL;
1308  }
1309 
1310  ast_cli_perms_init(1);
1311 
1312  return CLI_SUCCESS;
1313 }
Definition: cli.h:152
#define NULL
Definition: resample.c:96
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_perms_init(int reload)
Definition: main/cli.c:2081

◆ handle_cli_show_permissions()

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 1252 of file main/cli.c.

References ast_cli(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, cli_perm::command, ast_cli_entry::command, ast_cli_args::fd, usergroup_cli_perm::gid, cli_perm::list, NULL, cli_perm::permit, usergroup_cli_perm::perms, usergroup_cli_perm::uid, and ast_cli_entry::usage.

1253 {
1254  struct usergroup_cli_perm *cp;
1255  struct cli_perm *perm;
1256  struct passwd *pw = NULL;
1257  struct group *gr = NULL;
1258 
1259  switch (cmd) {
1260  case CLI_INIT:
1261  e->command = "cli show permissions";
1262  e->usage =
1263  "Usage: cli show permissions\n"
1264  " Shows CLI configured permissions.\n";
1265  return NULL;
1266  case CLI_GENERATE:
1267  return NULL;
1268  }
1269 
1271  AST_LIST_TRAVERSE(&cli_perms, cp, list) {
1272  if (cp->uid >= 0) {
1273  pw = getpwuid(cp->uid);
1274  if (pw) {
1275  ast_cli(a->fd, "user: %s [uid=%d]\n", pw->pw_name, cp->uid);
1276  }
1277  } else {
1278  gr = getgrgid(cp->gid);
1279  if (gr) {
1280  ast_cli(a->fd, "group: %s [gid=%d]\n", gr->gr_name, cp->gid);
1281  }
1282  }
1283  ast_cli(a->fd, "Permissions:\n");
1284  if (cp->perms) {
1285  AST_LIST_TRAVERSE(cp->perms, perm, list) {
1286  ast_cli(a->fd, "\t%s -> %s\n", perm->permit ? "permit" : "deny", perm->command);
1287  }
1288  }
1289  ast_cli(a->fd, "\n");
1290  }
1292 
1293  return CLI_SUCCESS;
1294 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:159
struct cli_perm_head * perms
Definition: main/cli.c:81
List of restrictions per user.
Definition: main/cli.c:69
list of users to apply restrictions.
Definition: main/cli.c:78
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
List of users and permissions.
Definition: main/cli.c:93
char * command
Definition: main/cli.c:71
unsigned int permit
Definition: main/cli.c:70

◆ handle_cli_wait_fullybooted()

static char* handle_cli_wait_fullybooted ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1919 of file main/cli.c.

References ast_cli(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

1920 {
1921  switch (cmd) {
1922  case CLI_INIT:
1923  e->command = "core waitfullybooted";
1924  e->usage =
1925  "Usage: core waitfullybooted\n"
1926  " Wait until Asterisk has fully booted.\n";
1927  return NULL;
1928  case CLI_GENERATE:
1929  return NULL;
1930  }
1931 
1933  usleep(100);
1934  }
1935 
1936  ast_cli(a->fd, "Asterisk has fully booted.\n");
1937 
1938  return CLI_SUCCESS;
1939 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
struct ast_flags ast_options
Definition: options.c:61

◆ handle_commandmatchesarray()

static char* handle_commandmatchesarray ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1393 of file main/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(), NULL, and ast_cli_entry::usage.

1394 {
1395  char *buf, *obuf;
1396  int buflen = 2048;
1397  int len = 0;
1398  char **matches;
1399  int x, matchlen;
1400 
1401  switch (cmd) {
1402  case CLI_INIT:
1403  e->command = "_command matchesarray";
1404  e->usage =
1405  "Usage: _command matchesarray \"<line>\" text \n"
1406  " This function is used internally to help with command completion and should.\n"
1407  " never be called by the user directly.\n";
1408  return NULL;
1409  case CLI_GENERATE:
1410  return NULL;
1411  }
1412 
1413  if (a->argc != 4)
1414  return CLI_SHOWUSAGE;
1415  if (!(buf = ast_malloc(buflen)))
1416  return CLI_FAILURE;
1417  buf[len] = '\0';
1418  matches = ast_cli_completion_matches(a->argv[2], a->argv[3]);
1419  if (matches) {
1420  for (x=0; matches[x]; x++) {
1421  matchlen = strlen(matches[x]) + 1;
1422  if (len + matchlen >= buflen) {
1423  buflen += matchlen * 3;
1424  obuf = buf;
1425  if (!(buf = ast_realloc(obuf, buflen)))
1426  /* Memory allocation failure... Just free old buffer and be done */
1427  ast_free(obuf);
1428  }
1429  if (buf)
1430  len += sprintf( buf + len, "%s ", matches[x]);
1431  ast_free(matches[x]);
1432  matches[x] = NULL;
1433  }
1434  ast_free(matches);
1435  }
1436 
1437  if (buf) {
1438  ast_cli(a->fd, "%s%s",buf, AST_CLI_COMPLETE_EOF);
1439  ast_free(buf);
1440  } else
1441  ast_cli(a->fd, "NULL\n");
1442 
1443  return CLI_SUCCESS;
1444 }
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:228
#define AST_CLI_COMPLETE_EOF
Definition: cli.h:52
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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...
Definition: main/cli.c:2670
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_core_reload()

static char* handle_core_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 319 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_module_reload(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, and ast_cli_entry::usage.

320 {
321  switch (cmd) {
322  case CLI_INIT:
323  e->command = "core reload";
324  e->usage =
325  "Usage: core reload\n"
326  " Execute a global reload.\n";
327  return NULL;
328 
329  case CLI_GENERATE:
330  return NULL;
331  }
332 
333  if (a->argc != e->args) {
334  return CLI_SHOWUSAGE;
335  }
336 
338 
339  return CLI_SUCCESS;
340 }
enum ast_module_reload_result ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:1562
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
int args
This gets set in ast_cli_register()
Definition: cli.h:185
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_core_set_debug_channel()

static char* handle_core_set_debug_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1476 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_callback(), ast_channel_get_by_name(), ast_channel_unref, ast_cli(), ast_cli_complete(), ast_complete_channels(), c, channel_set_debug(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEBUGCHAN_FLAG, ast_cli_args::fd, channel_set_debug_args::fd, global_fin, global_fout, channel_set_debug_args::is_off, ast_cli_args::line, ast_cli_args::n, NULL, OBJ_MULTIPLE, OBJ_NODATA, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

Referenced by handle_nodebugchan_deprecated().

1477 {
1478  struct ast_channel *c = NULL;
1479  static const char * const completions_all[] = { "all", NULL };
1480  static const char * const completions_off[] = { "off", NULL };
1481  struct channel_set_debug_args args = {
1482  .fd = a->fd,
1483  };
1484 
1485  switch (cmd) {
1486  case CLI_INIT:
1487  e->command = "core set debug channel";
1488  e->usage =
1489  "Usage: core set debug channel <all|channel> [off]\n"
1490  " Enables/disables debugging on all or on a specific channel.\n";
1491  return NULL;
1492  case CLI_GENERATE:
1493  if (a->pos == 4) {
1494  char *complete = ast_cli_complete(a->word, completions_all, a->n);
1495  if (!complete) {
1496  complete = ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
1497  }
1498  return complete;
1499  } else if (a->pos == 5) {
1500  return ast_cli_complete(a->word, completions_off, a->n);
1501  }
1502 
1503  return NULL;
1504  }
1505 
1506  if (cmd == (CLI_HANDLER + 1000)) {
1507  /* called from handle_nodebugchan_deprecated */
1508  args.is_off = 1;
1509  } else if (a->argc == e->args + 2) {
1510  /* 'core set debug channel {all|chan_id}' */
1511  if (!strcasecmp(a->argv[e->args + 1], "off"))
1512  args.is_off = 1;
1513  else
1514  return CLI_SHOWUSAGE;
1515  } else if (a->argc != e->args + 1) {
1516  return CLI_SHOWUSAGE;
1517  }
1518 
1519  if (!strcasecmp("all", a->argv[e->args])) {
1520  if (args.is_off) {
1523  } else {
1526  }
1528  } else {
1529  if ((c = ast_channel_get_by_name(a->argv[e->args]))) {
1530  channel_set_debug(c, NULL, &args, 0);
1531  ast_channel_unref(c);
1532  } else {
1533  ast_cli(a->fd, "No such channel %s\n", a->argv[e->args]);
1534  }
1535  }
1536 
1537  ast_cli(a->fd, "Debugging on new channels is %s\n", args.is_off ? "disabled" : "enabled");
1538 
1539  return CLI_SUCCESS;
1540 }
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: main/cli.c:1830
Main Channel structure associated with a channel.
#define DEBUGCHAN_FLAG
Definition: channel.h:858
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
static int channel_set_debug(void *obj, void *arg, void *data, int flags)
Definition: main/cli.c:1452
const int argc
Definition: cli.h:160
unsigned long global_fin
Definition: channel.c:95
Definition: cli.h:152
unsigned long global_fout
Definition: channel.c:95
static struct test_val c
const char * args
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
struct ast_channel * ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
Call a function with every active channel.
Definition: channel.c:1278
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
char * ast_cli_complete(const char *word, const char *const choices[], int state)
Definition: main/cli.c:1811
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454

◆ handle_debug()

static char* handle_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 572 of file main/cli.c.

References ast_cli_args::argv, ast_module_helper(), AST_MODULE_HELPER_RUNNING, ast_strdup, ast_strlen_zero, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_number(), DEBUG_HANDLER, handle_debug_or_trace(), ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, S_OR, ast_cli_entry::usage, and ast_cli_args::word.

573 {
574  int atleast = 0;
575  const char *argv3 = a->argv ? S_OR(a->argv[3], "") : "";
576 
577  switch (cmd) {
578  case CLI_INIT:
579  e->command = "core set debug";
580  e->usage =
581  "Usage: core set debug [atleast] <level> [module]\n"
582  " core set debug off\n"
583  "\n"
584  " Sets level of debug messages to be displayed or\n"
585  " sets a module name to display debug messages from.\n"
586  " 0 or off means no messages should be displayed.\n"
587  " Equivalent to -d[d[...]] on startup\n";
588  return NULL;
589 
590  case CLI_GENERATE:
591  if (!strcasecmp(argv3, "category")) {
592  return NULL;
593  }
594 
595  if (!strcasecmp(argv3, "atleast")) {
596  atleast = 1;
597  }
598  if (a->pos == 3 || (a->pos == 4 && atleast)) {
599  const char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], "");
600  int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21;
601 
602  if (a->n < 21 && numbermatch == 0) {
603  return complete_number(pos, 0, 0x7fffffff, a->n);
604  } else if (pos[0] == '0') {
605  if (a->n == 0) {
606  return ast_strdup("0");
607  }
608  } else if (a->n == (21 - numbermatch)) {
609  if (a->pos == 3 && !strncasecmp(argv3, "off", strlen(argv3))) {
610  return ast_strdup("off");
611  } else if (a->pos == 3 && !strncasecmp(argv3, "atleast", strlen(argv3))) {
612  return ast_strdup("atleast");
613  }
614  } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) {
615  return ast_strdup("atleast");
616  }
617  } else if ((a->pos == 4 && !atleast && strcasecmp(argv3, "off") && strcasecmp(argv3, "channel"))
618  || (a->pos == 5 && atleast)) {
619  return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, AST_MODULE_HELPER_RUNNING);
620  }
621  return NULL;
622  }
623  /* all the above return, so we proceed with the handler.
624  * we are guaranteed to be called with argc >= e->args;
625  */
626 
627  return handle_debug_or_trace(DEBUG_HANDLER, e, cmd, a);
628 }
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
Match modules names for the Asterisk cli.
Definition: loader.c:1374
Definition: cli.h:152
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
const char * line
Definition: cli.h:162
#define DEBUG_HANDLER
Definition: main/cli.c:403
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * handle_debug_or_trace(int handler, struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/cli.c:449
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const int pos
Definition: cli.h:164
static char * complete_number(const char *partial, unsigned int min, unsigned int max, int n)
Definition: main/cli.c:363

◆ handle_debug_category()

static char* handle_debug_category ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1542 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli_completion_add(), ast_debug_category_complete(), ast_debug_category_set_sublevels(), AST_LOG_CATEGORY_DISABLED, AST_LOG_CATEGORY_ENABLED, ast_strdup, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::n, NULL, ast_cli_args::pos, S_OR, ast_cli_entry::usage, and ast_cli_args::word.

1543 {
1544  const char *argv4 = a->argv ? S_OR(a->argv[4], "") : "";
1545  int offset = strncasecmp(argv4, "off", strlen(argv4)) ? 0 : 1;
1546 
1547  switch (cmd) {
1548  case CLI_INIT:
1549  e->command = "core set debug category";
1550  e->usage =
1551  "Usage: core set debug category <category>[:<sublevel>] [category[:<sublevel] ...]\n"
1552  " core set debug category off [<category> [<category>] ...]\n\n"
1553  " Allows enabling and disabling debug logging categories.\n"
1554  " When a category is enabled all relevant debug messages are logged\n"
1555  " for a given category. However, if a sublevel is specified only\n"
1556  " those categorized messages at or below the coded debug sublevel\n"
1557  " are logged.\n";
1558  return NULL;
1559 
1560  case CLI_GENERATE:
1561  if (a->pos < e->args) {
1562  return NULL;
1563  }
1564 
1565  if (a->pos == 4 && offset) {
1567  }
1568 
1569  return ast_debug_category_complete(a->argv + 4,
1570  a->pos - e->args, a->word, a->n - 1);
1571  }
1572 
1573  if (a->argc <= e->args) {
1574  return CLI_SHOWUSAGE;
1575  }
1576 
1577  ast_debug_category_set_sublevels(a->argv + e->args + offset, a->argc - e->args - offset,
1579 
1580  return CLI_SUCCESS;
1581 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
char * ast_debug_category_complete(const char *const *argv, int argc, const char *word, int state)
Add a unique (no duplicates) result to a request for completion for debug categories.
int ast_debug_category_set_sublevels(const char *const *names, size_t size, int default_sublevel)
Set one or more debug category&#39;s sublevel.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
#define AST_LOG_CATEGORY_DISABLED
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const int pos
Definition: cli.h:164
#define AST_LOG_CATEGORY_ENABLED
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726

◆ handle_debug_or_trace()

static char* handle_debug_or_trace ( int  handler,
struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 449 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_calloc, ast_clear_flag, ast_cli(), ast_free, AST_OPT_FLAG_DEBUG_MODULE, AST_OPT_FLAG_TRACE_MODULE, ast_options, AST_RWLIST_EMPTY, AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_set_flag, ast_strdupa, CLI_FAILURE, CLI_SHOWUSAGE, CLI_SUCCESS, DEBUG_HANDLER, debug_modules, ast_cli_args::fd, find_module_level(), module_level::level, option_debug, option_trace, status_debug_verbose(), and trace_modules.

Referenced by handle_debug(), and handle_trace().

450 {
451  int oldval;
452  int newlevel;
453  int atleast = 0;
454  struct module_level *ml;
455  struct module_level_list *modules;
456  unsigned int module_option;
457  int *core_option;
458  const char *handler_name;
459 
460  if (a->argc <= e->args) {
461  return CLI_SHOWUSAGE;
462  }
463 
464  if (handler == DEBUG_HANDLER) {
465  modules = &debug_modules;
466  module_option = AST_OPT_FLAG_DEBUG_MODULE;
467  core_option = &option_debug;
468  handler_name = "debug";
469  } else {
470  modules = &trace_modules;
471  module_option = AST_OPT_FLAG_TRACE_MODULE;
472  core_option = &option_trace;
473  handler_name = "trace";
474  }
475 
476  if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args], "off")) {
477  newlevel = 0;
478  } else {
479  if (!strcasecmp(a->argv[e->args], "atleast")) {
480  atleast = 1;
481  }
482 
483  if (a->argc != e->args + atleast + 1 && a->argc != e->args + atleast + 2) {
484  return CLI_SHOWUSAGE;
485  }
486 
487  if (sscanf(a->argv[e->args + atleast], "%30d", &newlevel) != 1) {
488  return CLI_SHOWUSAGE;
489  }
490 
491  if (a->argc == e->args + atleast + 2) {
492  /* We have specified a module name. */
493  char *mod = ast_strdupa(a->argv[e->args + atleast + 1]);
494  int mod_len = strlen(mod);
495 
496  if (3 < mod_len && !strcasecmp(mod + mod_len - 3, ".so")) {
497  mod[mod_len - 3] = '\0';
498  }
499 
500  AST_RWLIST_WRLOCK(modules);
501 
502  ml = find_module_level(mod, modules);
503  if (!newlevel) {
504  if (!ml) {
505  /* Specified off for a nonexistent entry. */
506  AST_RWLIST_UNLOCK(modules);
507  ast_cli(a->fd, "Core %s is still 0 for '%s'.\n", handler_name, mod);
508  return CLI_SUCCESS;
509  }
510  AST_RWLIST_REMOVE(modules, ml, entry);
511  if (AST_RWLIST_EMPTY(modules)) {
512  ast_clear_flag(&ast_options, module_option);
513  }
514  AST_RWLIST_UNLOCK(modules);
515  ast_cli(a->fd, "Core %s was %u and has been set to 0 for '%s'.\n", handler_name,
516  ml->level, mod);
517  ast_free(ml);
518  return CLI_SUCCESS;
519  }
520 
521  if (ml) {
522  if ((atleast && newlevel < ml->level) || ml->level == newlevel) {
523  ast_cli(a->fd, "Core %s is still %u for '%s'.\n", handler_name, ml->level, mod);
524  AST_RWLIST_UNLOCK(modules);
525  return CLI_SUCCESS;
526  }
527  oldval = ml->level;
528  ml->level = newlevel;
529  } else {
530  ml = ast_calloc(1, sizeof(*ml) + strlen(mod) + 1);
531  if (!ml) {
532  AST_RWLIST_UNLOCK(modules);
533  return CLI_FAILURE;
534  }
535  oldval = ml->level;
536  ml->level = newlevel;
537  strcpy(ml->module, mod);
538  AST_RWLIST_INSERT_TAIL(modules, ml, entry);
539  }
540  ast_set_flag(&ast_options, module_option);
541 
542  ast_cli(a->fd, "Core %s was %d and has been set to %u for '%s'.\n", handler_name,
543  oldval, ml->level, ml->module);
544 
545  AST_RWLIST_UNLOCK(modules);
546 
547  return CLI_SUCCESS;
548  }
549  }
550 
551  /* Update global debug level */
552  if (!newlevel) {
553  /* Specified level was 0 or off. */
554  AST_RWLIST_WRLOCK(modules);
555  while ((ml = AST_RWLIST_REMOVE_HEAD(modules, entry))) {
556  ast_free(ml);
557  }
559  AST_RWLIST_UNLOCK(modules);
560  }
561  oldval = *core_option;
562  if (!atleast || newlevel > *core_option) {
563  *core_option = newlevel;
564  }
565 
566  /* Report debug level status */
567  status_debug_verbose(a, handler, oldval, *core_option);
568 
569  return CLI_SUCCESS;
570 }
static struct module_level_list debug_modules
Definition: main/cli.c:107
static struct module_level * find_module_level(const char *module, struct module_level_list *mll)
Find the module level setting.
Definition: main/cli.c:351
unsigned int level
Definition: main/cli.c:99
int option_debug
Definition: options.c:69
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define ast_set_flag(p, flag)
Definition: utils.h:70
const int argc
Definition: cli.h:160
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
map a debug or verbose level to a module name
Definition: main/cli.c:98
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int args
This gets set in ast_cli_register()
Definition: cli.h:185
#define DEBUG_HANDLER
Definition: main/cli.c:403
const int fd
Definition: cli.h:159
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char *const * argv
Definition: cli.h:161
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
#define CLI_SHOWUSAGE
Definition: cli.h:45
static struct module_level_list trace_modules
Definition: main/cli.c:108
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:843
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define CLI_SUCCESS
Definition: cli.h:44
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
struct ast_flags ast_options
Definition: options.c:61
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:884
Definition: search.h:40
static void status_debug_verbose(struct ast_cli_args *a, int handler, int old_val, int cur_val)
Definition: main/cli.c:407
int option_trace
Definition: options.c:71

◆ handle_help()

static char * handle_help ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2552 of file main/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, NULL, ast_cli_entry::usage, and ast_cli_args::word.

Referenced by handle_cli_malloc_trim().

2553 {
2554  char fullcmd[80];
2555  struct ast_cli_entry *my_e;
2556  char *res = CLI_SUCCESS;
2557 
2558  if (cmd == CLI_INIT) {
2559  e->command = "core show help";
2560  e->usage =
2561  "Usage: core show help [topic]\n"
2562  " When called with a topic as an argument, displays usage\n"
2563  " information on the given command. If called without a\n"
2564  " topic, it provides a list of commands.\n";
2565  return NULL;
2566 
2567  } else if (cmd == CLI_GENERATE) {
2568  /* skip first 14 or 15 chars, "core show help " */
2569  int l = strlen(a->line);
2570 
2571  if (l > 15) {
2572  l = 15;
2573  }
2574  /* XXX watch out, should stop to the non-generator parts */
2575  return __ast_cli_generator(a->line + l, a->word, a->n, 0);
2576  }
2577  if (a->argc == e->args) {
2578  return help1(a->fd, NULL, 0);
2579  }
2580 
2582  my_e = find_cli(a->argv + 3, 1); /* try exact match first */
2583  if (!my_e) {
2584  res = help1(a->fd, a->argv + 3, 1 /* locked */);
2586  return res;
2587  }
2588  if (my_e->usage)
2589  ast_cli(a->fd, "%s", my_e->usage);
2590  else {
2591  ast_join(fullcmd, sizeof(fullcmd), a->argv + 3);
2592  ast_cli(a->fd, "No help text available for '%s'.\n", fullcmd);
2593  }
2595  return res;
2596 }
#define ast_join(s, len, w)
Definition: strings.h:483
descriptor for a cli entry.
Definition: cli.h:171
const int argc
Definition: cli.h:160
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:152
static char * help1(int fd, const char *const match[], int locked)
helper for final part of handle_help if locked = 1, assume the list is already locked ...
Definition: main/cli.c:2522
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
int args
This gets set in ast_cli_register()
Definition: cli.h:185
static char * __ast_cli_generator(const char *text, const char *word, int state, int lock)
Definition: main/cli.c:2829
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
static struct ast_cli_entry * find_cli(const char *const cmds[], int match_type)
Definition: main/cli.c:2316
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_load()

static char* handle_load ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 240 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_load_resource(), ast_module_helper(), AST_MODULE_HELPER_LOAD, 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, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

241 {
242  /* "module load <mod>" */
243  switch (cmd) {
244  case CLI_INIT:
245  e->command = "module load";
246  e->usage =
247  "Usage: module load <module name>\n"
248  " Loads the specified module into Asterisk.\n";
249  return NULL;
250 
251  case CLI_GENERATE:
252  if (a->pos != e->args) {
253  return NULL;
254  }
255  return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, AST_MODULE_HELPER_LOAD);
256  }
257  if (a->argc != e->args + 1) {
258  return CLI_SHOWUSAGE;
259  }
260  if (ast_load_resource(a->argv[e->args])) {
261  ast_cli(a->fd, "Unable to load module %s\n", a->argv[e->args]);
262  return CLI_FAILURE;
263  }
264  ast_cli(a->fd, "Loaded %s\n", a->argv[e->args]);
265  return CLI_SUCCESS;
266 }
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
Match modules names for the Asterisk cli.
Definition: loader.c:1374
enum ast_module_load_result ast_load_resource(const char *resource_name)
Load a module.
Definition: loader.c:1819
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164

◆ handle_logger_mute()

static char* handle_logger_mute ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 783 of file main/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, NULL, and ast_cli_entry::usage.

784 {
785  switch (cmd) {
786  case CLI_INIT:
787  e->command = "logger mute";
788  e->usage =
789  "Usage: logger mute\n"
790  " Disables logging output to the current console, making it possible to\n"
791  " gather information without being disturbed by scrolling lines.\n";
792  return NULL;
793  case CLI_GENERATE:
794  return NULL;
795  }
796 
797  if (a->argc < 2 || a->argc > 3)
798  return CLI_SHOWUSAGE;
799 
800  if (a->argc == 3 && !strcasecmp(a->argv[2], "silent"))
802  else
804 
805  return CLI_SUCCESS;
806 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_console_toggle_mute(int fd, int silent)
mute or unmute a console from logging
Definition: asterisk.c:1232
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_modlist()

static char* handle_modlist ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 971 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_module_helper(), AST_MODULE_HELPER_LOADED, ast_mutex_lock, ast_mutex_unlock, ast_update_module_list(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, climodentryfd, climodentrylock, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, MODLIST_FORMAT2, modlist_modentry(), ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

972 {
973  const char *like;
974 
975  switch (cmd) {
976  case CLI_INIT:
977  e->command = "module show [like]";
978  e->usage =
979  "Usage: module show [like keyword]\n"
980  " Shows Asterisk modules currently in use, and usage statistics.\n";
981  return NULL;
982 
983  case CLI_GENERATE:
984  if (a->pos == e->args) {
985  return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, AST_MODULE_HELPER_LOADED);
986  } else {
987  return NULL;
988  }
989  }
990  /* all the above return, so we proceed with the handler.
991  * we are guaranteed to have argc >= e->args
992  */
993  if (a->argc == e->args - 1)
994  like = "";
995  else if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args-1], "like") )
996  like = a->argv[e->args];
997  else
998  return CLI_SHOWUSAGE;
999 
1001  climodentryfd = a->fd; /* global, protected by climodentrylock */
1002  ast_cli(a->fd, MODLIST_FORMAT2, "Module", "Description", "Use Count", "Status", "Support Level");
1003  ast_cli(a->fd,"%d modules loaded\n", ast_update_module_list(modlist_modentry, like));
1004  climodentryfd = -1;
1006  return CLI_SUCCESS;
1007 }
static ast_mutex_t climodentrylock
Definition: main/cli.c:860
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
Match modules names for the Asterisk cli.
Definition: loader.c:1374
const int argc
Definition: cli.h:160
static int climodentryfd
Definition: main/cli.c:861
Definition: cli.h:152
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define MODLIST_FORMAT2
Definition: main/cli.c:858
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
static int modlist_modentry(const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level)
Definition: main/cli.c:863
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164
int ast_update_module_list(int(*modentry)(const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level), const char *like)
Ask for a list of modules, descriptions, use counts and status.
Definition: loader.c:2567
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ handle_nodebugchan_deprecated()

static char* handle_nodebugchan_deprecated ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1583 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, handle_core_set_debug_channel(), and NULL.

1584 {
1585  char *res;
1586 
1587  switch (cmd) {
1588  case CLI_INIT:
1589  e->command = "no debug channel";
1590  return NULL;
1591  case CLI_HANDLER:
1592  /* exit out of switch statement */
1593  break;
1594  default:
1595  return NULL;
1596  }
1597 
1598  if (a->argc != e->args + 1)
1599  return CLI_SHOWUSAGE;
1600 
1601  /* add a 'magic' value to the CLI_HANDLER command so that
1602  * handle_core_set_debug_channel() will act as if 'off'
1603  * had been specified as part of the command
1604  */
1605  res = handle_core_set_debug_channel(e, CLI_HANDLER + 1000, a);
1606 
1607  return res;
1608 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
static char * handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/cli.c:1476
#define NULL
Definition: resample.c:96
int args
This gets set in ast_cli_register()
Definition: cli.h:185
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186

◆ handle_reload()

static char* handle_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 268 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_module_helper(), AST_MODULE_HELPER_RELOAD, ast_module_reload(), AST_MODULE_RELOAD_ERROR, AST_MODULE_RELOAD_IN_PROGRESS, AST_MODULE_RELOAD_NOT_FOUND, AST_MODULE_RELOAD_NOT_IMPLEMENTED, AST_MODULE_RELOAD_QUEUED, AST_MODULE_RELOAD_SUCCESS, AST_MODULE_RELOAD_UNINITIALIZED, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

269 {
270  int x;
271 
272  switch (cmd) {
273  case CLI_INIT:
274  e->command = "module reload";
275  e->usage =
276  "Usage: module reload [module ...]\n"
277  " Reloads configuration files for all listed modules which support\n"
278  " reloading, or for all supported modules if none are listed.\n";
279  return NULL;
280 
281  case CLI_GENERATE:
282  return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, AST_MODULE_HELPER_RELOAD);
283  }
284  if (a->argc == e->args) {
286  return CLI_SUCCESS;
287  }
288  for (x = e->args; x < a->argc; x++) {
290  switch (res) {
292  ast_cli(a->fd, "No such module '%s'\n", a->argv[x]);
293  break;
295  ast_cli(a->fd, "The module '%s' does not support reloads\n", a->argv[x]);
296  break;
298  ast_cli(a->fd, "Asterisk cannot reload a module yet; request queued\n");
299  break;
301  ast_cli(a->fd, "The module '%s' reported a reload failure\n", a->argv[x]);
302  break;
304  ast_cli(a->fd, "A module reload request is already in progress; please be patient\n");
305  break;
307  ast_cli(a->fd, "The module '%s' was not properly initialized. Before reloading"
308  " the module, you must run \"module load %s\" and fix whatever is"
309  " preventing the module from being initialized.\n", a->argv[x], a->argv[x]);
310  break;
312  ast_cli(a->fd, "Module '%s' reloaded successfully.\n", a->argv[x]);
313  break;
314  }
315  }
316  return CLI_SUCCESS;
317 }
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
Match modules names for the Asterisk cli.
Definition: loader.c:1374
enum ast_module_reload_result ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:1562
ast_module_reload_result
Possible return types for ast_module_reload.
Definition: module.h:109
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164

◆ handle_showcalls()

static char* handle_showcalls ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1011 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_cli(), ast_cli_complete(), ast_option_maxcalls, ast_processed_calls(), ast_startuptime, ast_tvnow(), ast_tvsub(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, ESS, ast_cli_args::fd, ast_cli_args::n, NULL, ast_cli_args::pos, print_uptimestr(), RESULT_SUCCESS, ast_cli_entry::usage, and ast_cli_args::word.

1012 {
1013  static const char * const completions[] = { "seconds", NULL };
1014  struct timeval curtime = ast_tvnow();
1015  int showuptime, printsec;
1016 
1017  switch (cmd) {
1018  case CLI_INIT:
1019  e->command = "core show calls [uptime]";
1020  e->usage =
1021  "Usage: core show calls [uptime [seconds]]\n"
1022  " Lists number of currently active calls and total number of calls\n"
1023  " processed through PBX since last restart. If 'uptime' is specified\n"
1024  " the system uptime is also displayed. If 'seconds' is specified in\n"
1025  " addition to 'uptime', the system uptime is displayed in seconds.\n";
1026  return NULL;
1027 
1028  case CLI_GENERATE:
1029  if (a->pos != e->args)
1030  return NULL;
1031  return ast_cli_complete(a->word, completions, a->n);
1032  }
1033 
1034  /* regular handler */
1035  if (a->argc >= e->args && !strcasecmp(a->argv[e->args-1],"uptime")) {
1036  showuptime = 1;
1037 
1038  if (a->argc == e->args+1 && !strcasecmp(a->argv[e->args],"seconds"))
1039  printsec = 1;
1040  else if (a->argc == e->args)
1041  printsec = 0;
1042  else
1043  return CLI_SHOWUSAGE;
1044  } else if (a->argc == e->args-1) {
1045  showuptime = 0;
1046  printsec = 0;
1047  } else
1048  return CLI_SHOWUSAGE;
1049 
1050  if (ast_option_maxcalls) {
1051  ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
1053  ((double)ast_active_calls() / (double)ast_option_maxcalls) * 100.0);
1054  } else {
1055  ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
1056  }
1057 
1058  ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
1059 
1060  if (ast_startuptime.tv_sec && showuptime) {
1061  print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime: ", printsec);
1062  }
1063 
1064  return RESULT_SUCCESS;
1065 }
int ast_active_calls(void)
Retrieve the number of active calls.
Definition: pbx.c:4764
static void print_uptimestr(int fd, struct timeval timeval, const char *prefix, int printsec)
Definition: main/cli.c:876
const int argc
Definition: cli.h:160
Definition: cli.h:152
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int ast_option_maxcalls
Definition: options.c:79
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
int ast_processed_calls(void)
Retrieve the total number of calls processed through the PBX since last restart.
Definition: pbx.c:4769
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ESS(x)
Definition: cli.h:59
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
char * ast_cli_complete(const char *word, const char *const choices[], int state)
Definition: main/cli.c:1811
const char * usage
Definition: cli.h:177
struct timeval ast_startuptime
Definition: asterisk.c:336
const int pos
Definition: cli.h:164
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2298
#define RESULT_SUCCESS
Definition: cli.h:40

◆ handle_showchan()

static char* handle_showchan ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

< Buffer for CDR variables.

< Accumulation buffer for all output.

Definition at line 1610 of file main/cli.c.

References ao2_cleanup, ast_cli_args::argc, ast_cli_args::argv, ast_callid_strnprint(), ast_cdr_serialize_variables(), AST_CHAN_TP_INTERNAL, ast_channel_appl(), ast_channel_caller(), ast_channel_callgroup(), ast_channel_callid(), ast_channel_connected(), ast_channel_connected_effective_id(), ast_channel_context(), ast_channel_creationtime(), ast_channel_data(), ast_channel_dialed(), ast_channel_exten(), ast_channel_get_bridge(), ast_channel_get_by_name(), ast_channel_get_stream_topology(), ast_channel_language(), ast_channel_linkedid(), ast_channel_lock, ast_channel_name(), ast_channel_nativeformats(), ast_channel_pickupgroup(), ast_channel_priority(), ast_channel_readformat(), ast_channel_readtrans(), ast_channel_tech(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_channel_varshead(), ast_channel_whentohangup(), ast_channel_writeformat(), ast_channel_writetrans(), ast_cli(), ast_codec_media_type2str(), ast_complete_channels(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_format_get_name(), ast_free, AST_LIST_TRAVERSE, ast_state2str(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_strlen(), ast_str_thread_get(), ast_stream_get_formats(), ast_stream_get_group(), ast_stream_get_metadata_list(), ast_stream_get_name(), ast_stream_get_state(), ast_stream_get_type(), ast_stream_state2str(), ast_stream_topology_get_count(), ast_stream_topology_get_stream(), ast_translate_path_to_str(), ast_tvnow(), ast_tvzero(), ast_var_name(), ast_var_value(), ast_variables_destroy(), ast_bridge::callid, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, min, ast_cli_args::n, name, ast_variable::name, ast_variable::next, NULL, ast_cli_args::pos, S_COR, S_OR, type, ast_bridge::uniqueid, ast_cli_entry::usage, ast_variable::value, var, and ast_cli_args::word.

1611 {
1612  struct ast_channel *chan;
1613  struct timeval now;
1614  char cdrtime[256];
1615  struct ast_str *obuf;/*!< Buffer for CDR variables. */
1616  struct ast_str *output;/*!< Accumulation buffer for all output. */
1617  long elapsed_seconds=0;
1618  int hour=0, min=0, sec=0;
1619  struct ast_var_t *var;
1620  struct ast_str *write_transpath = ast_str_alloca(256);
1621  struct ast_str *read_transpath = ast_str_alloca(256);
1622  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1623  struct ast_bridge *bridge;
1625  char callid_buf[32];
1626  int stream_num;
1627 
1628  switch (cmd) {
1629  case CLI_INIT:
1630  e->command = "core show channel";
1631  e->usage =
1632  "Usage: core show channel <channel>\n"
1633  " Shows lots of information about the specified channel.\n";
1634  return NULL;
1635  case CLI_GENERATE:
1636  return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
1637  }
1638 
1639  if (a->argc != 4) {
1640  return CLI_SHOWUSAGE;
1641  }
1642 
1643  obuf = ast_str_thread_get(&ast_str_thread_global_buf, 16);
1644  if (!obuf) {
1645  return CLI_FAILURE;
1646  }
1647 
1648  chan = ast_channel_get_by_name(a->argv[3]);
1649  if (!chan) {
1650  ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
1651 
1652  return CLI_SUCCESS;
1653  }
1654 
1655  output = ast_str_create(8192);
1656  if (!output) {
1657  ast_channel_unref(chan);
1658 
1659  return CLI_FAILURE;
1660  }
1661 
1662  now = ast_tvnow();
1663  ast_channel_lock(chan);
1664 
1665  if (!ast_tvzero(ast_channel_creationtime(chan))) {
1666  elapsed_seconds = now.tv_sec - ast_channel_creationtime(chan).tv_sec;
1667  hour = elapsed_seconds / 3600;
1668  min = (elapsed_seconds % 3600) / 60;
1669  sec = elapsed_seconds % 60;
1670  snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
1671  } else {
1672  strcpy(cdrtime, "N/A");
1673  }
1674 
1675  ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath);
1676  ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath);
1677 
1678  bridge = ast_channel_get_bridge(chan);
1679  callid_buf[0] = '\0';
1680  callid = ast_channel_callid(chan);
1681  if (callid) {
1682  ast_callid_strnprint(callid_buf, sizeof(callid_buf), callid);
1683  }
1684 
1685  ast_str_append(&output, 0,
1686  " -- General --\n"
1687  " Name: %s\n"
1688  " Type: %s\n"
1689  " UniqueID: %s\n"
1690  " LinkedID: %s\n"
1691  " Caller ID: %s\n"
1692  " Caller ID Name: %s\n"
1693  "Connected Line ID: %s\n"
1694  "Connected Line ID Name: %s\n"
1695  "Eff. Connected Line ID: %s\n"
1696  "Eff. Connected Line ID Name: %s\n"
1697  " DNID Digits: %s\n"
1698  " Language: %s\n"
1699  " State: %s (%u)\n"
1700  " NativeFormats: %s\n"
1701  " WriteFormat: %s\n"
1702  " ReadFormat: %s\n"
1703  " WriteTranscode: %s %s\n"
1704  " ReadTranscode: %s %s\n"
1705  " Time to Hangup: %ld\n"
1706  " Elapsed Time: %s\n"
1707  " Bridge ID: %s\n"
1708  " -- PBX --\n"
1709  " Context: %s\n"
1710  " Extension: %s\n"
1711  " Priority: %d\n"
1712  " Call Group: %llu\n"
1713  " Pickup Group: %llu\n"
1714  " Application: %s\n"
1715  " Data: %s\n"
1716  " Call Identifer: %s\n",
1717  ast_channel_name(chan),
1718  ast_channel_tech(chan)->type,
1719  ast_channel_uniqueid(chan),
1720  ast_channel_linkedid(chan),
1721  S_COR(ast_channel_caller(chan)->id.number.valid,
1722  ast_channel_caller(chan)->id.number.str, "(N/A)"),
1723  S_COR(ast_channel_caller(chan)->id.name.valid,
1724  ast_channel_caller(chan)->id.name.str, "(N/A)"),
1725  S_COR(ast_channel_connected(chan)->id.number.valid,
1726  ast_channel_connected(chan)->id.number.str, "(N/A)"),
1727  S_COR(ast_channel_connected(chan)->id.name.valid,
1728  ast_channel_connected(chan)->id.name.str, "(N/A)"),
1730  ast_channel_connected_effective_id(chan).number.str, "(N/A)"),
1732  ast_channel_connected_effective_id(chan).name.str, "(N/A)"),
1733  S_OR(ast_channel_dialed(chan)->number.str, "(N/A)"),
1734  ast_channel_language(chan),
1736  ast_channel_state(chan),
1740  ast_str_strlen(write_transpath) ? "Yes" : "No",
1741  ast_str_buffer(write_transpath),
1742  ast_str_strlen(read_transpath) ? "Yes" : "No",
1743  ast_str_buffer(read_transpath),
1744  (long)ast_channel_whentohangup(chan)->tv_sec,
1745  cdrtime,
1746  bridge ? bridge->uniqueid : "(Not bridged)",
1747  ast_channel_context(chan),
1748  ast_channel_exten(chan),
1749  ast_channel_priority(chan),
1750  ast_channel_callgroup(chan),
1752  S_OR(ast_channel_appl(chan), "(N/A)"),
1753  S_OR(ast_channel_data(chan), "(Empty)"),
1754  S_OR(callid_buf, "(None)")
1755  );
1756 
1757  ast_str_append(&output, 0, " Variables:\n");
1758 
1759  AST_LIST_TRAVERSE(ast_channel_varshead(chan), var, entries) {
1760  ast_str_append(&output, 0, "%s=%s\n", ast_var_name(var), ast_var_value(var));
1761  }
1762 
1763  if (!(ast_channel_tech(chan)->properties & AST_CHAN_TP_INTERNAL)
1764  && ast_cdr_serialize_variables(ast_channel_name(chan), &obuf, '=', '\n')) {
1765  ast_str_append(&output, 0, " CDR Variables:\n%s\n", ast_str_buffer(obuf));
1766  }
1767 
1768  ast_str_append(&output, 0, " -- Streams --\n");
1769  for (stream_num = 0; stream_num < ast_stream_topology_get_count(ast_channel_get_stream_topology(chan)); stream_num++) {
1771  struct ast_variable *metadata = ast_stream_get_metadata_list(stream);
1772 
1773  ast_str_append(&output, 0,
1774  "Name: %s\n"
1775  " Type: %s\n"
1776  " State: %s\n"
1777  " Group: %d\n"
1778  " Formats: %s\n"
1779  " Metadata:\n",
1780  ast_stream_get_name(stream),
1783  ast_stream_get_group(stream),
1785  );
1786 
1787  if (metadata) {
1788  struct ast_variable *v;
1789  for(v = metadata; v; v = v->next) {
1790  ast_str_append(&output, 0, " %s: %s\n", v->name, v->value);
1791  }
1792  ast_variables_destroy(metadata);
1793  }
1794  }
1795 
1796  ast_channel_unlock(chan);
1797 
1798  ast_cli(a->fd, "%s", ast_str_buffer(output));
1799  ast_free(output);
1800 
1801  ao2_cleanup(bridge);
1802  ast_channel_unref(chan);
1803 
1804  return CLI_SUCCESS;
1805 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
struct ast_variable * next
static const char type[]
Definition: chan_ooh323.c:109
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: main/cli.c:1830
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
int ast_stream_get_group(const struct ast_stream *stream)
Get the stream group that a stream is part of.
Definition: stream.c:1077
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
const char * ast_var_value(const struct ast_var_t *var)
Definition: chanvars.c:80
const char * ast_var_name(const struct ast_var_t *var)
Definition: chanvars.c:60
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316
const int argc
Definition: cli.h:160
ast_callid callid
Definition: bridge.h:369
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:326
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition: codec.c:347
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:108
Definition: cli.h:152
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
unsigned int ast_callid
Definition: logger.h:87
#define ast_str_alloca(init_len)
Definition: strings.h:800
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
struct varshead * ast_channel_varshead(struct ast_channel *chan)
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
Definition: channel.c:642
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition: stream.c:788
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int ast_channel_priority(const struct ast_channel *chan)
struct ast_trans_pvt * ast_channel_readtrans(const struct ast_channel *chan)
const char * ast_channel_linkedid(const struct ast_channel *chan)
const char * line
Definition: cli.h:162
struct timeval * ast_channel_whentohangup(struct ast_channel *chan)
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
Number structure.
Definition: app_followme.c:154
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10735
const int fd
Definition: cli.h:159
struct ast_trans_pvt * ast_channel_writetrans(const struct ast_channel *chan)
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
const int n
Definition: cli.h:165
struct ast_variable * ast_stream_get_metadata_list(const struct ast_stream *stream)
Get all stream metadata keys.
Definition: stream.c:439
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:972
const char * ast_channel_exten(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char *const * argv
Definition: cli.h:161
Structure that contains information about a bridge.
Definition: bridge.h:357
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
#define CLI_SHOWUSAGE
Definition: cli.h:45
void ast_callid_strnprint(char *buffer, size_t buffer_size, ast_callid callid)
copy a string representation of the callid into a target string
Definition: logger.c:1952
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct timeval ast_channel_creationtime(struct ast_channel *chan)
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:736
const char * ast_channel_appl(const struct ast_channel *chan)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define CLI_FAILURE
Definition: cli.h:46
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
const char * usage
Definition: cli.h:177
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
const char * ast_channel_data(const struct ast_channel *chan)
#define CLI_SUCCESS
Definition: cli.h:44
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
const char * ast_translate_path_to_str(struct ast_trans_pvt *t, struct ast_str **str)
Puts a string representation of the translation path into outbuf.
Definition: translate.c:928
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
const int pos
Definition: cli.h:164
const char * ast_stream_state2str(enum ast_stream_state state)
Convert the state of a stream into a string.
Definition: stream.c:388
int ast_cdr_serialize_variables(const char *channel_name, struct ast_str **buf, char delim, char sep)
Serializes all the data and variables for a current CDR record.
Definition: cdr.c:3353
const char * ast_channel_language(const struct ast_channel *chan)
ast_group_t ast_channel_pickupgroup(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:861
ast_group_t ast_channel_callgroup(const struct ast_channel *chan)
const char * ast_stream_get_name(const struct ast_stream *stream)
Get the name of a stream.
Definition: stream.c:309
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
#define min(a, b)
Definition: f2c.h:197
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
ast_callid ast_channel_callid(const struct ast_channel *chan)
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ handle_showuptime()

static char* handle_showuptime ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 938 of file main/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, NULL, print_uptimestr(), and ast_cli_entry::usage.

939 {
940  struct timeval curtime = ast_tvnow();
941  int printsec;
942 
943  switch (cmd) {
944  case CLI_INIT:
945  e->command = "core show uptime [seconds]";
946  e->usage =
947  "Usage: core show uptime [seconds]\n"
948  " Shows Asterisk uptime information.\n"
949  " The seconds word returns the uptime in seconds only.\n";
950  return NULL;
951 
952  case CLI_GENERATE:
953  return NULL;
954  }
955  /* regular handler */
956  if (a->argc == e->args && !strcasecmp(a->argv[e->args-1],"seconds"))
957  printsec = 1;
958  else if (a->argc == e->args-1)
959  printsec = 0;
960  else
961  return CLI_SHOWUSAGE;
962  if (ast_startuptime.tv_sec) {
963  print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime: ", printsec);
964  }
965  if (ast_lastreloadtime.tv_sec) {
966  print_uptimestr(a->fd, ast_tvsub(curtime, ast_lastreloadtime), "Last reload: ", printsec);
967  }
968  return CLI_SUCCESS;
969 }
static void print_uptimestr(int fd, struct timeval timeval, const char *prefix, int printsec)
Definition: main/cli.c:876
const int argc
Definition: cli.h:160
Definition: cli.h:152
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
struct timeval ast_lastreloadtime
Definition: asterisk.c:337
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
struct timeval ast_startuptime
Definition: asterisk.c:336
#define CLI_SUCCESS
Definition: cli.h:44
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2298

◆ handle_softhangup()

static char* handle_softhangup ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1195 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_channel_unref, ast_cli(), ast_cli_complete(), ast_complete_channels(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, c, 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, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

1196 {
1197  struct ast_channel *c = NULL;
1198  static const char * const completions[] = { "all", NULL };
1199  char *complete;
1200 
1201  switch (cmd) {
1202  case CLI_INIT:
1203  e->command = "channel request hangup";
1204  e->usage =
1205  "Usage: channel request hangup <channel>|<all>\n"
1206  " Request that a channel be hung up. The hangup takes effect\n"
1207  " the next time the driver reads or writes from the channel.\n"
1208  " If 'all' is specified instead of a channel name, all channels\n"
1209  " will see the hangup request.\n";
1210  return NULL;
1211  case CLI_GENERATE:
1212  if (a->pos != e->args) {
1213  return NULL;
1214  }
1215  complete = ast_cli_complete(a->word, completions, a->n);
1216  if (!complete) {
1217  complete = ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
1218  }
1219  return complete;
1220  }
1221 
1222  if (a->argc != 4) {
1223  return CLI_SHOWUSAGE;
1224  }
1225 
1226  if (!strcasecmp(a->argv[3], "all")) {
1227  struct ast_channel_iterator *iter = NULL;
1228  if (!(iter = ast_channel_iterator_all_new())) {
1229  return CLI_FAILURE;
1230  }
1231  for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
1232  ast_channel_lock(c);
1233  ast_cli(a->fd, "Requested Hangup on channel '%s'\n", ast_channel_name(c));
1235  ast_channel_unlock(c);
1236  }
1238  } else if ((c = ast_channel_get_by_name(a->argv[3]))) {
1239  ast_channel_lock(c);
1240  ast_cli(a->fd, "Requested Hangup on channel '%s'\n", ast_channel_name(c));
1242  ast_channel_unlock(c);
1243  c = ast_channel_unref(c);
1244  } else {
1245  ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
1246  }
1247 
1248  return CLI_SUCCESS;
1249 }
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: main/cli.c:1830
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1422
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
const int argc
Definition: cli.h:160
Definition: cli.h:152
static struct test_val c
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
char * ast_cli_complete(const char *word, const char *const choices[], int state)
Definition: main/cli.c:1811
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const char * ast_channel_name(const struct ast_channel *chan)
const int pos
Definition: cli.h:164
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1360
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1408
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454

◆ handle_trace()

static char* handle_trace ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 630 of file main/cli.c.

References ast_cli_args::argv, ast_module_helper(), AST_MODULE_HELPER_RUNNING, ast_strdup, ast_strlen_zero, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_number(), handle_debug_or_trace(), ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, S_OR, TRACE_HANDLER, ast_cli_entry::usage, and ast_cli_args::word.

631 {
632  int atleast = 0;
633  const char *argv3 = a->argv ? S_OR(a->argv[3], "") : "";
634 
635  switch (cmd) {
636  case CLI_INIT:
637  e->command = "core set trace";
638  e->usage =
639  "Usage: core set trace [atleast] <level> [module]\n"
640  " core set trace off\n"
641  "\n"
642  " Sets level of trace messages to be displayed or\n"
643  " sets a module name to display trace messages from.\n"
644  " 0 or off means no messages should be displayed.\n";
645  return NULL;
646 
647  case CLI_GENERATE:
648  if (!strcasecmp(argv3, "atleast")) {
649  atleast = 1;
650  }
651  if (a->pos == 3 || (a->pos == 4 && atleast)) {
652  const char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], "");
653  int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21;
654 
655  if (a->n < 21 && numbermatch == 0) {
656  return complete_number(pos, 0, 0x7fffffff, a->n);
657  } else if (pos[0] == '0') {
658  if (a->n == 0) {
659  return ast_strdup("0");
660  }
661  } else if (a->n == (21 - numbermatch)) {
662  if (a->pos == 3 && !strncasecmp(argv3, "off", strlen(argv3))) {
663  return ast_strdup("off");
664  } else if (a->pos == 3 && !strncasecmp(argv3, "atleast", strlen(argv3))) {
665  return ast_strdup("atleast");
666  }
667  } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) {
668  return ast_strdup("atleast");
669  }
670  } else if ((a->pos == 4 && !atleast && strcasecmp(argv3, "off") && strcasecmp(argv3, "channel"))
671  || (a->pos == 5 && atleast)) {
672  return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, AST_MODULE_HELPER_RUNNING);
673  }
674  return NULL;
675  }
676  /* all the above return, so we proceed with the handler.
677  * we are guaranteed to be called with argc >= e->args;
678  */
679 
680  return handle_debug_or_trace(TRACE_HANDLER, e, cmd, a);
681 }
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
Match modules names for the Asterisk cli.
Definition: loader.c:1374
Definition: cli.h:152
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
const char * line
Definition: cli.h:162
#define TRACE_HANDLER
Definition: main/cli.c:404
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char * handle_debug_or_trace(int handler, struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: main/cli.c:449
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const int pos
Definition: cli.h:164
static char * complete_number(const char *partial, unsigned int min, unsigned int max, int n)
Definition: main/cli.c:363

◆ handle_unload()

static char* handle_unload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 808 of file main/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_MODULE_HELPER_UNLOAD, 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, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

809 {
810  /* "module unload mod_1 [mod_2 .. mod_N]" */
811  int x;
812  int force = AST_FORCE_SOFT;
813  const char *s;
814 
815  switch (cmd) {
816  case CLI_INIT:
817  e->command = "module unload";
818  e->usage =
819  "Usage: module unload [-f|-h] <module_1> [<module_2> ... ]\n"
820  " Unloads the specified module from Asterisk. The -f\n"
821  " option causes the module to be unloaded even if it is\n"
822  " in use (may cause a crash) and the -h module causes the\n"
823  " module to be unloaded even if the module says it cannot, \n"
824  " which almost always will cause a crash.\n";
825  return NULL;
826 
827  case CLI_GENERATE:
828  return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, AST_MODULE_HELPER_UNLOAD);
829  }
830  if (a->argc < e->args + 1)
831  return CLI_SHOWUSAGE;
832  x = e->args; /* first argument */
833  s = a->argv[x];
834  if (s[0] == '-') {
835  if (s[1] == 'f')
836  force = AST_FORCE_FIRM;
837  else if (s[1] == 'h')
838  force = AST_FORCE_HARD;
839  else
840  return CLI_SHOWUSAGE;
841  if (a->argc < e->args + 2) /* need at least one module name */
842  return CLI_SHOWUSAGE;
843  x++; /* skip this argument */
844  }
845 
846  for (; x < a->argc; x++) {
847  if (ast_unload_resource(a->argv[x], force)) {
848  ast_cli(a->fd, "Unable to unload resource %s\n", a->argv[x]);
849  return CLI_FAILURE;
850  }
851  ast_cli(a->fd, "Unloaded %s\n", a->argv[x]);
852  }
853 
854  return CLI_SUCCESS;
855 }
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
Match modules names for the Asterisk cli.
Definition: loader.c:1374
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:1229
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164

◆ handle_verbose()

static char* handle_verbose ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 683 of file main/cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_strdup, ast_strlen_zero, ast_verb_console_get(), ast_verb_console_set(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_number(), ast_cli_args::n, NULL, ast_cli_args::pos, S_OR, status_debug_verbose(), ast_cli_entry::usage, and VERBOSE_HANDLER.

684 {
685  int oldval;
686  int newlevel;
687  int atleast = 0;
688  int silent = 0;
689  const char *argv3 = a->argv ? S_OR(a->argv[3], "") : "";
690 
691  switch (cmd) {
692  case CLI_INIT:
693  e->command = "core set verbose";
694  e->usage =
695  "Usage: core set verbose [atleast] <level> [silent]\n"
696  " core set verbose off\n"
697  "\n"
698  " Sets level of verbose messages to be displayed.\n"
699  " 0 or off means no verbose messages should be displayed.\n"
700  " The silent option means the command does not report what\n"
701  " happened to the verbose level.\n"
702  " Equivalent to -v[v[...]] on startup\n";
703  return NULL;
704 
705  case CLI_GENERATE:
706  if (!strcasecmp(argv3, "atleast")) {
707  atleast = 1;
708  }
709  if (a->pos == 3 || (a->pos == 4 && atleast)) {
710  const char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], "");
711  int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21;
712 
713  if (a->n < 21 && numbermatch == 0) {
714  return complete_number(pos, 0, 0x7fffffff, a->n);
715  } else if (pos[0] == '0') {
716  if (a->n == 0) {
717  return ast_strdup("0");
718  }
719  } else if (a->n == (21 - numbermatch)) {
720  if (a->pos == 3 && !strncasecmp(argv3, "off", strlen(argv3))) {
721  return ast_strdup("off");
722  } else if (a->pos == 3 && !strncasecmp(argv3, "atleast", strlen(argv3))) {
723  return ast_strdup("atleast");
724  }
725  } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) {
726  return ast_strdup("atleast");
727  }
728  } else if ((a->pos == 4 && !atleast && strcasecmp(argv3, "off"))
729  || (a->pos == 5 && atleast)) {
730  const char *pos = S_OR(a->argv[a->pos], "");
731 
732  if (a->n == 0 && !strncasecmp(pos, "silent", strlen(pos))) {
733  return ast_strdup("silent");
734  }
735  }
736  return NULL;
737  }
738  /* all the above return, so we proceed with the handler.
739  * we are guaranteed to be called with argc >= e->args;
740  */
741 
742  if (a->argc <= e->args) {
743  return CLI_SHOWUSAGE;
744  }
745 
746  if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args], "off")) {
747  newlevel = 0;
748  } else {
749  if (!strcasecmp(a->argv[e->args], "atleast")) {
750  atleast = 1;
751  }
752  if (a->argc == e->args + atleast + 2
753  && !strcasecmp(a->argv[e->args + atleast + 1], "silent")) {
754  silent = 1;
755  }
756  if (a->argc != e->args + atleast + silent + 1) {
757  return CLI_SHOWUSAGE;
758  }
759  if (sscanf(a->argv[e->args + atleast], "%30d", &newlevel) != 1) {
760  return CLI_SHOWUSAGE;
761  }
762  }
763 
764  /* Update verbose level */
765  oldval = ast_verb_console_get();
766  if (!atleast || newlevel > oldval) {
767  ast_verb_console_set(newlevel);
768  } else {
769  newlevel = oldval;
770  }
771 
772  if (silent) {
773  /* Be silent after setting the level. */
774  return CLI_SUCCESS;
775  }
776 
777  /* Report verbose level status */
778  status_debug_verbose(a, VERBOSE_HANDLER, oldval, newlevel);
779 
780  return CLI_SUCCESS;
781 }
const int argc
Definition: cli.h:160
int ast_verb_console_get(void)
Get this thread&#39;s console verbosity level.
Definition: logger.c:2323
Definition: cli.h:152
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int args
This gets set in ast_cli_register()
Definition: cli.h:185
#define ast_strlen_zero(foo)
Definition: strings.h:52
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define VERBOSE_HANDLER
Definition: main/cli.c:405
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
void ast_verb_console_set(int verb_level)
Set this thread&#39;s console verbosity level.
Definition: logger.c:2341
const int pos
Definition: cli.h:164
static char * complete_number(const char *partial, unsigned int min, unsigned int max, int n)
Definition: main/cli.c:363
static void status_debug_verbose(struct ast_cli_args *a, int handler, int old_val, int cur_val)
Definition: main/cli.c:407

◆ help1()

static char* help1 ( int  fd,
const char *const  match[],
int  locked 
)
static

helper for final part of handle_help if locked = 1, assume the list is already locked

Definition at line 2522 of file main/cli.c.

References ast_cli_entry::_full_cmd, ast_cli(), ast_join, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, cli_next(), CLI_SUCCESS, len(), NULL, S_OR, and ast_cli_entry::summary.

Referenced by handle_help().

2523 {
2524  char matchstr[80] = "";
2525  struct ast_cli_entry *e = NULL;
2526  int len = 0;
2527  int found = 0;
2528 
2529  if (match) {
2530  ast_join(matchstr, sizeof(matchstr), match);
2531  len = strlen(matchstr);
2532  }
2533  if (!locked)
2535  while ( (e = cli_next(e)) ) {
2536  /* Hide commands that start with '_' */
2537  if (e->_full_cmd[0] == '_')
2538  continue;
2539  if (match && strncasecmp(matchstr, e->_full_cmd, len))
2540  continue;
2541  ast_cli(fd, "%-30s -- %s\n", e->_full_cmd,
2542  S_OR(e->summary, "<no description available>"));
2543  found++;
2544  }
2545  if (!locked)
2547  if (!found && matchstr[0])
2548  ast_cli(fd, "No such command '%s'.\n", matchstr);
2549  return CLI_SUCCESS;
2550 }
char * _full_cmd
Definition: cli.h:181
#define ast_join(s, len, w)
Definition: strings.h:483
descriptor for a cli entry.
Definition: cli.h:171
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2315
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define CLI_SUCCESS
Definition: cli.h:44
const char *const summary
Definition: cli.h:176
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: main/cli.c:929

◆ is_prefix()

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 2266 of file main/cli.c.

References ast_strdup, ast_strdupa, ast_strlen_zero, cli_rsvd, NULL, strsep(), and t1.

Referenced by __ast_cli_generator().

2268 {
2269  int lw;
2270  char *s, *t1;
2271 
2272  *actual = 0;
2273  if (ast_strlen_zero(token))
2274  return NULL;
2275  if (ast_strlen_zero(word))
2276  word = ""; /* dummy */
2277  lw = strlen(word);
2278  if (strcspn(word, cli_rsvd) != lw)
2279  return NULL; /* no match if word has reserved chars */
2280  if (strchr(cli_rsvd, token[0]) == NULL) { /* regular match */
2281  if (strncasecmp(token, word, lw)) /* no match */
2282  return NULL;
2283  *actual = 1;
2284  return (pos != 0) ? NULL : ast_strdup(token);
2285  }
2286  /* now handle regexp match */
2287 
2288  /* Wildcard always matches, so we never do is_prefix on them */
2289 
2290  t1 = ast_strdupa(token + 1); /* copy, skipping first char */
2291  while (pos >= 0 && (s = strsep(&t1, cli_rsvd)) && *s) {
2292  if (*s == '%') /* wildcard */
2293  continue;
2294  if (strncasecmp(s, word, lw)) /* no match */
2295  continue;
2296  (*actual)++;
2297  if (pos-- == 0)
2298  return ast_strdup(s);
2299  }
2300  return NULL;
2301 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * strsep(char **str, const char *delims)
static const char cli_rsvd[]
Definition: main/cli.c:2040
short word
static uint16_t t1
Definition: res_pktccops.c:157

◆ modlist_modentry()

static int modlist_modentry ( const char *  module,
const char *  description,
int  usecnt,
const char *  status,
const char *  like,
enum ast_module_support_level  support_level 
)
static

Definition at line 863 of file main/cli.c.

References ast_cli(), ast_module_support_level_to_string(), climodentryfd, MODLIST_FORMAT, and strcasestr().

Referenced by handle_modlist().

866 {
867  /* Comparing the like with the module */
868  if (strcasestr(module, like) ) {
871  return 1;
872  }
873  return 0;
874 }
const char * ast_module_support_level_to_string(enum ast_module_support_level support_level)
Definition: loader.c:2755
static int climodentryfd
Definition: main/cli.c:861
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static int usecnt
Definition: chan_ooh323.c:332
char * strcasestr(const char *, const char *)
#define MODLIST_FORMAT
Definition: main/cli.c:857
struct ast_module * module
Definition: cli.h:180
jack_status_t status
Definition: app_jack.c:146

◆ more_words()

static int more_words ( const char *const *  dst)
static

returns true if there are more words to match

Definition at line 2816 of file main/cli.c.

Referenced by __ast_cli_generator().

2817 {
2818  int i;
2819  for (i = 0; dst[i]; i++) {
2820  if (dst[i][0] != '[')
2821  return -1;
2822  }
2823  return 0;
2824 }

◆ parse_args()

static char* parse_args ( const char *  s,
int *  argc,
const char *  argv[],
int  max,
int *  trailingwhitespace 
)
static

Definition at line 2598 of file main/cli.c.

References ast_log, ast_strdup, dummy(), LOG_WARNING, and NULL.

Referenced by __ast_cli_generator(), and ast_cli_command_full().

2599 {
2600  char *duplicate, *cur;
2601  int x = 0;
2602  int quoted = 0;
2603  int escaped = 0;
2604  int whitespace = 1;
2605  int dummy = 0;
2606 
2607  if (trailingwhitespace == NULL)
2608  trailingwhitespace = &dummy;
2609  *trailingwhitespace = 0;
2610  if (s == NULL) /* invalid, though! */
2611  return NULL;
2612  /* make a copy to store the parsed string */
2613  if (!(duplicate = ast_strdup(s)))
2614  return NULL;
2615 
2616  cur = duplicate;
2617 
2618  /* Remove leading spaces from the command */
2619  while (isspace(*s)) {
2620  cur++;
2621  s++;
2622  }
2623 
2624  /* scan the original string copying into cur when needed */
2625  for (; *s ; s++) {
2626  if (x >= max - 1) {
2627  ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s);
2628  break;
2629  }
2630  if (*s == '"' && !escaped) {
2631  quoted = !quoted;
2632  if (quoted && whitespace) {
2633  /* start a quoted string from previous whitespace: new argument */
2634  argv[x++] = cur;
2635  whitespace = 0;
2636  }
2637  } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) {
2638  /* If we are not already in whitespace, and not in a quoted string or
2639  processing an escape sequence, and just entered whitespace, then
2640  finalize the previous argument and remember that we are in whitespace
2641  */
2642  if (!whitespace) {
2643  *cur++ = '\0';
2644  whitespace = 1;
2645  }
2646  } else if (*s == '\\' && !escaped) {
2647  escaped = 1;
2648  } else {
2649  if (whitespace) {
2650  /* we leave whitespace, and are not quoted. So it's a new argument */
2651  argv[x++] = cur;
2652  whitespace = 0;
2653  }
2654  *cur++ = *s;
2655  escaped = 0;
2656  }
2657  }
2658  /* Null terminate */
2659  *cur++ = '\0';
2660  /* XXX put a NULL in the last argument, because some functions that take
2661  * the array may want a null-terminated array.
2662  * argc still reflects the number of non-NULL entries.
2663  */
2664  argv[x] = NULL;
2665  *argc = x;
2666  *trailingwhitespace = whitespace;
2667  return duplicate;
2668 }
#define LOG_WARNING
Definition: logger.h:274
static void dummy(char *unused,...)
Definition: chan_unistim.c:220
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define max(a, b)
Definition: f2c.h:198

◆ print_uptimestr()

static void print_uptimestr ( int  fd,
struct timeval  timeval,
const char *  prefix,
int  printsec 
)
static

Definition at line 876 of file main/cli.c.

References ast_cli(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_strlen(), DAY, ESS, HOUR, MINUTE, NEEDCOMMA, out, WEEK, and YEAR.

Referenced by ast_cli_print_timestr_fromseconds(), handle_showcalls(), and handle_showuptime().

877 {
878  int x; /* the main part - years, weeks, etc. */
879  struct ast_str *out;
880 
881 #define SECOND (1)
882 #define MINUTE (SECOND*60)
883 #define HOUR (MINUTE*60)
884 #define DAY (HOUR*24)
885 #define WEEK (DAY*7)
886 #define YEAR (DAY*365)
887 #define NEEDCOMMA(x) ((x) ? ", " : "") /* define if we need a comma */
888  if (timeval.tv_sec < 0) /* invalid, nothing to show */
889  return;
890 
891  if (printsec) { /* plain seconds output */
892  ast_cli(fd, "%s%lu\n", prefix, (u_long)timeval.tv_sec);
893  return;
894  }
895  out = ast_str_alloca(256);
896  if (timeval.tv_sec > YEAR) {
897  x = (timeval.tv_sec / YEAR);
898  timeval.tv_sec -= (x * YEAR);
899  ast_str_append(&out, 0, "%d year%s%s", x, ESS(x), NEEDCOMMA(timeval.tv_sec));
900  }
901  if (timeval.tv_sec > WEEK) {
902  x = (timeval.tv_sec / WEEK);
903  timeval.tv_sec -= (x * WEEK);
904  ast_str_append(&out, 0, "%d week%s%s", x, ESS(x), NEEDCOMMA(timeval.tv_sec));
905  }
906  if (timeval.tv_sec > DAY) {
907  x = (timeval.tv_sec / DAY);
908  timeval.tv_sec -= (x * DAY);
909  ast_str_append(&out, 0, "%d day%s%s", x, ESS(x), NEEDCOMMA(timeval.tv_sec));
910  }
911  if (timeval.tv_sec > HOUR) {
912  x = (timeval.tv_sec / HOUR);
913  timeval.tv_sec -= (x * HOUR);
914  ast_str_append(&out, 0, "%d hour%s%s", x, ESS(x), NEEDCOMMA(timeval.tv_sec));
915  }
916  if (timeval.tv_sec > MINUTE) {
917  x = (timeval.tv_sec / MINUTE);
918  timeval.tv_sec -= (x * MINUTE);
919  ast_str_append(&out, 0, "%d minute%s%s", x, ESS(x), NEEDCOMMA(timeval.tv_sec));
920  }
921  x = timeval.tv_sec;
922  if (x > 0 || ast_str_strlen(out) == 0) {
923  /* if there is nothing, print 0 seconds */
924  ast_str_append(&out, 0, "%d second%s", x, ESS(x));
925  }
926  ast_cli(fd, "%s%s\n", prefix, ast_str_buffer(out));
927 }
#define DAY
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_str_alloca(init_len)
Definition: strings.h:800
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define YEAR
#define NEEDCOMMA(x)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ESS(x)
Definition: cli.h:59
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
FILE * out
Definition: utils/frame.c:33
#define HOUR
#define WEEK
#define MINUTE
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ remove_shutdown_command()

static void remove_shutdown_command ( struct ast_cli_entry e)
static

Definition at line 2390 of file main/cli.c.

References ast_rwlock_unlock, ast_rwlock_wrlock, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_REMOVE_ELEM_UNORDERED, and shutdown_commands_lock.

Referenced by ast_cli_unregister().

2391 {
2395 }
#define AST_VECTOR_REMOVE_ELEM_UNORDERED(vec, elem, cleanup)
Remove an element from a vector.
Definition: vector.h:585
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:573
static ast_rwlock_t shutdown_commands_lock
Definition: main/cli.c:112
#define ast_rwlock_wrlock(a)
Definition: lock.h:234

◆ set_full_cmd()

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 2046 of file main/cli.c.

References ast_cli_entry::_full_cmd, ast_cli_entry::args, ast_join, ast_log, ast_strdup, buf, cli_rsvd, ast_cli_entry::cmda, ast_cli_entry::cmdlen, and LOG_WARNING.

Referenced by __ast_cli_register().

2047 {
2048  int i;
2049  char buf[80];
2050 
2051  ast_join(buf, sizeof(buf), e->cmda);
2052  e->_full_cmd = ast_strdup(buf);
2053  if (!e->_full_cmd) {
2054  ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf);
2055  return -1;
2056  }
2057  e->cmdlen = strcspn(e->_full_cmd, cli_rsvd);
2058  for (i = 0; e->cmda[i]; i++)
2059  ;
2060  e->args = i;
2061  return 0;
2062 }
char * _full_cmd
Definition: cli.h:181
int cmdlen
Definition: cli.h:182
#define ast_join(s, len, w)
Definition: strings.h:483
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
int args
This gets set in ast_cli_register()
Definition: cli.h:185
#define ast_log
Definition: astobj2.c:42
static const char cli_rsvd[]
Definition: main/cli.c:2040
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:172

◆ status_debug_verbose()

static void status_debug_verbose ( struct ast_cli_args a,
int  handler,
int  old_val,
int  cur_val 
)
static

Definition at line 407 of file main/cli.c.

References ast_cli(), DEBUG_HANDLER, ast_cli_args::fd, TRACE_HANDLER, and VERBOSE_HANDLER.

Referenced by handle_debug_or_trace(), and handle_verbose().

408 {
409  char was_buf[30];
410  const char *was;
411  const char *what = "";
412 
413  switch(handler) {
414  case DEBUG_HANDLER:
415  what = "Core debug";
416  break;
417  case TRACE_HANDLER:
418  what = "Core trace";
419  break;
420  case VERBOSE_HANDLER:
421  what = "Console verbose";
422  break;
423  }
424 
425  if (old_val) {
426  snprintf(was_buf, sizeof(was_buf), "%d", old_val);
427  was = was_buf;
428  } else {
429  was = "OFF";
430  }
431 
432  if (old_val == cur_val) {
433  ast_cli(a->fd, "%s is still %s.\n", what, was);
434  } else {
435  char now_buf[30];
436  const char *now;
437 
438  if (cur_val) {
439  snprintf(now_buf, sizeof(now_buf), "%d", cur_val);
440  now = now_buf;
441  } else {
442  now = "OFF";
443  }
444 
445  ast_cli(a->fd, "%s was %s and is now %s.\n", what, was, now);
446  }
447 }
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define TRACE_HANDLER
Definition: main/cli.c:404
#define DEBUG_HANDLER
Definition: main/cli.c:403
const int fd
Definition: cli.h:159
#define VERBOSE_HANDLER
Definition: main/cli.c:405
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59

◆ word_match()

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 2227 of file main/cli.c.

References ast_strlen_zero, cli_rsvd, and strcasestr().

Referenced by __ast_cli_generator(), and find_cli().

2228 {
2229  int l;
2230  char *pos;
2231 
2232  if (ast_strlen_zero(cmd) || ast_strlen_zero(cli_word))
2233  return -1;
2234  if (!strchr(cli_rsvd, cli_word[0])) /* normal match */
2235  return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1;
2236  l = strlen(cmd);
2237  /* wildcard match - will extend in the future */
2238  if (l > 0 && cli_word[0] == '%') {
2239  return 1; /* wildcard */
2240  }
2241 
2242  /* Start a search for the command entered against the cli word in question */
2243  pos = strcasestr(cli_word, cmd);
2244  while (pos) {
2245 
2246  /*
2247  *Check if the word matched with is surrounded by reserved characters on both sides
2248  * and isn't at the beginning of the cli_word since that would make it check in a location we shouldn't know about.
2249  * If it is surrounded by reserved chars and isn't at the beginning, it's a match.
2250  */
2251  if (pos != cli_word && strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) {
2252  return 1; /* valid match */
2253  }
2254 
2255  /* Ok, that one didn't match, strcasestr to the next appearance of the command and start over.*/
2256  pos = strcasestr(pos + 1, cmd);
2257  }
2258  /* If no matches were found over the course of the while loop, we hit the end of the string. It's a mismatch. */
2259  return -1;
2260 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
char * strcasestr(const char *, const char *)
static const char cli_rsvd[]
Definition: main/cli.c:2040

Variable Documentation

◆ ast_cli_buf

struct ast_threadstorage ast_cli_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ast_cli_buf , .custom_init = NULL , }
static

Definition at line 110 of file main/cli.c.

Referenced by AST_VECTOR().

◆ cli_cli

struct ast_cli_entry cli_cli[]
static

Definition at line 1984 of file main/cli.c.

◆ cli_default_perm

int cli_default_perm = 1
static

Default permissions value 1=Permit 0=Deny.

Definition at line 87 of file main/cli.c.

Referenced by ast_cli_perms_init(), and cli_has_permissions().

◆ cli_perms

struct cli_perms cli_perms = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ cli_rsvd

const char cli_rsvd[] = "[]{}|*%"
static

Some regexp characters in cli arguments are reserved and used as separators.

Definition at line 2040 of file main/cli.c.

Referenced by is_prefix(), set_full_cmd(), and word_match().

◆ climodentryfd

int climodentryfd = -1
static

Definition at line 861 of file main/cli.c.

Referenced by handle_modlist(), and modlist_modentry().

◆ climodentrylock

ast_mutex_t climodentrylock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 860 of file main/cli.c.

Referenced by handle_modlist().

◆ debug_modules

struct module_level_list debug_modules = AST_RWLIST_HEAD_INIT_VALUE
static

lists of module names and their debug/trace levels

Definition at line 107 of file main/cli.c.

Referenced by handle_debug_or_trace().

◆ helpers

struct helpers helpers = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ perms_config

const char perms_config[] = "cli_permissions.conf"
static

CLI permissions config file.

Definition at line 85 of file main/cli.c.

Referenced by ast_cli_perms_init().

◆ permsconfiglock

ast_mutex_t permsconfiglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

mutex used to prevent a user from running the 'cli reload permissions' command while it is already running.

Definition at line 91 of file main/cli.c.

Referenced by ast_cli_perms_init().

◆ shutdown_commands_lock

ast_rwlock_t shutdown_commands_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
static

◆ trace_modules

struct module_level_list trace_modules = AST_RWLIST_HEAD_INIT_VALUE
static

Definition at line 108 of file main/cli.c.

Referenced by handle_debug_or_trace().