Asterisk - The Open Source Telephony Project  21.4.1
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"

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
 Initial buffer size for resulting strings in ast_cli()
 
#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
 
#define DAY   (HOUR*24)
 
#define DEBUG_HANDLER   0
 
#define FORMAT_STRING   "%-64.64s %-32.32s %-7.7s %-30.30s\n"
 
#define FORMAT_STRING   "%-25s %-20s %-20s\n"
 
#define FORMAT_STRING2   "%-64.64s %-32.32s %-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   "%-80.80s %-24.24s %-24.24s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
 
#define VERBOSE_FORMAT_STRING2   "%-80.80s %-24.24s %-24.24s %-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...
 
void ast_cli (int fd, const char *fmt,...)
 
int ast_cli_allow_at_shutdown (struct ast_cli_entry *e)
 Allow a CLI command to be executed while Asterisk is shutting down. More...
 
void ast_cli_channels_init (void)
 
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_stringast_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 int channel_set_debug (void *obj, void *arg, void *data, int flags)
 
static void cli_channels_shutdown (void)
 
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.
 
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'
 
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'
 
static char * handle_cli_show_permissions (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 handles CLI command 'cli show permissions'
 
static char * handle_cli_wait_fullybooted (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_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_refresh (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
 
static char * is_prefix (const char *word, const char *token, int pos, int *actual)
 if word is a valid prefix for token, returns the pos-th match as a malloced string, or NULL otherwise. Always tell in *actual how many matches we got.
 
static int modlist_modentry (const char *module, const char *description, int usecnt, const char *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
 
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_channels_cli []
 
static struct ast_cli_entry cli_cli []
 
static int cli_default_perm = 1
 Default permissions value 1=Permit 0=Deny.
 
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.
 
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.
 
struct {
   size_t   current
 
   struct ast_cli_entry **   elems
 
   size_t   max
 
shutdown_commands
 
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.

Function Documentation

void ast_builtins_init ( void  )

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

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

References ast_cli_register_multiple, ast_register_cleanup(), and AST_VECTOR_INIT.

2239 {
2240  AST_VECTOR_INIT(&shutdown_commands, 0);
2241  ast_cli_register_multiple(cli_cli, ARRAY_LEN(cli_cli));
2242  ast_register_cleanup(cli_shutdown);
2243 }
#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
int ast_cli_allow_at_shutdown ( struct ast_cli_entry e)

Allow a CLI command to be executed while Asterisk is shutting down.

CLI commands by defeault are disabled when Asterisk is shutting down. This is to ensure the safety of the shutdown since CLI commands may attempt to access resources that have been freed as a result of the shutdown.

If a CLI command should be allowed at shutdown, then the best way to enable this is to call ast_cli_allow_at_shutdown during the CLI_INIT state of the CLI handler.

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

References AST_VECTOR_APPEND.

3062 {
3063  int res;
3064 
3065  ast_rwlock_wrlock(&shutdown_commands_lock);
3066  res = AST_VECTOR_APPEND(&shutdown_commands, e);
3067  ast_rwlock_unlock(&shutdown_commands_lock);
3068 
3069  return res;
3070 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
void ast_cli_channels_init ( void  )

Provided by cli.c

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

References ast_cli_register_multiple, and ast_register_cleanup().

2246 {
2247  ast_cli_register_multiple(cli_channels_cli, ARRAY_LEN(cli_channels_cli));
2248  ast_register_cleanup(cli_channels_shutdown);
2249 }
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
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 2974 of file main/cli.c.

References ast_atomic_fetchadd_int(), ast_join, ast_module_running_ref, ast_module_unref, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_shutting_down(), find_best(), ast_cli_entry::inuse, ast_cli_entry::module, S_OR, and ast_cli_entry::usage.

Referenced by ast_cli_command_multiple_full().

2975 {
2976  const char *args[AST_MAX_ARGS + 1];
2977  struct ast_cli_entry *e = NULL;
2978  int x;
2979  char *duplicate = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL);
2980  char tmp[AST_MAX_ARGS + 1];
2981  char *retval = CLI_FAILURE;
2982  struct ast_cli_args a = {
2983  .fd = fd, .argc = x, .argv = args+1 };
2984 
2985  if (duplicate == NULL)
2986  return RESULT_FAILURE;
2987 
2988  if (x < 1) /* We need at least one entry, otherwise ignore */
2989  goto done;
2990 
2992  e = find_cli(args + 1, 0);
2993  if (e)
2996  if (e == NULL) {
2997  ast_cli(fd, "No such command '%s' (type 'core show help %s' for other possible commands)\n", s, find_best(args + 1));
2998  goto done;
2999  }
3000 
3001  if (ast_shutting_down() && !allowed_on_shutdown(e)) {
3002  ast_cli(fd, "Command '%s' cannot be run during shutdown\n", s);
3003  goto done;
3004  }
3005 
3006  ast_join(tmp, sizeof(tmp), args + 1);
3007  /* Check if the user has rights to run this command. */
3008  if (!cli_has_permissions(uid, gid, tmp)) {
3009  ast_cli(fd, "You don't have permissions to run '%s' command\n", tmp);
3010  goto done;
3011  }
3012 
3013  /*
3014  * Within the handler, argv[-1] contains a pointer to the ast_cli_entry.
3015  * Remember that the array returned by parse_args is NULL-terminated.
3016  */
3017  args[0] = (char *)e;
3018 
3019  /* If the command is in a module it must be running. */
3020  if (!e->module || ast_module_running_ref(e->module)) {
3021  retval = e->handler(e, CLI_HANDLER, &a);
3023  }
3024 
3025  if (retval == CLI_SHOWUSAGE) {
3026  ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
3027  } else if (retval == CLI_FAILURE) {
3028  ast_cli(fd, "Command '%s' failed.\n", s);
3029  }
3030 
3031 done:
3032  if (e) {
3033  ast_atomic_fetchadd_int(&e->inuse, -1);
3034  }
3035  ast_free(duplicate);
3036  return retval == CLI_SUCCESS ? RESULT_SUCCESS : RESULT_FAILURE;
3037 }
int ast_shutting_down(void)
Definition: asterisk.c:1876
#define ast_join(s, len, w)
Join an array of strings into a single string.
Definition: strings.h:520
descriptor for a cli entry.
Definition: cli.h:171
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
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:757
int inuse
Definition: cli.h:179
static struct callattempt * find_best(struct callattempt *outgoing)
find the entry with the best metric, or NULL
Definition: app_queue.c:4885
const char * usage
Definition: cli.h:177
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:469
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
struct ast_module * module
Definition: cli.h:180
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
Returns
number of commands executed

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

References ast_cli_command_full().

3040 {
3041  char cmd[512];
3042  int x, y = 0, count = 0;
3043 
3044  for (x = 0; x < size; x++) {
3045  cmd[y] = s[x];
3046  y++;
3047  if (s[x] == '\0') {
3048  ast_cli_command_full(uid, gid, fd, cmd);
3049  y = 0;
3050  count++;
3051  }
3052  }
3053  return count;
3054 }
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:2974
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):

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

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

References ast_cli_completion_add(), and ast_strdup.

Referenced by handle_orig().

1847 {
1848  int i, which = 0, len;
1849  len = ast_strlen_zero(word) ? 0 : strlen(word);
1850 
1851  for (i = 0; choices[i]; i++) {
1852  if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state) {
1853  if (state != -1) {
1854  return ast_strdup(choices[i]);
1855  }
1856 
1857  if (ast_cli_completion_add(ast_strdup(choices[i]))) {
1858  return NULL;
1859  }
1860  }
1861  }
1862  return NULL;
1863 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2761
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 2761 of file main/cli.c.

References ast_threadstorage_get_ptr().

Referenced by ast_cli_complete(), ast_complete_applications(), ast_complete_channels(), cli_complete_show(), handle_cli_sound_show(), and handle_show_named_acl_cmd().

2762 {
2763  return cli_completion_vector_add(ast_threadstorage_get_ptr(&completion_storage), value);
2764 }
void * ast_threadstorage_get_ptr(struct ast_threadstorage *ts)
Retrieve a raw pointer from threadstorage.
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 2705 of file main/cli.c.

References ast_cli_completion_vector(), AST_VECTOR_APPEND, AST_VECTOR_CALLBACK_VOID, AST_VECTOR_PTR_FREE, and AST_VECTOR_STEAL_ELEMENTS.

2706 {
2707  struct ast_vector_string *vec = ast_cli_completion_vector(text, word);
2708  char **match_list;
2709 
2710  if (!vec) {
2711  return NULL;
2712  }
2713 
2714  if (AST_VECTOR_APPEND(vec, NULL)) {
2715  /* We failed to NULL terminate the elements */
2716  AST_VECTOR_CALLBACK_VOID(vec, ast_free);
2717  AST_VECTOR_PTR_FREE(vec);
2718 
2719  return NULL;
2720  }
2721 
2722  match_list = AST_VECTOR_STEAL_ELEMENTS(vec);
2723  AST_VECTOR_PTR_FREE(vec);
2724 
2725  return match_list;
2726 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#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:2766
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
Definition: vector.h:189
String vector definitions.
Definition: vector.h:55
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:862
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 2766 of file main/cli.c.

References ast_calloc, ast_cli_generator(), 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, and AST_VECTOR_SIZE.

Referenced by ast_cli_completion_matches().

2767 {
2768  char *retstr, *prevstr;
2769  size_t max_equal;
2770  size_t which = 0;
2771  struct ast_vector_string *vec = ast_calloc(1, sizeof(*vec));
2772 
2773  /* Recursion into this function is a coding error. */
2774  ast_assert(!ast_threadstorage_get_ptr(&completion_storage));
2775 
2776  if (!vec) {
2777  return NULL;
2778  }
2779 
2780  if (ast_threadstorage_set_ptr(&completion_storage, vec)) {
2781  ast_log(LOG_ERROR, "Failed to initialize threadstorage for completion.\n");
2782  ast_free(vec);
2783 
2784  return NULL;
2785  }
2786 
2787  while ((retstr = ast_cli_generator(text, word, which)) != NULL) {
2788  if (cli_completion_vector_add(vec, retstr)) {
2789  ast_threadstorage_set_ptr(&completion_storage, NULL);
2790 
2791  goto vector_cleanup;
2792  }
2793 
2794  ++which;
2795  }
2796 
2797  ast_threadstorage_set_ptr(&completion_storage, NULL);
2798 
2799  if (!AST_VECTOR_SIZE(vec)) {
2800  AST_VECTOR_PTR_FREE(vec);
2801 
2802  return NULL;
2803  }
2804 
2805  prevstr = AST_VECTOR_GET(vec, 0);
2806  max_equal = strlen(prevstr);
2807  which = 1;
2808 
2809  /* Find the longest substring that is common to all results
2810  * (it is a candidate for completion), and store a copy in entry 0.
2811  */
2812  while (which < AST_VECTOR_SIZE(vec)) {
2813  size_t i = 0;
2814 
2815  retstr = AST_VECTOR_GET(vec, which);
2816  /* Check for and remove duplicate strings. */
2817  if (!strcasecmp(prevstr, retstr)) {
2818  AST_VECTOR_REMOVE(vec, which, 1);
2819  ast_free(retstr);
2820 
2821  continue;
2822  }
2823 
2824  while (i < max_equal && toupper(prevstr[i]) == toupper(retstr[i])) {
2825  i++;
2826  }
2827 
2828  max_equal = i;
2829  prevstr = retstr;
2830  ++which;
2831  }
2832 
2833  /* Insert longest match to position 0. */
2834  retstr = ast_strndup(AST_VECTOR_GET(vec, 0), max_equal);
2835  if (!retstr || AST_VECTOR_INSERT_AT(vec, 0, retstr)) {
2836  ast_free(retstr);
2837 
2838  goto vector_cleanup;
2839  }
2840 
2841  return vec;
2842 
2843 vector_cleanup:
2844  AST_VECTOR_CALLBACK_VOID(vec, ast_free);
2845  AST_VECTOR_PTR_FREE(vec);
2846 
2847  return NULL;
2848 }
char * ast_cli_generator(const char *text, const char *word, int state)
Readline madness Useful for readline, that's about it.
Definition: main/cli.c:2952
int ast_threadstorage_set_ptr(struct ast_threadstorage *ts, void *ptr)
Set a raw pointer from threadstorage.
#define ast_strndup(str, len)
A wrapper for strndup()
Definition: astmm.h:256
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
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:680
#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
String vector definitions.
Definition: vector.h:55
#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:609
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:862
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 2952 of file main/cli.c.

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

2953 {
2954  return __ast_cli_generator(text, word, state, 1);
2955 }
int ast_cli_perms_init ( int  reload)

Provided by cli.c

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

References ast_calloc, ast_category_browse(), ast_config_destroy(), ast_config_load2(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, cli_default_perm, cli_perm::command, CONFIG_FLAG_FILEUNCHANGED, destroy_user_perms(), usergroup_cli_perm::gid, ast_variable::name, ast_variable::next, cli_perm::permit, usergroup_cli_perm::perms, perms_config, permsconfiglock, usergroup_cli_perm::uid, and ast_variable::value.

Referenced by handle_cli_reload_permissions().

2106 {
2107  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2108  struct ast_config *cfg;
2109  char *cat = NULL;
2110  struct ast_variable *v;
2111  struct usergroup_cli_perm *user_group, *cp_entry;
2112  struct cli_perm *perm = NULL;
2113  struct passwd *pw;
2114  struct group *gr;
2115 
2116  if (ast_mutex_trylock(&permsconfiglock)) {
2117  ast_log(LOG_NOTICE, "You must wait until last 'cli reload permissions' command finish\n");
2118  return 1;
2119  }
2120 
2121  cfg = ast_config_load2(perms_config, "" /* core, can't reload */, config_flags);
2122  if (!cfg) {
2123  ast_mutex_unlock(&permsconfiglock);
2124  return 1;
2125  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
2126  ast_mutex_unlock(&permsconfiglock);
2127  return 0;
2128  }
2129 
2130  /* free current structures. */
2132 
2133  while ((cat = ast_category_browse(cfg, cat))) {
2134  if (!strcasecmp(cat, "general")) {
2135  /* General options */
2136  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
2137  if (!strcasecmp(v->name, "default_perm")) {
2138  cli_default_perm = (!strcasecmp(v->value, "permit")) ? 1: 0;
2139  }
2140  }
2141  continue;
2142  }
2143 
2144  /* users or groups */
2145  gr = NULL, pw = NULL;
2146  if (cat[0] == '@') {
2147  /* This is a group */
2148  gr = getgrnam(&cat[1]);
2149  if (!gr) {
2150  ast_log (LOG_WARNING, "Unknown group '%s'\n", &cat[1]);
2151  continue;
2152  }
2153  } else {
2154  /* This is a user */
2155  pw = getpwnam(cat);
2156  if (!pw) {
2157  ast_log (LOG_WARNING, "Unknown user '%s'\n", cat);
2158  continue;
2159  }
2160  }
2161  user_group = NULL;
2162  /* Check for duplicates */
2164  AST_LIST_TRAVERSE(&cli_perms, cp_entry, list) {
2165  if ((pw && cp_entry->uid == pw->pw_uid) || (gr && cp_entry->gid == gr->gr_gid)) {
2166  /* if it is duplicated, just added this new settings, to
2167  the current list. */
2168  user_group = cp_entry;
2169  break;
2170  }
2171  }
2173 
2174  if (!user_group) {
2175  /* alloc space for the new user config. */
2176  user_group = ast_calloc(1, sizeof(*user_group));
2177  if (!user_group) {
2178  continue;
2179  }
2180  user_group->uid = (pw ? pw->pw_uid : -1);
2181  user_group->gid = (gr ? gr->gr_gid : -1);
2182  user_group->perms = ast_calloc(1, sizeof(*user_group->perms));
2183  if (!user_group->perms) {
2184  ast_free(user_group);
2185  continue;
2186  }
2187  }
2188  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
2189  if (ast_strlen_zero(v->value)) {
2190  /* we need to check this condition cause it could break security. */
2191  ast_log(LOG_WARNING, "Empty permit/deny option in user '%s'\n", cat);
2192  continue;
2193  }
2194  if (!strcasecmp(v->name, "permit")) {
2195  perm = ast_calloc(1, sizeof(*perm));
2196  if (perm) {
2197  perm->permit = 1;
2198  perm->command = ast_strdup(v->value);
2199  }
2200  } else if (!strcasecmp(v->name, "deny")) {
2201  perm = ast_calloc(1, sizeof(*perm));
2202  if (perm) {
2203  perm->permit = 0;
2204  perm->command = ast_strdup(v->value);
2205  }
2206  } else {
2207  /* up to now, only 'permit' and 'deny' are possible values. */
2208  ast_log(LOG_WARNING, "Unknown '%s' option\n", v->name);
2209  continue;
2210  }
2211  if (perm) {
2212  /* Added the permission to the user's list. */
2213  AST_LIST_INSERT_TAIL(user_group->perms, perm, list);
2214  perm = NULL;
2215  }
2216  }
2218  AST_RWLIST_INSERT_TAIL(&cli_perms, user_group, list);
2220  }
2221 
2222  ast_config_destroy(cfg);
2223  ast_mutex_unlock(&permsconfiglock);
2224  return 0;
2225 }
struct ast_variable * next
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:3321
static ast_mutex_t permsconfiglock
mutex used to prevent a user from running the 'cli reload permissions' command while it is already ru...
Definition: main/cli.c:91
Structure for variables, used for configurations and for channel variables.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
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:241
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
static int cli_default_perm
Default permissions value 1=Permit 0=Deny.
Definition: main/cli.c:87
struct cli_perm_head * perms
Definition: main/cli.c:81
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:731
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:491
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
Structure used to handle boolean flags.
Definition: utils.h:199
List of users and permissions.
Definition: main/cli.c:93
char * command
Definition: main/cli.c:71
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
unsigned int permit
Definition: main/cli.c:70
static void destroy_user_perms(void)
cleanup (free) cli_perms linkedlist.
Definition: main/cli.c:2089
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
fdfd to print by ast_cli
secondsThe time (in seconds) to print
prefixA Prefix string to add before of duration formatted

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

References ast_tv().

Referenced by handle_cdr_pgsql_status(), and realtime_ldap_status().

3057 {
3058  print_uptimestr(fd, ast_tv(seconds, 0), prefix, 0);
3059 }
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235
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 2432 of file main/cli.c.

References ast_cli_entry::_full_cmd, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::inuse, and ast_cli_entry::usage.

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

2433 {
2434  if (e->inuse) {
2435  ast_log(LOG_WARNING, "Can't remove command that is in use\n");
2436  } else {
2438  AST_RWLIST_REMOVE(&helpers, e, list);
2440  remove_shutdown_command(e);
2441  ast_free(e->_full_cmd);
2442  e->_full_cmd = NULL;
2443  if (e->handler) {
2444  /* this is a new-style entry. Reset fields and free memory. */
2445  char *cmda = (char *) e->cmda;
2446  memset(cmda, '\0', sizeof(e->cmda));
2447  ast_free(e->command);
2448  e->command = NULL;
2449  e->usage = NULL;
2450  }
2451  }
2452  return 0;
2453 }
char * _full_cmd
Definition: cli.h:181
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
int inuse
Definition: cli.h:179
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:172
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 2543 of file main/cli.c.

References ast_cli_unregister().

2544 {
2545  int i, res = 0;
2546 
2547  for (i = 0; i < len; i++)
2548  res |= ast_cli_unregister(e + i);
2549 
2550  return res;
2551 }
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: main/cli.c:2432
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 1865 of file main/cli.c.

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

Referenced by handle_cli_agi_add_cmd(), handle_redirect(), handle_show_chanvar(), handle_show_hangup_channel(), and handle_showchan().

1866 {
1867  int wordlen = strlen(word), which = 0;
1868  struct ao2_container *cached_channels;
1869  char *ret = NULL;
1870  struct ao2_iterator iter;
1871  struct ast_channel_snapshot *snapshot;
1872 
1873  if (pos != rpos) {
1874  return NULL;
1875  }
1876 
1877  cached_channels = ast_channel_cache_all();
1878 
1879  iter = ao2_iterator_init(cached_channels, 0);
1880  for (; (snapshot = ao2_iterator_next(&iter)); ao2_ref(snapshot, -1)) {
1881  if (!strncasecmp(word, snapshot->base->name, wordlen) && (++which > state)) {
1882  if (state != -1) {
1883  ret = ast_strdup(snapshot->base->name);
1884  ao2_ref(snapshot, -1);
1885  break;
1886  }
1887 
1888  if (ast_cli_completion_add(ast_strdup(snapshot->base->name))) {
1889  ao2_ref(snapshot, -1);
1890  break;
1891  }
1892  }
1893  }
1894  ao2_iterator_destroy(&iter);
1895  ao2_ref(cached_channels, -1);
1896 
1897  return ret;
1898 }
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:241
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
enum ast_channel_state state
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
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
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2761
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, and AST_RWLIST_UNLOCK.

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
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
map a debug or verbose level to a module name
Definition: main/cli.c:98
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
Definition: search.h:40
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
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.

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 AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
Definition: search.h:40
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 1645 of file main/cli.c.

References ast_callid_strnprint(), ast_cdr_serialize_variables(), AST_CHAN_TP_INTERNAL, ast_channel_get_bridge(), ast_channel_get_by_name(), ast_channel_get_stream_topology(), ast_channel_unref, ast_codec_media_type2str(), ast_complete_channels(), ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_format_get_name(), AST_LIST_TRAVERSE, ast_state2str(), 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_variables_destroy(), ast_bridge::callid, ast_cli_entry::command, ast_variable::name, ast_bridge::name, ast_variable::next, S_COR, S_OR, ast_bridge::uniqueid, ast_cli_entry::usage, and ast_variable::value.

1646 {
1647  struct ast_channel *chan;
1648  struct timeval now;
1649  char cdrtime[256];
1650  struct ast_str *obuf;/*!< Buffer for CDR variables. */
1651  struct ast_str *output;/*!< Accumulation buffer for all output. */
1652  long elapsed_seconds=0;
1653  int hour=0, min=0, sec=0;
1654  struct ast_var_t *var;
1655  struct ast_str *write_transpath = ast_str_alloca(256);
1656  struct ast_str *read_transpath = ast_str_alloca(256);
1657  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1658  struct ast_bridge *bridge;
1659  ast_callid callid;
1660  char callid_buf[32];
1661  int stream_num;
1662 
1663  switch (cmd) {
1664  case CLI_INIT:
1665  e->command = "core show channel";
1666  e->usage =
1667  "Usage: core show channel <channel>\n"
1668  " Shows lots of information about the specified channel.\n";
1669  return NULL;
1670  case CLI_GENERATE:
1671  return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
1672  }
1673 
1674  if (a->argc != 4) {
1675  return CLI_SHOWUSAGE;
1676  }
1677 
1678  obuf = ast_str_thread_get(&ast_str_thread_global_buf, 16);
1679  if (!obuf) {
1680  return CLI_FAILURE;
1681  }
1682 
1683  chan = ast_channel_get_by_name(a->argv[3]);
1684  if (!chan) {
1685  ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
1686 
1687  return CLI_SUCCESS;
1688  }
1689 
1690  output = ast_str_create(8192);
1691  if (!output) {
1692  ast_channel_unref(chan);
1693 
1694  return CLI_FAILURE;
1695  }
1696 
1697  now = ast_tvnow();
1698  ast_channel_lock(chan);
1699 
1700  if (!ast_tvzero(ast_channel_creationtime(chan))) {
1701  elapsed_seconds = now.tv_sec - ast_channel_creationtime(chan).tv_sec;
1702  hour = elapsed_seconds / 3600;
1703  min = (elapsed_seconds % 3600) / 60;
1704  sec = elapsed_seconds % 60;
1705  snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
1706  } else {
1707  strcpy(cdrtime, "N/A");
1708  }
1709 
1710  ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath);
1711  ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath);
1712 
1713  bridge = ast_channel_get_bridge(chan);
1714  callid_buf[0] = '\0';
1715  callid = ast_channel_callid(chan);
1716  if (callid) {
1717  ast_callid_strnprint(callid_buf, sizeof(callid_buf), callid);
1718  }
1719 
1720  ast_str_append(&output, 0,
1721  " -- General --\n"
1722  " Name: %s\n"
1723  " Type: %s\n"
1724  " UniqueID: %s\n"
1725  " LinkedID: %s\n"
1726  " Caller ID: %s\n"
1727  " Caller ID Name: %s\n"
1728  "Connected Line ID: %s\n"
1729  "Connected Line ID Name: %s\n"
1730  "Eff. Connected Line ID: %s\n"
1731  "Eff. Connected Line ID Name: %s\n"
1732  " DNID Digits: %s\n"
1733  " Language: %s\n"
1734  " State: %s (%u)\n"
1735  " NativeFormats: %s\n"
1736  " WriteFormat: %s\n"
1737  " ReadFormat: %s\n"
1738  " WriteTranscode: %s %s\n"
1739  " ReadTranscode: %s %s\n"
1740  " Time to Hangup: %ld\n"
1741  " Elapsed Time: %s\n"
1742  " Bridge ID: %s\n"
1743  " -- PBX --\n"
1744  " Context: %s\n"
1745  " Extension: %s\n"
1746  " Priority: %d\n"
1747  " Call Group: %llu\n"
1748  " Pickup Group: %llu\n"
1749  " Application: %s\n"
1750  " Data: %s\n"
1751  " Call Identifer: %s\n",
1752  ast_channel_name(chan),
1753  ast_channel_tech(chan)->type,
1754  ast_channel_uniqueid(chan),
1755  ast_channel_linkedid(chan),
1756  S_COR(ast_channel_caller(chan)->id.number.valid,
1757  ast_channel_caller(chan)->id.number.str, "(N/A)"),
1758  S_COR(ast_channel_caller(chan)->id.name.valid,
1759  ast_channel_caller(chan)->id.name.str, "(N/A)"),
1760  S_COR(ast_channel_connected(chan)->id.number.valid,
1761  ast_channel_connected(chan)->id.number.str, "(N/A)"),
1762  S_COR(ast_channel_connected(chan)->id.name.valid,
1763  ast_channel_connected(chan)->id.name.str, "(N/A)"),
1764  S_COR(ast_channel_connected_effective_id(chan).number.valid,
1765  ast_channel_connected_effective_id(chan).number.str, "(N/A)"),
1766  S_COR(ast_channel_connected_effective_id(chan).name.valid,
1767  ast_channel_connected_effective_id(chan).name.str, "(N/A)"),
1768  S_OR(ast_channel_dialed(chan)->number.str, "(N/A)"),
1769  ast_channel_language(chan),
1771  ast_channel_state(chan),
1772  ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf),
1773  ast_format_get_name(ast_channel_writeformat(chan)),
1774  ast_format_get_name(ast_channel_readformat(chan)),
1775  ast_str_strlen(write_transpath) ? "Yes" : "No",
1776  ast_str_buffer(write_transpath),
1777  ast_str_strlen(read_transpath) ? "Yes" : "No",
1778  ast_str_buffer(read_transpath),
1779  (long)ast_channel_whentohangup(chan)->tv_sec,
1780  cdrtime,
1781  bridge ? bridge->uniqueid : "(Not bridged)",
1782  ast_channel_context(chan),
1783  ast_channel_exten(chan),
1784  ast_channel_priority(chan),
1785  ast_channel_callgroup(chan),
1786  ast_channel_pickupgroup(chan),
1787  S_OR(ast_channel_appl(chan), "(N/A)"),
1788  S_OR(ast_channel_data(chan), "(Empty)"),
1789  S_OR(callid_buf, "(None)")
1790  );
1791 
1792  ast_str_append(&output, 0, " Variables:\n");
1793 
1794  AST_LIST_TRAVERSE(ast_channel_varshead(chan), var, entries) {
1795  ast_str_append(&output, 0, "%s=%s\n", ast_var_name(var), ast_var_value(var));
1796  }
1797 
1798  if (!(ast_channel_tech(chan)->properties & AST_CHAN_TP_INTERNAL)
1799  && ast_cdr_serialize_variables(ast_channel_name(chan), &obuf, '=', '\n')) {
1800  ast_str_append(&output, 0, " CDR Variables:\n%s\n", ast_str_buffer(obuf));
1801  }
1802 
1803  ast_str_append(&output, 0, " -- Streams --\n");
1804  for (stream_num = 0; stream_num < ast_stream_topology_get_count(ast_channel_get_stream_topology(chan)); stream_num++) {
1806  struct ast_variable *metadata = ast_stream_get_metadata_list(stream);
1807 
1808  ast_str_append(&output, 0,
1809  "Name: %s\n"
1810  " Type: %s\n"
1811  " State: %s\n"
1812  " Group: %d\n"
1813  " Formats: %s\n"
1814  " Metadata:\n",
1815  ast_stream_get_name(stream),
1818  ast_stream_get_group(stream),
1820  );
1821 
1822  if (metadata) {
1823  struct ast_variable *v;
1824  for(v = metadata; v; v = v->next) {
1825  ast_str_append(&output, 0, " %s: %s\n", v->name, v->value);
1826  }
1827  ast_variables_destroy(metadata);
1828  }
1829  }
1830 
1831  ast_channel_unlock(chan);
1832 
1833  ast_cli(a->fd, "%s", ast_str_buffer(output));
1834  ast_free(output);
1835 
1836  ao2_cleanup(bridge);
1837  ast_channel_unref(chan);
1838 
1839  return CLI_SUCCESS;
1840 }
struct ast_variable * next
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:1865
Main Channel structure associated with a channel.
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:971
const ast_string_field uniqueid
Definition: bridge.h:401
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:1262
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:2958
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316
ast_callid callid
Definition: bridge.h:361
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
const ast_string_field name
Definition: bridge.h:401
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:348
Structure for variables, used for configurations and for channel variables.
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117
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:1139
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
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
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:10534
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:87
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
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:628
Structure that contains information about a bridge.
Definition: bridge.h:349
Support for dynamic strings.
Definition: strings.h:623
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:734
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
char * command
Definition: cli.h:186
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
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
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:930
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
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:3415
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:909
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:2288
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
const char * ast_state2str(enum ast_channel_state state)
Gives the string form of a given channel state.
Definition: channel.c:636
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'ed dynamic length string.
Definition: strings.h:659
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 2070 of file main/cli.c.

References ast_cli_entry::_full_cmd, ast_cli_entry::args, ast_join, ast_strdup, ast_cli_entry::cmda, and ast_cli_entry::cmdlen.

2071 {
2072  int i;
2073  char buf[80];
2074 
2075  ast_join(buf, sizeof(buf), e->cmda);
2076  e->_full_cmd = ast_strdup(buf);
2077  if (!e->_full_cmd) {
2078  ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf);
2079  return -1;
2080  }
2081  e->cmdlen = strcspn(e->_full_cmd, cli_rsvd);
2082  for (i = 0; e->cmda[i]; i++)
2083  ;
2084  e->args = i;
2085  return 0;
2086 }
char * _full_cmd
Definition: cli.h:181
int cmdlen
Definition: cli.h:182
#define ast_join(s, len, w)
Join an array of strings into a single string.
Definition: strings.h:520
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
int args
This gets set in ast_cli_register()
Definition: cli.h:185
static const char cli_rsvd[]
Definition: main/cli.c:2064
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:172
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 2262 of file main/cli.c.

2263 {
2264  int l;
2265  char *pos;
2266 
2267  if (ast_strlen_zero(cmd) || ast_strlen_zero(cli_word))
2268  return -1;
2269  if (!strchr(cli_rsvd, cli_word[0])) /* normal match */
2270  return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1;
2271  l = strlen(cmd);
2272  /* wildcard match - will extend in the future */
2273  if (l > 0 && cli_word[0] == '%') {
2274  return 1; /* wildcard */
2275  }
2276 
2277  /* Start a search for the command entered against the cli word in question */
2278  pos = strcasestr(cli_word, cmd);
2279  while (pos) {
2280 
2281  /*
2282  *Check if the word matched with is surrounded by reserved characters on both sides
2283  * and isn't at the beginning of the cli_word since that would make it check in a location we shouldn't know about.
2284  * If it is surrounded by reserved chars and isn't at the beginning, it's a match.
2285  */
2286  if (pos != cli_word && strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) {
2287  return 1; /* valid match */
2288  }
2289 
2290  /* Ok, that one didn't match, strcasestr to the next appearance of the command and start over.*/
2291  pos = strcasestr(pos + 1, cmd);
2292  }
2293  /* If no matches were found over the course of the while loop, we hit the end of the string. It's a mismatch. */
2294  return -1;
2295 }
static const char cli_rsvd[]
Definition: main/cli.c:2064

Variable Documentation

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

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

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

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.