Wed Jan 8 2020 09:50:10

Asterisk developer's documentation


cli.c File Reference

Standard Command Line Interface. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include <sys/signal.h>
#include <signal.h>
#include <ctype.h>
#include <regex.h>
#include <pwd.h>
#include <grp.h>
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/lock.h"
#include "editline/readline/readline.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"

Go to the source code of this file.

Data Structures

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

Macros

#define AST_CLI_INITLEN   256
 Initial buffer size for resulting strings in ast_cli() More...
 
#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
 
#define DAY   (HOUR*24)
 
#define FORMAT_STRING   "%-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\n"
 
#define MODLIST_FORMAT2   "%-30s %-40.40s %-10s\n"
 
#define NEEDCOMMA(x)   ((x)? ",": "") /* define if we need a comma */
 
#define SECOND   (1)
 
#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
 
#define VERBOSE_FORMAT_STRING2   "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-11.11s %-20.20s\n"
 
#define WEEK   (DAY*7)
 
#define YEAR   (DAY*365)
 

Functions

static char * __ast_cli_generator (const char *text, const char *word, int state, int lock)
 
static int __ast_cli_register (struct ast_cli_entry *e, struct ast_cli_entry *ed)
 
static int __ast_cli_unregister (struct ast_cli_entry *e, struct ast_cli_entry *ed)
 
static void __init_ast_cli_buf (void)
 
void ast_builtins_init (void)
 initialize the _full_cmd string in * each of the builtins. More...
 
void ast_cli (int fd, const char *fmt,...)
 
int ast_cli_command_full (int uid, int gid, int fd, const char *s)
 Interprets a command Interpret a command s, sending output to fd if uid:gid has permissions to run this command. uid = CLI_NO_PERMS to avoid checking user permissions gid = CLI_NO_PERMS to avoid checking group permissions. 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)
 
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...
 
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_generatornummatches (const char *text, const char *word)
 Return the number of unique matches for the generator. More...
 
int ast_cli_perms_init (int reload)
 
int ast_cli_register (struct ast_cli_entry *e)
 Registers a command or an array of commands. More...
 
int ast_cli_register_multiple (struct ast_cli_entry *e, int len)
 Register multiple commands. 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...
 
unsigned int ast_verbose_get_by_module (const char *module)
 Get the verbose level for a module. More...
 
static int channel_set_debug (void *obj, void *arg, void *data, int flags)
 
static int cli_has_permissions (int uid, int gid, const char *command)
 
static int cli_is_registered (struct ast_cli_entry *e)
 
static struct ast_cli_entrycli_next (struct ast_cli_entry *e)
 
static void cli_shutdown (void)
 
static char * complete_fn (const char *word, int state)
 
static char * complete_number (const char *partial, unsigned int min, unsigned int max, int n)
 
static void destroy_match_list (char **match_list, int matches)
 
static void destroy_user_perms (void)
 cleanup (free) cli_perms linkedlist. 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, unsigned int debug)
 Find the debug or verbose file 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_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_commandcomplete (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_commandmatchesarray (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_commandnummatches (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_core_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_core_set_debug_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_help (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_load (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_logger_mute (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_modlist (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_nodebugchan_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showcalls (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showchan (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showuptime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_softhangup (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_unload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_verbose (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * help1 (int fd, const char *const match[], int locked)
 helper for final part of handle_help if locked = 1, assume the list is already locked 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 *like)
 
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 int set_full_cmd (struct ast_cli_entry *e)
 
static int word_match (const char *cmd, const char *cli_word)
 

Variables

static struct ast_threadstorage ast_cli_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ast_cli_buf , .custom_init = NULL , }
 
static struct ast_cli_entry cli_cli []
 
static int cli_default_perm = 1
 Default permissions value 1=Permit 0=Deny. More...
 
static struct cli_perms cli_perms = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static const char cli_rsvd [] = "[]{}|*%"
 
static int climodentryfd = -1
 
static ast_mutex_t climodentrylock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static struct module_level_list debug_modules = AST_RWLIST_HEAD_INIT_VALUE
 
static struct helpers helpers = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
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 }
 mutex used to prevent a user from running the 'cli reload permissions' command while it is already running. More...
 
static struct module_level_list verbose_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 cli.c.

Macro Definition Documentation

#define AST_CLI_INITLEN   256

Initial buffer size for resulting strings in ast_cli()

Definition at line 103 of file cli.c.

Referenced by ast_cli().

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

Referenced by handle_chanlist().

#define DAY   (HOUR*24)

Referenced by print_uptimestr().

#define FORMAT_STRING   "%-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"

Referenced by handle_chanlist().

#define HOUR   (MINUTE*60)

Referenced by print_uptimestr().

#define MINUTE   (SECOND*60)

Referenced by print_uptimestr().

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

Definition at line 645 of file cli.c.

Referenced by modlist_modentry().

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

Definition at line 646 of file cli.c.

Referenced by handle_modlist().

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

Referenced by print_uptimestr().

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

Referenced by handle_chanlist().

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

Referenced by handle_chanlist().

#define WEEK   (DAY*7)

Referenced by print_uptimestr().

#define YEAR   (DAY*365)

Referenced by print_uptimestr().

Function Documentation

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

Definition at line 2442 of file cli.c.

References ast_cli_args::argv, ARRAY_LEN, ast_free, ast_join(), AST_MAX_ARGS, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_strlen_zero(), CLI_GENERATE, cli_next(), ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::handler, is_prefix(), ast_cli_args::line, more_words(), parse_args(), word, and word_match().

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

2443 {
2444  const char *argv[AST_MAX_ARGS];
2445  struct ast_cli_entry *e = NULL;
2446  int x = 0, argindex, matchlen;
2447  int matchnum=0;
2448  char *ret = NULL;
2449  char matchstr[80] = "";
2450  int tws = 0;
2451  /* Split the argument into an array of words */
2452  char *duplicate = parse_args(text, &x, argv, ARRAY_LEN(argv), &tws);
2453 
2454  if (!duplicate) /* malloc error */
2455  return NULL;
2456 
2457  /* Compute the index of the last argument (could be an empty string) */
2458  argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x;
2459 
2460  /* rebuild the command, ignore terminating white space and flatten space */
2461  ast_join(matchstr, sizeof(matchstr)-1, argv);
2462  matchlen = strlen(matchstr);
2463  if (tws) {
2464  strcat(matchstr, " "); /* XXX */
2465  if (matchlen)
2466  matchlen++;
2467  }
2468  if (lock)
2470  while ( (e = cli_next(e)) ) {
2471  /* XXX repeated code */
2472  int src = 0, dst = 0, n = 0;
2473 
2474  if (e->command[0] == '_')
2475  continue;
2476 
2477  /*
2478  * Try to match words, up to and excluding the last word, which
2479  * is either a blank or something that we want to extend.
2480  */
2481  for (;src < argindex; dst++, src += n) {
2482  n = word_match(argv[src], e->cmda[dst]);
2483  if (n < 0)
2484  break;
2485  }
2486 
2487  if (src != argindex && more_words(e->cmda + dst)) /* not a match */
2488  continue;
2489  ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n);
2490  matchnum += n; /* this many matches here */
2491  if (ret) {
2492  /*
2493  * argv[src] is a valid prefix of the next word in this
2494  * command. If this is also the correct entry, return it.
2495  */
2496  if (matchnum > state)
2497  break;
2498  ast_free(ret);
2499  ret = NULL;
2500  } else if (ast_strlen_zero(e->cmda[dst])) {
2501  /*
2502  * This entry is a prefix of the command string entered
2503  * (only one entry in the list should have this property).
2504  * Run the generator if one is available. In any case we are done.
2505  */
2506  if (e->handler) { /* new style command */
2507  struct ast_cli_args a = {
2508  .line = matchstr, .word = word,
2509  .pos = argindex,
2510  .n = state - matchnum,
2511  .argv = argv,
2512  .argc = x};
2513  ret = e->handler(e, CLI_GENERATE, &a);
2514  }
2515  if (ret)
2516  break;
2517  }
2518  }
2519  if (lock)
2521  ast_free(duplicate);
2522  return ret;
2523 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
descriptor for a cli entry.
Definition: cli.h:165
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static char * parse_args(const char *s, int *argc, const char *argv[], int max, int *trailingwhitespace)
Definition: cli.c:2266
char * text
Definition: app_queue.c:1091
static int more_words(const char *const *dst)
returns true if there are more words to match
Definition: cli.c:2429
Definition: ael.tab.c:203
const char * line
Definition: cli.h:156
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: cli.c:1936
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static int word_match(const char *cmd, const char *cli_word)
Definition: cli.c:1897
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
ast_mutex_t lock
Definition: app_meetme.c:964
const char *const * argv
Definition: cli.h:155
char *(* handler)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cli.h:181
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: cli.c:712
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
#define AST_MAX_ARGS
Definition: cli.h:49
void ast_join(char *s, size_t len, const char *const w[])
Definition: utils.c:1690
Definition: cli.c:225
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:166
static int __ast_cli_register ( struct ast_cli_entry e,
struct ast_cli_entry ed 
)
static

Definition at line 2082 of file cli.c.

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

Referenced by ast_cli_register().

2083 {
2084  struct ast_cli_entry *cur;
2085  int i, lf, ret = -1;
2086 
2087  struct ast_cli_args a; /* fake argument */
2088  char **dst = (char **)e->cmda; /* need to cast as the entry is readonly */
2089  char *s;
2090 
2092 
2093  if (cli_is_registered(e)) {
2094  ast_log(LOG_WARNING, "Command '%s' already registered (the same ast_cli_entry)\n",
2095  S_OR(e->_full_cmd, e->command));
2096  ret = 0; /* report success */
2097  goto done;
2098  }
2099 
2100  memset(&a, '\0', sizeof(a));
2101  e->handler(e, CLI_INIT, &a);
2102  /* XXX check that usage and command are filled up */
2103  s = ast_skip_blanks(e->command);
2104  s = e->command = ast_strdup(s);
2105  for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) {
2106  *dst++ = s; /* store string */
2107  s = ast_skip_nonblanks(s);
2108  if (*s == '\0') /* we are done */
2109  break;
2110  *s++ = '\0';
2111  s = ast_skip_blanks(s);
2112  }
2113  *dst++ = NULL;
2114 
2115  if (find_cli(e->cmda, 1)) {
2116  ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n",
2117  S_OR(e->_full_cmd, e->command));
2118  goto done;
2119  }
2120  if (set_full_cmd(e)) {
2121  ast_log(LOG_WARNING, "Error registering CLI Command '%s'\n",
2122  S_OR(e->_full_cmd, e->command));
2123  goto done;
2124  }
2125 
2126  lf = e->cmdlen;
2128  int len = cur->cmdlen;
2129  if (lf < len)
2130  len = lf;
2131  if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) {
2133  break;
2134  }
2135  }
2137 
2138  if (!cur)
2139  AST_RWLIST_INSERT_TAIL(&helpers, e, list);
2140  ret = 0; /* success */
2141 
2142 done:
2144  if (ret) {
2145  ast_free(e->command);
2146  e->command = NULL;
2147  }
2148 
2149  return ret;
2150 }
char * _full_cmd
Definition: cli.h:175
int cmdlen
Definition: cli.h:176
#define ast_strdup(a)
Definition: astmm.h:109
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
descriptor for a cli entry.
Definition: cli.h:165
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static int cli_is_registered(struct ast_cli_entry *e)
Definition: cli.c:2048
Definition: cli.h:146
char * ast_skip_nonblanks(const char *str)
Gets a pointer to first whitespace character in a string.
Definition: strings.h:136
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_cli_entry * find_cli(const char *const cmds[], int match_type)
Definition: cli.c:1986
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:595
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
char *(* handler)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cli.h:181
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:97
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
Definition: cli.c:225
static int set_full_cmd(struct ast_cli_entry *e)
Definition: cli.c:1717
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:166
#define AST_MAX_CMD_LEN
Definition: cli.h:47
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
static int __ast_cli_unregister ( struct ast_cli_entry e,
struct ast_cli_entry ed 
)
static

Definition at line 2060 of file cli.c.

References ast_cli_entry::_full_cmd, ast_free, ast_log(), AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::handler, ast_cli_entry::inuse, LOG_WARNING, and ast_cli_entry::usage.

Referenced by ast_cli_unregister().

2061 {
2062  if (e->inuse) {
2063  ast_log(LOG_WARNING, "Can't remove command that is in use\n");
2064  } else {
2066  AST_RWLIST_REMOVE(&helpers, e, list);
2068  ast_free(e->_full_cmd);
2069  e->_full_cmd = NULL;
2070  if (e->handler) {
2071  /* this is a new-style entry. Reset fields and free memory. */
2072  char *cmda = (char *) e->cmda;
2073  memset(cmda, '\0', sizeof(e->cmda));
2074  ast_free(e->command);
2075  e->command = NULL;
2076  e->usage = NULL;
2077  }
2078  }
2079  return 0;
2080 }
char * _full_cmd
Definition: cli.h:175
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
int inuse
Definition: cli.h:173
char *(* handler)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cli.h:181
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
Definition: cli.c:225
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:870
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:166
static void __init_ast_cli_buf ( void  )
static

Definition at line 100 of file cli.c.

106 {
void ast_builtins_init ( void  )

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 1880 of file cli.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_register_atexit(), and cli_shutdown().

Referenced by main().

1881 {
1884 }
static struct ast_cli_entry cli_cli[]
Definition: cli.c:1661
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
static void cli_shutdown(void)
Definition: cli.c:1874
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
void ast_cli ( int  fd,
const char *  fmt,
  ... 
)

Definition at line 105 of file cli.c.

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

Referenced by __iax2_show_peers(), __say_cli_init(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), _sip_show_peers_one(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), agent_logoff_cmd(), agents_show(), agents_show_online(), ais_clm_show_members(), ais_evt_show_event_channels(), aji_cli_create_collection(), aji_cli_create_leafnode(), aji_cli_delete_pubsub_node(), aji_cli_list_pubsub_nodes(), aji_cli_purge_pubsub_nodes(), aji_do_reload(), aji_do_set_debug(), aji_show_buddies(), aji_show_clients(), alias_show(), aoc_cli_debug_enable(), ast_cli_command_full(), ast_cli_netstats(), ast_console_toggle_mute(), cc_cli_output_status(), cc_cli_print_monitor_stats(), channel_set_debug(), cli_console_active(), cli_console_answer(), cli_console_autoanswer(), cli_console_dial(), cli_console_flash(), cli_console_hangup(), cli_console_mute(), cli_console_sendtext(), cli_fax_set_debug(), cli_fax_show_capabilities(), cli_fax_show_session(), cli_fax_show_sessions(), cli_fax_show_settings(), cli_fax_show_stats(), cli_fax_show_version(), cli_list_available(), cli_list_devices(), cli_match_char_tree(), cli_odbc_read(), cli_odbc_write(), cli_realtime_destroy(), cli_realtime_load(), cli_realtime_store(), cli_realtime_update(), cli_realtime_update2(), cli_tps_ping(), cli_tps_report(), console_active(), console_answer(), console_autoanswer(), console_boost(), console_cmd(), console_dial(), console_do_answer(), console_flash(), console_hangup(), console_mute(), console_sendtext(), console_transfer(), dahdi_set_dnd(), dahdi_set_hwgain(), dahdi_set_swgain(), dahdi_show_channel(), dahdi_show_channels(), dahdi_show_status(), dahdi_show_version(), data_provider_print_cli(), data_result_print_cli(), data_result_print_cli_node(), db_show_cb(), db_showkey_cb(), dialog_dump_func(), do_print(), dump_raw_ie(), dundi_do_lookup(), dundi_do_precache(), dundi_do_query(), dundi_flush(), dundi_set_debug(), dundi_show_entityid(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), dundi_store_history(), event_dump_cache(), event_dump_cli(), group_show_channels(), gtalk_show_channels(), handle_chanlist(), handle_cli_agi_add_cmd(), handle_cli_agi_debug(), handle_cli_agi_dump_html(), handle_cli_agi_show(), handle_cli_check_permissions(), handle_cli_config_list(), handle_cli_core_show_channeltype(), handle_cli_core_show_channeltypes(), handle_cli_core_show_config_mappings(), handle_cli_core_show_file_formats(), handle_cli_core_show_translation(), handle_cli_database_del(), handle_cli_database_deltree(), handle_cli_database_get(), handle_cli_database_put(), handle_cli_database_show(), handle_cli_database_showkey(), handle_cli_devstate_change(), handle_cli_devstate_list(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_add_ignorepat(), handle_cli_dialplan_add_include(), handle_cli_dialplan_reload(), handle_cli_dialplan_remove_extension(), handle_cli_dialplan_remove_ignorepat(), handle_cli_dialplan_remove_include(), handle_cli_dialplan_save(), handle_cli_file_convert(), handle_cli_h323_set_debug(), handle_cli_h323_set_trace(), handle_cli_iax2_provision(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_set_debug_jb(), handle_cli_iax2_set_debug_trunk(), handle_cli_iax2_set_mtu(), handle_cli_iax2_show_cache(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_firmware(), handle_cli_iax2_show_netstats(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_stats(), handle_cli_iax2_show_threads(), handle_cli_iax2_show_users(), handle_cli_iax2_unregister(), handle_cli_indication_show(), handle_cli_keys_show(), handle_cli_misdn_reload(), handle_cli_misdn_send_digit(), handle_cli_misdn_send_display(), handle_cli_misdn_set_debug(), handle_cli_misdn_show_channels(), handle_cli_misdn_show_config(), handle_cli_misdn_show_port(), handle_cli_misdn_show_ports_stats(), handle_cli_misdn_show_stacks(), handle_cli_misdn_toggle_echocancel(), handle_cli_mixmonitor(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_cli_odbc_show(), handle_cli_osp_show(), handle_cli_realtime_pgsql_cache(), handle_cli_realtime_pgsql_status(), handle_cli_refresh(), handle_cli_rtcp_set_debug(), handle_cli_rtcp_set_stats(), handle_cli_rtp_set_debug(), handle_cli_show_permissions(), handle_cli_show_sqlite_status(), handle_cli_sqlite_show_tables(), handle_cli_status(), handle_cli_stun_set_debug(), handle_cli_submit(), handle_cli_transcoder_show(), handle_cli_udptl_set_debug(), handle_cli_ulimit(), handle_cli_wait_fullybooted(), handle_commandcomplete(), handle_commandmatchesarray(), handle_commandnummatches(), handle_core_set_debug_channel(), handle_core_show_image_formats(), handle_dahdi_show_cadences(), handle_debug_dialplan(), handle_feature_show(), handle_help(), handle_load(), handle_logger_reload(), handle_logger_rotate(), handle_logger_set_level(), handle_logger_show_channels(), handle_manager_show_settings(), handle_mandebug(), handle_mfcr2_call_files(), handle_mfcr2_set_blocked(), handle_mfcr2_set_debug(), handle_mfcr2_set_idle(), handle_mfcr2_show_channels(), handle_mfcr2_show_variants(), handle_mfcr2_version(), handle_mgcp_audit_endpoint(), handle_mgcp_set_debug(), handle_mgcp_show_endpoints(), handle_minivm_list_templates(), handle_minivm_reload(), handle_minivm_show_settings(), handle_minivm_show_stats(), handle_minivm_show_users(), handle_minivm_show_zones(), handle_modlist(), handle_parkedcalls(), handle_pri_debug(), handle_pri_destroy_span(), handle_pri_service_generic(), handle_pri_set_debug_file(), handle_pri_show_debug(), handle_pri_show_span(), handle_pri_version(), handle_queue_add_member(), handle_queue_pause_member(), handle_queue_remove_member(), handle_queue_rule_show(), handle_queue_set_member_penalty(), handle_redirect(), handle_reload(), handle_restart_when_convenient(), handle_set_chanvar(), handle_set_extenpatternmatchnew(), handle_set_global(), handle_show_application(), handle_show_applications(), handle_show_calendar(), handle_show_calendars(), handle_show_chanvar(), handle_show_dialplan(), handle_show_function(), handle_show_functions(), handle_show_globals(), handle_show_hint(), handle_show_hints(), handle_show_http(), handle_show_profile(), handle_show_settings(), handle_show_switches(), handle_show_sysinfo(), handle_show_threads(), handle_show_version_files(), handle_showcalls(), handle_showchan(), handle_showmanager(), handle_showmanagers(), handle_showmancmd(), handle_showmancmds(), handle_showmanconn(), handle_showmaneventq(), handle_skinny_set_debug(), handle_skinny_show_settings(), handle_softhangup(), handle_stop_when_convenient(), handle_unload(), handle_unset_extenpatternmatchnew(), handle_verbose(), handle_version(), handle_voicemail_reload(), handle_voicemail_show_users(), handle_voicemail_show_zones(), help1(), help_workhorse(), iax_show_provisioning(), jingle_show_channels(), locals_show(), meetme_show_cmd(), modlist_modentry(), orig_app(), orig_exten(), peer_dump_func(), pktccops_debug(), pktccops_gatedel(), pktccops_gateset(), pktccops_show_cmtses(), pktccops_show_gates(), pktccops_show_pools(), print_app_docs(), print_bc_info(), print_cel_sub(), print_codec_to_cli(), print_group(), print_stats_cb(), print_uptimestr(), realtime_ldap_status(), rtcp_do_debug_ip(), rtp_do_debug_ip(), show_channels_cb(), show_chanstats_cb(), show_codec_n(), show_codecs(), show_config_description(), show_debug_helper(), show_dialplan_helper(), show_license(), show_users_realtime(), show_warranty(), sig_pri_cli_show_channels(), sig_pri_cli_show_channels_header(), sig_pri_cli_show_span(), sig_pri_cli_show_spans(), sip_cli_notify(), sip_do_debug(), sip_do_debug_ip(), sip_do_debug_peer(), sip_prune_realtime(), sip_set_history(), sip_show_channel(), sip_show_channels(), sip_show_channelstats(), sip_show_domains(), sip_show_history(), sip_show_inuse(), sip_show_mwi(), sip_show_objects(), sip_show_registry(), sip_show_sched(), sip_show_settings(), sip_show_tcp(), sip_show_user(), sip_show_users(), sip_unregister(), sla_show_stations(), sla_show_trunks(), spandsp_fax_cli_show_capabilities(), spandsp_fax_cli_show_session(), spandsp_fax_cli_show_stats(), timing_test(), unistim_do_debug(), unistim_info(), and unistim_sp().

106 {
107  int res;
108  struct ast_str *buf;
109  va_list ap;
110 
112  return;
113 
114  va_start(ap, fmt);
115  res = ast_str_set_va(&buf, 0, fmt, ap);
116  va_end(ap);
117 
118  if (res != AST_DYNSTR_BUILD_FAILED) {
119  ast_carefulwrite(fd, ast_str_buffer(buf), ast_str_strlen(buf), 100);
120  }
121 }
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: utils.c:1328
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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:792
#define AST_CLI_INITLEN
Initial buffer size for resulting strings in ast_cli()
Definition: cli.c:103
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
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:669
static struct ast_threadstorage ast_cli_buf
Definition: cli.c:100
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 2530 of file cli.c.

References args, ast_atomic_fetchadd_int(), ast_cli(), ast_free, ast_join(), AST_MAX_ARGS, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_FAILURE, CLI_HANDLER, cli_has_permissions(), CLI_SHOWUSAGE, ast_cli_args::fd, find_best(), find_cli(), ast_cli_entry::handler, ast_cli_entry::inuse, parse_args(), S_OR, and ast_cli_entry::usage.

Referenced by ast_cli_command_multiple_full().

2531 {
2532  const char *args[AST_MAX_ARGS + 1];
2533  struct ast_cli_entry *e;
2534  int x;
2535  char *duplicate = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL);
2536  char tmp[AST_MAX_ARGS + 1];
2537  char *retval = NULL;
2538  struct ast_cli_args a = {
2539  .fd = fd, .argc = x, .argv = args+1 };
2540 
2541  if (duplicate == NULL)
2542  return -1;
2543 
2544  if (x < 1) /* We need at least one entry, otherwise ignore */
2545  goto done;
2546 
2548  e = find_cli(args + 1, 0);
2549  if (e)
2552  if (e == NULL) {
2553  ast_cli(fd, "No such command '%s' (type 'core show help %s' for other possible commands)\n", s, find_best(args + 1));
2554  goto done;
2555  }
2556 
2557  ast_join(tmp, sizeof(tmp), args + 1);
2558  /* Check if the user has rights to run this command. */
2559  if (!cli_has_permissions(uid, gid, tmp)) {
2560  ast_cli(fd, "You don't have permissions to run '%s' command\n", tmp);
2561  ast_free(duplicate);
2562  return 0;
2563  }
2564 
2565  /*
2566  * Within the handler, argv[-1] contains a pointer to the ast_cli_entry.
2567  * Remember that the array returned by parse_args is NULL-terminated.
2568  */
2569  args[0] = (char *)e;
2570 
2571  retval = e->handler(e, CLI_HANDLER, &a);
2572 
2573  if (retval == CLI_SHOWUSAGE) {
2574  ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
2575  } else {
2576  if (retval == CLI_FAILURE)
2577  ast_cli(fd, "Command '%s' failed.\n", s);
2578  }
2579  ast_atomic_fetchadd_int(&e->inuse, -1);
2580 done:
2581  ast_free(duplicate);
2582  return 0;
2583 }
static char * find_best(const char *argv[])
Definition: cli.c:2030
descriptor for a cli entry.
Definition: cli.h:165
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static int cli_has_permissions(int uid, int gid, const char *command)
Definition: cli.c:170
static char * parse_args(const char *s, int *argc, const char *argv[], int max, int *trailingwhitespace)
Definition: cli.c:2266
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
int inuse
Definition: cli.h:173
const int fd
Definition: cli.h:153
static struct ast_cli_entry * find_cli(const char *const cmds[], int match_type)
Definition: cli.c:1986
char *(* handler)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cli.h:181
static struct @350 args
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
#define ast_free(a)
Definition: astmm.h:97
#define AST_MAX_ARGS
Definition: cli.h:49
void ast_join(char *s, size_t len, const char *const w[])
Definition: utils.c:1690
const char * usage
Definition: cli.h:171
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
Definition: cli.c:225
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 2585 of file cli.c.

References ast_cli_command_full().

Referenced by netconsole().

2586 {
2587  char cmd[512];
2588  int x, y = 0, count = 0;
2589 
2590  for (x = 0; x < size; x++) {
2591  cmd[y] = s[x];
2592  y++;
2593  if (s[x] == '\0') {
2594  ast_cli_command_full(uid, gid, fd, cmd);
2595  y = 0;
2596  count++;
2597  }
2598  }
2599  return count;
2600 }
const int fd
Definition: cli.h:153
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: cli.c:2530
char* ast_cli_complete ( const char *  word,
const char *const  choices[],
int  pos 
)

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

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

Definition at line 1535 of file cli.c.

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

Referenced by event_dump_cache(), handle_cc_kill(), handle_cli_core_show_translation(), handle_cli_devstate_change(), handle_cli_iax2_prune_realtime(), handle_orig(), handle_show_applications(), and sip_prune_realtime().

1536 {
1537  int i, which = 0, len;
1538  len = ast_strlen_zero(word) ? 0 : strlen(word);
1539 
1540  for (i = 0; choices[i]; i++) {
1541  if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state)
1542  return ast_strdup(choices[i]);
1543  }
1544  return NULL;
1545 }
#define ast_strdup(a)
Definition: astmm.h:109
Definition: ael.tab.c:203
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char** ast_cli_completion_matches ( const char *  ,
const char *   
)

Generates a NULL-terminated array of strings that 1) begin with the string in the second parameter, and 2) are valid in a command after the string in the first parameter.

The first entry (offset 0) of the result is the longest common substring in the results, useful to extend the string that has been completed. Subsequent entries are all possible values, followed by a NULL. All strings and the array itself are malloc'ed and must be freed by the caller.

Definition at line 2368 of file cli.c.

References ast_cli_generator(), ast_copy_string(), ast_free, ast_malloc, ast_realloc, and destroy_match_list().

Referenced by cli_complete(), and handle_commandmatchesarray().

2369 {
2370  char **match_list = NULL, *retstr, *prevstr;
2371  char **new_list;
2372  size_t match_list_len, max_equal, which, i;
2373  int matches = 0;
2374 
2375  /* leave entry 0 free for the longest common substring */
2376  match_list_len = 1;
2377  while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
2378  if (matches + 1 >= match_list_len) {
2379  match_list_len <<= 1;
2380  new_list = ast_realloc(match_list, match_list_len * sizeof(*match_list));
2381  if (!new_list) {
2382  destroy_match_list(match_list, matches);
2383  return NULL;
2384  }
2385  match_list = new_list;
2386  }
2387  match_list[++matches] = retstr;
2388  }
2389 
2390  if (!match_list) {
2391  return match_list; /* NULL */
2392  }
2393 
2394  /* Find the longest substring that is common to all results
2395  * (it is a candidate for completion), and store a copy in entry 0.
2396  */
2397  prevstr = match_list[1];
2398  max_equal = strlen(prevstr);
2399  for (which = 2; which <= matches; which++) {
2400  for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
2401  continue;
2402  max_equal = i;
2403  }
2404 
2405  retstr = ast_malloc(max_equal + 1);
2406  if (!retstr) {
2407  destroy_match_list(match_list, matches);
2408  return NULL;
2409  }
2410  ast_copy_string(retstr, match_list[1], max_equal + 1);
2411  match_list[0] = retstr;
2412 
2413  /* ensure that the array is NULL terminated */
2414  if (matches + 1 >= match_list_len) {
2415  new_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list));
2416  if (!new_list) {
2417  ast_free(retstr);
2418  destroy_match_list(match_list, matches);
2419  return NULL;
2420  }
2421  match_list = new_list;
2422  }
2423  match_list[matches + 1] = NULL;
2424 
2425  return match_list;
2426 }
char * text
Definition: app_queue.c:1091
Definition: ael.tab.c:203
#define ast_free(a)
Definition: astmm.h:97
char * ast_cli_generator(const char *, const char *, int)
Readline madness Useful for readline, that&#39;s about it.
Definition: cli.c:2525
static void destroy_match_list(char **match_list, int matches)
Definition: cli.c:2356
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define ast_realloc(a, b)
Definition: astmm.h:103
#define ast_malloc(a)
Definition: astmm.h:91
char* ast_cli_generator ( const char *  ,
const char *  ,
int   
)

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

Return values
0on success
-1on failure

Definition at line 2525 of file cli.c.

References __ast_cli_generator().

Referenced by ast_cli_completion_matches(), ast_cli_generatornummatches(), cli_alias_passthrough(), and handle_cli_check_permissions().

2526 {
2527  return __ast_cli_generator(text, word, state, 1);
2528 }
char * text
Definition: app_queue.c:1091
Definition: ael.tab.c:203
static char * __ast_cli_generator(const char *text, const char *word, int state, int lock)
Definition: cli.c:2442
int ast_cli_generatornummatches ( const char *  text,
const char *  word 
)

Return the number of unique matches for the generator.

Definition at line 2339 of file cli.c.

References ast_cli_generator(), and ast_free.

Referenced by handle_commandnummatches().

2340 {
2341  int matches = 0, i = 0;
2342  char *buf = NULL, *oldbuf = NULL;
2343 
2344  while ((buf = ast_cli_generator(text, word, i++))) {
2345  if (!oldbuf || strcmp(buf,oldbuf))
2346  matches++;
2347  if (oldbuf)
2348  ast_free(oldbuf);
2349  oldbuf = buf;
2350  }
2351  if (oldbuf)
2352  ast_free(oldbuf);
2353  return matches;
2354 }
char * text
Definition: app_queue.c:1091
Definition: ael.tab.c:203
#define ast_free(a)
Definition: astmm.h:97
char * ast_cli_generator(const char *, const char *, int)
Readline madness Useful for readline, that&#39;s about it.
Definition: cli.c:2525
int ast_cli_perms_init ( int  reload)

Provided by cli.c

Definition at line 1752 of file cli.c.

References ast_calloc, ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_mutex_trylock, ast_mutex_unlock, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ast_strlen_zero(), ast_variable_browse(), cli_perm::command, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, destroy_user_perms(), usergroup_cli_perm::gid, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, cli_perm::permit, usergroup_cli_perm::perms, perms_config, usergroup_cli_perm::uid, and ast_variable::value.

Referenced by handle_cli_reload_permissions(), and main().

1753 {
1754  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1755  struct ast_config *cfg;
1756  char *cat = NULL;
1757  struct ast_variable *v;
1758  struct usergroup_cli_perm *user_group, *cp_entry;
1759  struct cli_perm *perm = NULL;
1760  struct passwd *pw;
1761  struct group *gr;
1762 
1764  ast_log(LOG_NOTICE, "You must wait until last 'cli reload permissions' command finish\n");
1765  return 1;
1766  }
1767 
1768  cfg = ast_config_load2(perms_config, "" /* core, can't reload */, config_flags);
1769  if (!cfg) {
1771  return 1;
1772  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
1774  return 0;
1775  }
1776 
1777  /* free current structures. */
1779 
1780  while ((cat = ast_category_browse(cfg, cat))) {
1781  if (!strcasecmp(cat, "general")) {
1782  /* General options */
1783  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
1784  if (!strcasecmp(v->name, "default_perm")) {
1785  cli_default_perm = (!strcasecmp(v->value, "permit")) ? 1: 0;
1786  }
1787  }
1788  continue;
1789  }
1790 
1791  /* users or groups */
1792  gr = NULL, pw = NULL;
1793  if (cat[0] == '@') {
1794  /* This is a group */
1795  gr = getgrnam(&cat[1]);
1796  if (!gr) {
1797  ast_log (LOG_WARNING, "Unknown group '%s'\n", &cat[1]);
1798  continue;
1799  }
1800  } else {
1801  /* This is a user */
1802  pw = getpwnam(cat);
1803  if (!pw) {
1804  ast_log (LOG_WARNING, "Unknown user '%s'\n", cat);
1805  continue;
1806  }
1807  }
1808  user_group = NULL;
1809  /* Check for duplicates */
1811  AST_LIST_TRAVERSE(&cli_perms, cp_entry, list) {
1812  if ((pw && cp_entry->uid == pw->pw_uid) || (gr && cp_entry->gid == gr->gr_gid)) {
1813  /* if it is duplicated, just added this new settings, to
1814  the current list. */
1815  user_group = cp_entry;
1816  break;
1817  }
1818  }
1820 
1821  if (!user_group) {
1822  /* alloc space for the new user config. */
1823  user_group = ast_calloc(1, sizeof(*user_group));
1824  if (!user_group) {
1825  continue;
1826  }
1827  user_group->uid = (pw ? pw->pw_uid : -1);
1828  user_group->gid = (gr ? gr->gr_gid : -1);
1829  user_group->perms = ast_calloc(1, sizeof(*user_group->perms));
1830  if (!user_group->perms) {
1831  ast_free(user_group);
1832  continue;
1833  }
1834  }
1835  for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
1836  if (ast_strlen_zero(v->value)) {
1837  /* we need to check this condition cause it could break security. */
1838  ast_log(LOG_WARNING, "Empty permit/deny option in user '%s'\n", cat);
1839  continue;
1840  }
1841  if (!strcasecmp(v->name, "permit")) {
1842  perm = ast_calloc(1, sizeof(*perm));
1843  if (perm) {
1844  perm->permit = 1;
1845  perm->command = ast_strdup(v->value);
1846  }
1847  } else if (!strcasecmp(v->name, "deny")) {
1848  perm = ast_calloc(1, sizeof(*perm));
1849  if (perm) {
1850  perm->permit = 0;
1851  perm->command = ast_strdup(v->value);
1852  }
1853  } else {
1854  /* up to now, only 'permit' and 'deny' are possible values. */
1855  ast_log(LOG_WARNING, "Unknown '%s' option\n", v->name);
1856  continue;
1857  }
1858  if (perm) {
1859  /* Added the permission to the user's list. */
1860  AST_LIST_INSERT_TAIL(user_group->perms, perm, list);
1861  perm = NULL;
1862  }
1863  }
1865  AST_RWLIST_INSERT_TAIL(&cli_perms, user_group, list);
1867  }
1868 
1869  ast_config_destroy(cfg);
1871  return 0;
1872 }
#define ast_strdup(a)
Definition: astmm.h:109
static int cli_default_perm
Default permissions value 1=Permit 0=Deny.
Definition: cli.c:76
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
const char * value
Definition: config.h:79
#define ast_mutex_trylock(a)
Definition: lock.h:157
struct cli_perm_head * perms
Definition: cli.c:70
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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: cli.c:80
static const char perms_config[]
CLI permissions config file.
Definition: cli.c:74
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
const char * name
Definition: config.h:77
List of restrictions per user.
Definition: cli.c:58
static int reload(void)
Definition: app_amd.c:497
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
list of users to apply restrictions.
Definition: cli.c:67
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#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:97
Structure used to handle boolean flags.
Definition: utils.h:200
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
#define ast_calloc(a, b)
Definition: astmm.h:82
static void destroy_user_perms(void)
cleanup (free) cli_perms linkedlist.
Definition: cli.c:1736
List of users and permissions.
Definition: cli.c:82
char * command
Definition: cli.c:60
struct ast_variable * next
Definition: config.h:82
unsigned int permit
Definition: cli.c:59
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
#define ast_mutex_unlock(a)
Definition: lock.h:156
int ast_cli_register ( struct ast_cli_entry e)

Registers a command or an array of commands.

Parameters
ewhich cli entry to register. Register your own command
Return values
0on success
-1on failure

Definition at line 2159 of file cli.c.

References __ast_cli_register().

Referenced by ast_cdr_engine_init(), ast_cel_engine_init(), ast_cli_register_multiple(), dnsmgr_init(), do_reload(), load_config(), and load_module().

2160 {
2161  return __ast_cli_register(e, NULL);
2162 }
static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed)
Definition: cli.c:2082
int ast_cli_register_multiple ( struct ast_cli_entry e,
int  len 
)

Register multiple commands.

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

Definition at line 2167 of file cli.c.

References ast_cli_register(), and len().

Referenced by __ast_register_translator(), __init_manager(), ast_ais_clm_load_module(), ast_ais_evt_load_module(), ast_aoc_cli_init(), ast_builtins_init(), ast_cc_init(), ast_channels_init(), ast_data_init(), ast_event_init(), ast_features_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_indications_init(), ast_stun_init(), ast_test_init(), ast_timing_init(), ast_tps_init(), ast_udptl_init(), ast_utils_init(), astdb_init(), astobj2_init(), crypto_init(), iax_provision_init(), init_framer(), init_logger(), load_module(), load_pbx(), main(), and register_config_cli().

2168 {
2169  int i, res = 0;
2170 
2171  for (i = 0; i < len; i++)
2172  res |= ast_cli_register(e + i);
2173 
2174  return res;
2175 }
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
Definition: cli.c:2159
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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 2153 of file cli.c.

References __ast_cli_unregister().

Referenced by alias_unregister_cb(), ast_cel_engine_term(), ast_cli_unregister_multiple(), cdr_engine_shutdown(), dnsmgr_shutdown(), do_reload(), load_module(), and unload_module().

2154 {
2155  return __ast_cli_unregister(e, NULL);
2156 }
static int __ast_cli_unregister(struct ast_cli_entry *e, struct ast_cli_entry *ed)
Definition: cli.c:2060
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 2177 of file cli.c.

References ast_cli_unregister(), and len().

Referenced by __unload_module(), aoc_shutdown(), ast_ais_clm_unload_module(), astdb_shutdown(), astobj2_cleanup(), cc_shutdown(), channels_shutdown(), cli_shutdown(), close_logger(), config_shutdown(), data_shutdown(), event_shutdown(), features_shutdown(), file_shutdown(), framer_shutdown(), http_shutdown(), iax_provision_unload(), image_shutdown(), indications_shutdown(), load_module(), main_atexit(), manager_shutdown(), stun_shutdown(), timing_shutdown(), tps_shutdown(), udptl_shutdown(), unload_module(), and unload_pbx().

2178 {
2179  int i, res = 0;
2180 
2181  for (i = 0; i < len; i++)
2182  res |= ast_cli_unregister(e + i);
2183 
2184  return res;
2185 }
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: cli.c:2153
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char* ast_complete_channels ( const char *  line,
const char *  word,
int  pos,
int  state,
int  rpos 
)

Command completion for the list of active channels.

This can be called from a CLI command completion function that wants to complete from the list of active channels. 'rpos' is the required position in the command. This function will return NULL immediately if 'rpos' is not the same as the current position, 'pos'.

Definition at line 1547 of file cli.c.

References ast_channel_iterator_all_new(), ast_channel_iterator_by_name_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_strdup, ast_strlen_zero(), and ast_channel::name.

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

1548 {
1549  struct ast_channel *c = NULL;
1550  int which = 0;
1551  char notfound = '\0';
1552  char *ret = &notfound; /* so NULL can break the loop */
1553  struct ast_channel_iterator *iter;
1554 
1555  if (pos != rpos) {
1556  return NULL;
1557  }
1558 
1559  if (ast_strlen_zero(word)) {
1561  } else {
1562  iter = ast_channel_iterator_by_name_new(word, strlen(word));
1563  }
1564 
1565  if (!iter) {
1566  return NULL;
1567  }
1568 
1569  while (ret == &notfound && (c = ast_channel_iterator_next(iter))) {
1570  if (++which > state) {
1571  ast_channel_lock(c);
1572  ret = ast_strdup(c->name);
1573  ast_channel_unlock(c);
1574  }
1575  ast_channel_unref(c);
1576  }
1577 
1579 
1580  return ret == &notfound ? NULL : ret;
1581 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1715
#define ast_strdup(a)
Definition: astmm.h:109
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
Definition: ael.tab.c:203
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct ast_channel_iterator * ast_channel_iterator_by_name_new(const char *name, size_t name_len)
Create a new channel iterator based on name.
Definition: channel.c:1696
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1649
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1701
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 123 of file cli.c.

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

124 {
125  struct module_level *ml;
126  unsigned int res = 0;
127 
129  AST_LIST_TRAVERSE(&debug_modules, ml, entry) {
130  if (!strcasecmp(ml->module, module)) {
131  res = ml->level;
132  break;
133  }
134  }
136 
137  return res;
138 }
unsigned int level
Definition: cli.c:88
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
static struct module_level_list debug_modules
Definition: cli.c:96
map a debug or verbose level to a module name
Definition: cli.c:87
#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
unsigned int ast_verbose_get_by_module ( const char *  module)

Get the verbose level for a module.

Parameters
modulethe name of module
Returns
the verbose level

Definition at line 140 of file cli.c.

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

141 {
142  struct module_level *ml;
143  unsigned int res = 0;
144 
146  AST_LIST_TRAVERSE(&verbose_modules, ml, entry) {
147  if (!strcasecmp(ml->module, module)) {
148  res = ml->level;
149  break;
150  }
151  }
153 
154  return res;
155 }
unsigned int level
Definition: cli.c:88
#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: cli.c:87
#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
static struct module_level_list verbose_modules
Definition: cli.c:98
static int channel_set_debug ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 1280 of file cli.c.

References args, ast_channel_lock, ast_channel_unlock, ast_cli(), DEBUGCHAN_FLAG, channel_set_debug_args::fd, ast_channel::fin, ast_channel::fout, channel_set_debug_args::is_off, and ast_channel::name.

Referenced by handle_core_set_debug_channel().

1281 {
1282  struct ast_channel *chan = obj;
1283  struct channel_set_debug_args *args = data;
1284 
1285  ast_channel_lock(chan);
1286 
1287  if (!(chan->fin & DEBUGCHAN_FLAG) || !(chan->fout & DEBUGCHAN_FLAG)) {
1288  if (args->is_off) {
1289  chan->fin &= ~DEBUGCHAN_FLAG;
1290  chan->fout &= ~DEBUGCHAN_FLAG;
1291  } else {
1292  chan->fin |= DEBUGCHAN_FLAG;
1293  chan->fout |= DEBUGCHAN_FLAG;
1294  }
1295  ast_cli(args->fd, "Debugging %s on channel %s\n", args->is_off ? "disabled" : "enabled",
1296  chan->name);
1297  }
1298 
1299  ast_channel_unlock(chan);
1300 
1301  return 0;
1302 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define DEBUGCHAN_FLAG
Definition: channel.h:648
unsigned int fout
Definition: channel.h:847
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
unsigned int fin
Definition: channel.h:845
static struct @350 args
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static int cli_has_permissions ( int  uid,
int  gid,
const char *  command 
)
static

Definition at line 170 of file cli.c.

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

Referenced by ast_cli_command_full(), and handle_cli_check_permissions().

171 {
172  struct usergroup_cli_perm *user_perm;
173  struct cli_perm *perm;
174  /* set to the default permissions general option. */
175  int isallowg = cli_default_perm, isallowu = -1, ispattern;
176  regex_t regexbuf;
177 
178  /* if uid == -1 or gid == -1 do not check permissions.
179  if uid == -2 and gid == -2 is because rasterisk client didn't send
180  the credentials, so the cli_default_perm will be applied. */
181  if ((uid == CLI_NO_PERMS && gid == CLI_NO_PERMS) || command[0] == '_') {
182  return 1;
183  }
184 
185  if (gid < 0 && uid < 0) {
186  return cli_default_perm;
187  }
188 
190  AST_LIST_TRAVERSE(&cli_perms, user_perm, list) {
191  if (user_perm->gid != gid && user_perm->uid != uid) {
192  continue;
193  }
194  AST_LIST_TRAVERSE(user_perm->perms, perm, list) {
195  if (strcasecmp(perm->command, "all") && strncasecmp(perm->command, command, strlen(perm->command))) {
196  /* if the perm->command is a pattern, check it against command. */
197  ispattern = !regcomp(&regexbuf, perm->command, REG_EXTENDED | REG_NOSUB | REG_ICASE);
198  if (ispattern && regexec(&regexbuf, command, 0, NULL, 0)) {
199  regfree(&regexbuf);
200  continue;
201  }
202  if (!ispattern) {
203  continue;
204  }
205  regfree(&regexbuf);
206  }
207  if (user_perm->uid == uid) {
208  /* this is a user definition. */
209  isallowu = perm->permit;
210  } else {
211  /* otherwise is a group definition. */
212  isallowg = perm->permit;
213  }
214  }
215  }
217  if (isallowu > -1) {
218  /* user definition override group definition. */
219  isallowg = isallowu;
220  }
221 
222  return isallowg;
223 }
static int cli_default_perm
Default permissions value 1=Permit 0=Deny.
Definition: cli.c:76
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct cli_perm::@239 list
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define CLI_NO_PERMS
Definition: cli.h:37
struct cli_perm_head * perms
Definition: cli.c:70
List of restrictions per user.
Definition: cli.c:58
list of users to apply restrictions.
Definition: cli.c:67
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
List of users and permissions.
Definition: cli.c:82
char * command
Definition: cli.c:60
unsigned int permit
Definition: cli.c:59
static int cli_is_registered ( struct ast_cli_entry e)
static

Definition at line 2048 of file cli.c.

References cli_next().

Referenced by __ast_cli_register().

2049 {
2050  struct ast_cli_entry *cur = NULL;
2051 
2052  while ((cur = cli_next(cur))) {
2053  if (cur == e) {
2054  return 1;
2055  }
2056  }
2057  return 0;
2058 }
descriptor for a cli entry.
Definition: cli.h:165
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: cli.c:712
static struct ast_cli_entry* cli_next ( struct ast_cli_entry e)
static

Definition at line 712 of file cli.c.

References AST_LIST_FIRST, and AST_LIST_NEXT.

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

713 {
714  if (e) {
715  return AST_LIST_NEXT(e, list);
716  } else {
717  return AST_LIST_FIRST(&helpers);
718  }
719 }
#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
Definition: cli.c:225
struct ast_cli_entry::@159 list
static void cli_shutdown ( void  )
static

Definition at line 1874 of file cli.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by ast_builtins_init().

1875 {
1877 }
static struct ast_cli_entry cli_cli[]
Definition: cli.c:1661
#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: cli.c:2177
static char* complete_fn ( const char *  word,
int  state 
)
static

Definition at line 227 of file cli.c.

References ast_config_AST_MODULE_DIR, ast_copy_string(), ast_std_free(), and ast_strdup.

Referenced by handle_load().

228 {
229  char *c, *d;
230  char filename[PATH_MAX];
231 
232  if (word[0] == '/')
233  ast_copy_string(filename, word, sizeof(filename));
234  else
235  snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_MODULE_DIR, word);
236 
237  c = d = filename_completion_function(filename, state);
238 
239  if (c && word[0] != '/')
240  c += (strlen(ast_config_AST_MODULE_DIR) + 1);
241  if (c)
242  c = ast_strdup(c);
243 
244  ast_std_free(d);
245 
246  return c;
247 }
void ast_std_free(void *ptr)
#define ast_strdup(a)
Definition: astmm.h:109
const char * ast_config_AST_MODULE_DIR
Definition: asterisk.c:258
Definition: ael.tab.c:203
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char* complete_number ( const char *  partial,
unsigned int  min,
unsigned int  max,
int  n 
)
static

Definition at line 349 of file cli.c.

References ast_strdup, ast_strlen_zero(), and cli_perm::next.

Referenced by handle_verbose().

350 {
351  int i, count = 0;
352  unsigned int prospective[2];
353  unsigned int part = strtoul(partial, NULL, 10);
354  char next[12];
355 
356  if (part < min || part > max) {
357  return NULL;
358  }
359 
360  for (i = 0; i < 21; i++) {
361  if (i == 0) {
362  prospective[0] = prospective[1] = part;
363  } else if (part == 0 && !ast_strlen_zero(partial)) {
364  break;
365  } else if (i < 11) {
366  prospective[0] = prospective[1] = part * 10 + (i - 1);
367  } else {
368  prospective[0] = (part * 10 + (i - 11)) * 10;
369  prospective[1] = prospective[0] + 9;
370  }
371  if (i < 11 && (prospective[0] < min || prospective[0] > max)) {
372  continue;
373  } else if (prospective[1] < min || prospective[0] > max) {
374  continue;
375  }
376 
377  if (++count > n) {
378  if (i < 11) {
379  snprintf(next, sizeof(next), "%u", prospective[0]);
380  } else {
381  snprintf(next, sizeof(next), "%u...", prospective[0] / 10);
382  }
383  return ast_strdup(next);
384  }
385  }
386  return NULL;
387 }
#define ast_strdup(a)
Definition: astmm.h:109
struct ast_cli_entry * next
Definition: cli.h:183
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static void destroy_match_list ( char **  match_list,
int  matches 
)
static

Definition at line 2356 of file cli.c.

References ast_free.

Referenced by ast_cli_completion_matches().

2357 {
2358  if (match_list) {
2359  int idx;
2360 
2361  for (idx = 1; idx < matches; ++idx) {
2362  ast_free(match_list[idx]);
2363  }
2364  ast_free(match_list);
2365  }
2366 }
#define ast_free(a)
Definition: astmm.h:97
static void destroy_user_perms ( void  )
static

cleanup (free) cli_perms linkedlist.

Definition at line 1736 of file cli.c.

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

Referenced by ast_cli_perms_init().

1737 {
1738  struct cli_perm *perm;
1739  struct usergroup_cli_perm *user_perm;
1740 
1742  while ((user_perm = AST_LIST_REMOVE_HEAD(&cli_perms, list))) {
1743  while ((perm = AST_LIST_REMOVE_HEAD(user_perm->perms, list))) {
1744  ast_free(perm->command);
1745  ast_free(perm);
1746  }
1747  ast_free(user_perm);
1748  }
1750 }
#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: cli.c:70
struct usergroup_cli_perm::@240 list
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
List of restrictions per user.
Definition: cli.c:58
list of users to apply restrictions.
Definition: cli.c:67
#define ast_free(a)
Definition: astmm.h:97
List of users and permissions.
Definition: cli.c:82
char * command
Definition: cli.c:60
static char* find_best ( const char *  argv[])
static

Definition at line 2030 of file cli.c.

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

Referenced by ast_cli_command_full().

2031 {
2032  static char cmdline[80];
2033  int x;
2034  /* See how close we get, then print the candidate */
2035  const char *myargv[AST_MAX_CMD_LEN] = { NULL, };
2036 
2038  for (x = 0; argv[x]; x++) {
2039  myargv[x] = argv[x];
2040  if (!find_cli(myargv, -1))
2041  break;
2042  }
2044  ast_join(cmdline, sizeof(cmdline), myargv);
2045  return cmdline;
2046 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#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: cli.c:1986
void ast_join(char *s, size_t len, const char *const w[])
Definition: utils.c:1690
Definition: cli.c:225
#define AST_MAX_CMD_LEN
Definition: cli.h:47
static struct ast_cli_entry* find_cli ( const char *const  cmds[],
int  match_type 
)
static

Definition at line 1986 of file cli.c.

References ast_strlen_zero(), cli_next(), ast_cli_entry::cmda, and word_match().

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

1987 {
1988  int matchlen = -1; /* length of longest match so far */
1989  struct ast_cli_entry *cand = NULL, *e=NULL;
1990 
1991  while ( (e = cli_next(e)) ) {
1992  /* word-by word regexp comparison */
1993  const char * const *src = cmds;
1994  const char * const *dst = e->cmda;
1995  int n = 0;
1996  for (;; dst++, src += n) {
1997  n = word_match(*src, *dst);
1998  if (n < 0)
1999  break;
2000  }
2001  if (ast_strlen_zero(*dst) || ((*dst)[0] == '[' && ast_strlen_zero(dst[1]))) {
2002  /* no more words in 'e' */
2003  if (ast_strlen_zero(*src)) /* exact match, cannot do better */
2004  break;
2005  /* Here, cmds has more words than the entry 'e' */
2006  if (match_type != 0) /* but we look for almost exact match... */
2007  continue; /* so we skip this one. */
2008  /* otherwise we like it (case 0) */
2009  } else { /* still words in 'e' */
2010  if (ast_strlen_zero(*src))
2011  continue; /* cmds is shorter than 'e', not good */
2012  /* Here we have leftover words in cmds and 'e',
2013  * but there is a mismatch. We only accept this one if match_type == -1
2014  * and this is the last word for both.
2015  */
2016  if (match_type != -1 || !ast_strlen_zero(src[1]) ||
2017  !ast_strlen_zero(dst[1])) /* not the one we look for */
2018  continue;
2019  /* good, we are in case match_type == -1 and mismatch on last word */
2020  }
2021  if (src - cmds > matchlen) { /* remember the candidate */
2022  matchlen = src - cmds;
2023  cand = e;
2024  }
2025  }
2026 
2027  return e ? e : cand;
2028 }
descriptor for a cli entry.
Definition: cli.h:165
static int word_match(const char *cmd, const char *cli_word)
Definition: cli.c:1897
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: cli.c:712
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:166
static struct module_level* find_module_level ( const char *  module,
unsigned int  debug 
)
static

Find the debug or verbose file setting.

  • debug 1 for debug, 0 for verbose

Definition at line 336 of file cli.c.

References AST_LIST_TRAVERSE, debug_modules, and verbose_modules.

Referenced by handle_verbose().

337 {
338  struct module_level *ml;
339  struct module_level_list *mll = debug ? &debug_modules : &verbose_modules;
340 
341  AST_LIST_TRAVERSE(mll, ml, entry) {
342  if (!strcasecmp(ml->module, module))
343  return ml;
344  }
345 
346  return NULL;
347 }
static struct module_level_list debug_modules
Definition: cli.c:96
map a debug or verbose level to a module name
Definition: cli.c:87
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static struct module_level_list verbose_modules
Definition: cli.c:98
static char* group_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1583 of file cli.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_app_group_list_head(), ast_app_group_list_rdlock(), ast_app_group_list_unlock(), ast_cli(), AST_LIST_NEXT, ast_strlen_zero(), ast_group_info::category, ast_group_info::chan, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ESS, ast_cli_args::fd, FORMAT_STRING, ast_group_info::group, ast_group_info::group_list, ast_channel::name, and ast_cli_entry::usage.

1584 {
1585 #define FORMAT_STRING "%-25s %-20s %-20s\n"
1586 
1587  struct ast_group_info *gi = NULL;
1588  int numchans = 0;
1589  regex_t regexbuf;
1590  int havepattern = 0;
1591 
1592  switch (cmd) {
1593  case CLI_INIT:
1594  e->command = "group show channels";
1595  e->usage =
1596  "Usage: group show channels [pattern]\n"
1597  " Lists all currently active channels with channel group(s) specified.\n"
1598  " Optional regular expression pattern is matched to group names for each\n"
1599  " channel.\n";
1600  return NULL;
1601  case CLI_GENERATE:
1602  return NULL;
1603  }
1604 
1605  if (a->argc < 3 || a->argc > 4)
1606  return CLI_SHOWUSAGE;
1607 
1608  if (a->argc == 4) {
1609  if (regcomp(&regexbuf, a->argv[3], REG_EXTENDED | REG_NOSUB))
1610  return CLI_SHOWUSAGE;
1611  havepattern = 1;
1612  }
1613 
1614  ast_cli(a->fd, FORMAT_STRING, "Channel", "Group", "Category");
1615 
1617 
1618  gi = ast_app_group_list_head();
1619  while (gi) {
1620  if (!havepattern || !regexec(&regexbuf, gi->group, 0, NULL, 0)) {
1621  ast_cli(a->fd, FORMAT_STRING, gi->chan->name, gi->group, (ast_strlen_zero(gi->category) ? "(default)" : gi->category));
1622  numchans++;
1623  }
1624  gi = AST_LIST_NEXT(gi, group_list);
1625  }
1626 
1628 
1629  if (havepattern)
1630  regfree(&regexbuf);
1631 
1632  ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
1633  return CLI_SUCCESS;
1634 #undef FORMAT_STRING
1635 }
channel group info
Definition: channel.h:2459
const int argc
Definition: cli.h:154
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define FORMAT_STRING
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * group
Definition: channel.h:2462
struct ast_channel * chan
Definition: channel.h:2460
const char *const * argv
Definition: cli.h:155
struct ast_group_info * ast_app_group_list_head(void)
Get the head of the group count list.
Definition: app.c:1375
#define CLI_SHOWUSAGE
Definition: cli.h:44
const ast_string_field name
Definition: channel.h:787
#define ESS(x)
Definition: cli.h:58
char * command
Definition: cli.h:180
char * category
Definition: channel.h:2461
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
int ast_app_group_list_unlock(void)
Unlock the group count list.
Definition: app.c:1380
struct ast_group_info::@157 group_list
int ast_app_group_list_rdlock(void)
Read Lock the group count list.
Definition: app.c:1370
static char* handle_chanlist ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 846 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_active_calls(), ast_active_channels(), ast_bridged_channel(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_processed_calls(), ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, CONCISE_FORMAT_STRING, ESS, ast_cli_args::fd, FORMAT_STRING, FORMAT_STRING2, ast_channel::name, option_maxcalls, S_COR, S_OR, ast_cli_entry::usage, VERBOSE_FORMAT_STRING, and VERBOSE_FORMAT_STRING2.

847 {
848 #define FORMAT_STRING "%-20.20s %-20.20s %-7.7s %-30.30s\n"
849 #define FORMAT_STRING2 "%-20.20s %-20.20s %-7.7s %-30.30s\n"
850 #define CONCISE_FORMAT_STRING "%s!%s!%s!%d!%s!%s!%s!%s!%s!%s!%d!%s!%s!%s\n"
851 #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"
852 #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"
853 
854  struct ast_channel *c = NULL;
855  int numchans = 0, concise = 0, verbose = 0, count = 0;
856  struct ast_channel_iterator *iter = NULL;
857 
858  switch (cmd) {
859  case CLI_INIT:
860  e->command = "core show channels [concise|verbose|count]";
861  e->usage =
862  "Usage: core show channels [concise|verbose|count]\n"
863  " Lists currently defined channels and some information about them. If\n"
864  " 'concise' is specified, the format is abridged and in a more easily\n"
865  " machine parsable format. If 'verbose' is specified, the output includes\n"
866  " more and longer fields. If 'count' is specified only the channel and call\n"
867  " count is output.\n"
868  " The 'concise' option is deprecated and will be removed from future versions\n"
869  " of Asterisk.\n";
870  return NULL;
871 
872  case CLI_GENERATE:
873  return NULL;
874  }
875 
876  if (a->argc == e->args) {
877  if (!strcasecmp(a->argv[e->args-1],"concise"))
878  concise = 1;
879  else if (!strcasecmp(a->argv[e->args-1],"verbose"))
880  verbose = 1;
881  else if (!strcasecmp(a->argv[e->args-1],"count"))
882  count = 1;
883  else
884  return CLI_SHOWUSAGE;
885  } else if (a->argc != e->args - 1)
886  return CLI_SHOWUSAGE;
887 
888  if (!count) {
889  if (!concise && !verbose)
890  ast_cli(a->fd, FORMAT_STRING2, "Channel", "Location", "State", "Application(Data)");
891  else if (verbose)
892  ast_cli(a->fd, VERBOSE_FORMAT_STRING2, "Channel", "Context", "Extension", "Priority", "State", "Application", "Data",
893  "CallerID", "Duration", "Accountcode", "PeerAccount", "BridgedTo");
894  }
895 
896  if (!count && !(iter = ast_channel_iterator_all_new())) {
897  return CLI_FAILURE;
898  }
899 
900  for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
901  struct ast_channel *bc;
902  char durbuf[10] = "-";
903 
904  ast_channel_lock(c);
905 
906  bc = ast_bridged_channel(c);
907 
908  if (!count) {
909  if ((concise || verbose) && c->cdr && !ast_tvzero(c->cdr->start)) {
910  int duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
911  if (verbose) {
912  int durh = duration / 3600;
913  int durm = (duration % 3600) / 60;
914  int durs = duration % 60;
915  snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
916  } else {
917  snprintf(durbuf, sizeof(durbuf), "%d", duration);
918  }
919  }
920  if (concise) {
921  ast_cli(a->fd, CONCISE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
922  c->appl ? c->appl : "(None)",
923  S_OR(c->data, ""), /* XXX different from verbose ? */
924  S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
925  S_OR(c->accountcode, ""),
926  S_OR(c->peeraccount, ""),
927  c->amaflags,
928  durbuf,
929  bc ? bc->name : "(None)",
930  c->uniqueid);
931  } else if (verbose) {
932  ast_cli(a->fd, VERBOSE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
933  c->appl ? c->appl : "(None)",
934  c->data ? S_OR(c->data, "(Empty)" ): "(None)",
935  S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
936  durbuf,
937  S_OR(c->accountcode, ""),
938  S_OR(c->peeraccount, ""),
939  bc ? bc->name : "(None)");
940  } else {
941  char locbuf[40] = "(None)";
942  char appdata[40] = "(None)";
943 
944  if (!ast_strlen_zero(c->context) && !ast_strlen_zero(c->exten))
945  snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority);
946  if (c->appl)
947  snprintf(appdata, sizeof(appdata), "%s(%s)", c->appl, S_OR(c->data, ""));
948  ast_cli(a->fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata);
949  }
950  }
952  }
953 
954  if (iter) {
956  }
957 
958  if (!concise) {
959  numchans = ast_active_channels();
960  ast_cli(a->fd, "%d active channel%s\n", numchans, ESS(numchans));
961  if (option_maxcalls)
962  ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
964  ((double)ast_active_calls() / (double)option_maxcalls) * 100.0);
965  else
966  ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
967 
968  ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
969  }
970 
971  return CLI_SUCCESS;
972 
973 #undef FORMAT_STRING
974 #undef FORMAT_STRING2
975 #undef CONCISE_FORMAT_STRING
976 #undef VERBOSE_FORMAT_STRING
977 #undef VERBOSE_FORMAT_STRING2
978 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1715
#define VERBOSE_FORMAT_STRING
int ast_active_calls(void)
Retrieve the number of active calls.
Definition: pbx.c:5931
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
const int argc
Definition: cli.h:154
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
Definition: cli.h:146
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
Definition: channel.c:1007
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
#define VERBOSE_FORMAT_STRING2
#define FORMAT_STRING
const int fd
Definition: cli.h:153
#define CONCISE_FORMAT_STRING
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#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:83
const char *const * argv
Definition: cli.h:155
int ast_processed_calls(void)
Retrieve the total number of calls processed through the PBX since last restart.
Definition: pbx.c:5936
#define CLI_SHOWUSAGE
Definition: cli.h:44
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
#define FORMAT_STRING2
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define CLI_FAILURE
Definition: cli.h:45
#define ESS(x)
Definition: cli.h:58
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1649
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1701
int option_maxcalls
Definition: asterisk.c:184
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:848
static char* handle_cli_check_permissions ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

handles CLI command 'cli check permissions'

Definition at line 1092 of file cli.c.

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

1093 {
1094  struct passwd *pw = NULL;
1095  struct group *gr;
1096  int gid = -1, uid = -1;
1097  char command[AST_MAX_ARGS] = "";
1098  struct ast_cli_entry *ce = NULL;
1099  int found = 0;
1100  char *group, *tmp;
1101 
1102  switch (cmd) {
1103  case CLI_INIT:
1104  e->command = "cli check permissions";
1105  e->usage =
1106  "Usage: cli check permissions {<username>|@<groupname>|<username>@<groupname>} [<command>]\n"
1107  " Check permissions config for a user@group or list the allowed commands for the specified user.\n"
1108  " The username or the groupname may be omitted.\n";
1109  return NULL;
1110  case CLI_GENERATE:
1111  if (a->pos >= 4) {
1112  return ast_cli_generator(a->line + strlen("cli check permissions") + strlen(a->argv[3]) + 1, a->word, a->n);
1113  }
1114  return NULL;
1115  }
1116 
1117  if (a->argc < 4) {
1118  return CLI_SHOWUSAGE;
1119  }
1120 
1121  tmp = ast_strdupa(a->argv[3]);
1122  group = strchr(tmp, '@');
1123  if (group) {
1124  gr = getgrnam(&group[1]);
1125  if (!gr) {
1126  ast_cli(a->fd, "Unknown group '%s'\n", &group[1]);
1127  return CLI_FAILURE;
1128  }
1129  group[0] = '\0';
1130  gid = gr->gr_gid;
1131  }
1132 
1133  if (!group && ast_strlen_zero(tmp)) {
1134  ast_cli(a->fd, "You didn't supply a username\n");
1135  } else if (!ast_strlen_zero(tmp) && !(pw = getpwnam(tmp))) {
1136  ast_cli(a->fd, "Unknown user '%s'\n", tmp);
1137  return CLI_FAILURE;
1138  } else if (pw) {
1139  uid = pw->pw_uid;
1140  }
1141 
1142  if (a->argc == 4) {
1143  while ((ce = cli_next(ce))) {
1144  /* Hide commands that start with '_' */
1145  if (ce->_full_cmd[0] == '_') {
1146  continue;
1147  }
1148  if (cli_has_permissions(uid, gid, ce->_full_cmd)) {
1149  ast_cli(a->fd, "%30.30s %s\n", ce->_full_cmd, S_OR(ce->summary, "<no description available>"));
1150  found++;
1151  }
1152  }
1153  if (!found) {
1154  ast_cli(a->fd, "You are not allowed to run any command on Asterisk\n");
1155  }
1156  } else {
1157  ast_join(command, sizeof(command), a->argv + 4);
1158  ast_cli(a->fd, "%s '%s%s%s' is %s to run command: '%s'\n", uid >= 0 ? "User" : "Group", tmp,
1159  group && uid >= 0 ? "@" : "",
1160  group ? &group[1] : "",
1161  cli_has_permissions(uid, gid, command) ? "allowed" : "not allowed", command);
1162  }
1163 
1164  return CLI_SUCCESS;
1165 }
char * _full_cmd
Definition: cli.h:175
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
static int cli_has_permissions(int uid, int gid, const char *command)
Definition: cli.c:170
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define CLI_SHOWUSAGE
Definition: cli.h:44
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: cli.c:712
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
#define AST_MAX_ARGS
Definition: cli.h:49
void ast_join(char *s, size_t len, const char *const w[])
Definition: utils.c:1690
const char * word
Definition: cli.h:157
char * ast_cli_generator(const char *, const char *, int)
Readline madness Useful for readline, that&#39;s about it.
Definition: cli.c:2525
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const char *const summary
Definition: cli.h:170
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const int pos
Definition: cli.h:158
static ast_group_t group
Definition: chan_agent.c:221
static char* handle_cli_reload_permissions ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

handles CLI command 'cli reload permissions'

Definition at line 1073 of file cli.c.

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

1074 {
1075  switch (cmd) {
1076  case CLI_INIT:
1077  e->command = "cli reload permissions";
1078  e->usage =
1079  "Usage: cli reload permissions\n"
1080  " Reload the 'cli_permissions.conf' file.\n";
1081  return NULL;
1082  case CLI_GENERATE:
1083  return NULL;
1084  }
1085 
1086  ast_cli_perms_init(1);
1087 
1088  return CLI_SUCCESS;
1089 }
Definition: cli.h:146
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
int ast_cli_perms_init(int reload)
Definition: cli.c:1752
static char* handle_cli_show_permissions ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

handles CLI command 'cli show permissions'

Definition at line 1028 of file cli.c.

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

1029 {
1030  struct usergroup_cli_perm *cp;
1031  struct cli_perm *perm;
1032  struct passwd *pw = NULL;
1033  struct group *gr = NULL;
1034 
1035  switch (cmd) {
1036  case CLI_INIT:
1037  e->command = "cli show permissions";
1038  e->usage =
1039  "Usage: cli show permissions\n"
1040  " Shows CLI configured permissions.\n";
1041  return NULL;
1042  case CLI_GENERATE:
1043  return NULL;
1044  }
1045 
1047  AST_LIST_TRAVERSE(&cli_perms, cp, list) {
1048  if (cp->uid >= 0) {
1049  pw = getpwuid(cp->uid);
1050  if (pw) {
1051  ast_cli(a->fd, "user: %s [uid=%d]\n", pw->pw_name, cp->uid);
1052  }
1053  } else {
1054  gr = getgrgid(cp->gid);
1055  if (gr) {
1056  ast_cli(a->fd, "group: %s [gid=%d]\n", gr->gr_name, cp->gid);
1057  }
1058  }
1059  ast_cli(a->fd, "Permissions:\n");
1060  if (cp->perms) {
1061  AST_LIST_TRAVERSE(cp->perms, perm, list) {
1062  ast_cli(a->fd, "\t%s -> %s\n", perm->permit ? "permit" : "deny", perm->command);
1063  }
1064  }
1065  ast_cli(a->fd, "\n");
1066  }
1068 
1069  return CLI_SUCCESS;
1070 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
struct cli_perm_head * perms
Definition: cli.c:70
List of restrictions per user.
Definition: cli.c:58
list of users to apply restrictions.
Definition: cli.c:67
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
List of users and permissions.
Definition: cli.c:82
char * command
Definition: cli.c:60
unsigned int permit
Definition: cli.c:59
static char* handle_cli_wait_fullybooted ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1637 of file cli.c.

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

1638 {
1639  switch (cmd) {
1640  case CLI_INIT:
1641  e->command = "core waitfullybooted";
1642  e->usage =
1643  "Usage: core waitfullybooted\n"
1644  " Wait until Asterisk has fully booted.\n";
1645  return NULL;
1646  case CLI_GENERATE:
1647  return NULL;
1648  }
1649 
1651  usleep(100);
1652  }
1653 
1654  ast_cli(a->fd, "Asterisk has fully booted.\n");
1655 
1656  return CLI_SUCCESS;
1657 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
struct ast_flags ast_options
Definition: asterisk.c:178
static char* handle_commandcomplete ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1250 of file cli.c.

References __ast_cli_generator(), ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_free, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

1251 {
1252  char *buf;
1253  switch (cmd) {
1254  case CLI_INIT:
1255  e->command = "_command complete";
1256  e->usage =
1257  "Usage: _command complete \"<line>\" text state\n"
1258  " This function is used internally to help with command completion and should.\n"
1259  " never be called by the user directly.\n";
1260  return NULL;
1261  case CLI_GENERATE:
1262  return NULL;
1263  }
1264  if (a->argc != 5)
1265  return CLI_SHOWUSAGE;
1266  buf = __ast_cli_generator(a->argv[2], a->argv[3], atoi(a->argv[4]), 0);
1267  if (buf) {
1268  ast_cli(a->fd, "%s", buf);
1269  ast_free(buf);
1270  } else
1271  ast_cli(a->fd, "NULL\n");
1272  return CLI_SUCCESS;
1273 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
static char * __ast_cli_generator(const char *text, const char *word, int state, int lock)
Definition: cli.c:2442
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_commandmatchesarray ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1169 of file cli.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_CLI_COMPLETE_EOF, ast_cli_completion_matches(), ast_free, ast_malloc, ast_realloc, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, len(), and ast_cli_entry::usage.

1170 {
1171  char *buf, *obuf;
1172  int buflen = 2048;
1173  int len = 0;
1174  char **matches;
1175  int x, matchlen;
1176 
1177  switch (cmd) {
1178  case CLI_INIT:
1179  e->command = "_command matchesarray";
1180  e->usage =
1181  "Usage: _command matchesarray \"<line>\" text \n"
1182  " This function is used internally to help with command completion and should.\n"
1183  " never be called by the user directly.\n";
1184  return NULL;
1185  case CLI_GENERATE:
1186  return NULL;
1187  }
1188 
1189  if (a->argc != 4)
1190  return CLI_SHOWUSAGE;
1191  if (!(buf = ast_malloc(buflen)))
1192  return CLI_FAILURE;
1193  buf[len] = '\0';
1194  matches = ast_cli_completion_matches(a->argv[2], a->argv[3]);
1195  if (matches) {
1196  for (x=0; matches[x]; x++) {
1197  matchlen = strlen(matches[x]) + 1;
1198  if (len + matchlen >= buflen) {
1199  buflen += matchlen * 3;
1200  obuf = buf;
1201  if (!(buf = ast_realloc(obuf, buflen)))
1202  /* Memory allocation failure... Just free old buffer and be done */
1203  ast_free(obuf);
1204  }
1205  if (buf)
1206  len += sprintf( buf + len, "%s ", matches[x]);
1207  ast_free(matches[x]);
1208  matches[x] = NULL;
1209  }
1210  ast_free(matches);
1211  }
1212 
1213  if (buf) {
1214  ast_cli(a->fd, "%s%s",buf, AST_CLI_COMPLETE_EOF);
1215  ast_free(buf);
1216  } else
1217  ast_cli(a->fd, "NULL\n");
1218 
1219  return CLI_SUCCESS;
1220 }
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...
Definition: cli.c:2368
#define AST_CLI_COMPLETE_EOF
Definition: cli.h:51
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define CLI_FAILURE
Definition: cli.h:45
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
#define ast_realloc(a, b)
Definition: astmm.h:103
#define ast_malloc(a)
Definition: astmm.h:91
static char* handle_commandnummatches ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1224 of file cli.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_generatornummatches(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

1225 {
1226  int matches = 0;
1227 
1228  switch (cmd) {
1229  case CLI_INIT:
1230  e->command = "_command nummatches";
1231  e->usage =
1232  "Usage: _command nummatches \"<line>\" text \n"
1233  " This function is used internally to help with command completion and should.\n"
1234  " never be called by the user directly.\n";
1235  return NULL;
1236  case CLI_GENERATE:
1237  return NULL;
1238  }
1239 
1240  if (a->argc != 4)
1241  return CLI_SHOWUSAGE;
1242 
1243  matches = ast_cli_generatornummatches(a->argv[2], a->argv[3]);
1244 
1245  ast_cli(a->fd, "%d", matches);
1246 
1247  return CLI_SUCCESS;
1248 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
int ast_cli_generatornummatches(const char *, const char *)
Return the number of unique matches for the generator.
Definition: cli.c:2339
static char* handle_core_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 310 of file cli.c.

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

311 {
312  switch (cmd) {
313  case CLI_INIT:
314  e->command = "core reload";
315  e->usage =
316  "Usage: core reload\n"
317  " Execute a global reload.\n";
318  return NULL;
319 
320  case CLI_GENERATE:
321  return NULL;
322  }
323 
324  if (a->argc != e->args) {
325  return CLI_SHOWUSAGE;
326  }
327 
328  ast_module_reload(NULL);
329 
330  return CLI_SUCCESS;
331 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
int args
This gets set in ast_cli_register()
Definition: cli.h:179
#define CLI_SHOWUSAGE
Definition: cli.h:44
int ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:721
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_core_set_debug_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1304 of file cli.c.

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

Referenced by handle_nodebugchan_deprecated().

1305 {
1306  struct ast_channel *c = NULL;
1307  struct channel_set_debug_args args = {
1308  .fd = a->fd,
1309  };
1310 
1311  switch (cmd) {
1312  case CLI_INIT:
1313  e->command = "core set debug channel";
1314  e->usage =
1315  "Usage: core set debug channel <all|channel> [off]\n"
1316  " Enables/disables debugging on all or on a specific channel.\n";
1317  return NULL;
1318  case CLI_GENERATE:
1319  /* XXX remember to handle the optional "off" */
1320  if (a->pos != e->args)
1321  return NULL;
1322  return a->n == 0 ? ast_strdup("all") : ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
1323  }
1324 
1325  if (cmd == (CLI_HANDLER + 1000)) {
1326  /* called from handle_nodebugchan_deprecated */
1327  args.is_off = 1;
1328  } else if (a->argc == e->args + 2) {
1329  /* 'core set debug channel {all|chan_id}' */
1330  if (!strcasecmp(a->argv[e->args + 1], "off"))
1331  args.is_off = 1;
1332  else
1333  return CLI_SHOWUSAGE;
1334  } else if (a->argc != e->args + 1) {
1335  return CLI_SHOWUSAGE;
1336  }
1337 
1338  if (!strcasecmp("all", a->argv[e->args])) {
1339  if (args.is_off) {
1342  } else {
1345  }
1347  } else {
1348  if ((c = ast_channel_get_by_name(a->argv[e->args]))) {
1349  channel_set_debug(c, NULL, &args, 0);
1350  ast_channel_unref(c);
1351  } else {
1352  ast_cli(a->fd, "No such channel %s\n", a->argv[e->args]);
1353  }
1354  }
1355 
1356  ast_cli(a->fd, "Debugging on new channels is %s\n", args.is_off ? "disabled" : "enabled");
1357 
1358  return CLI_SUCCESS;
1359 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define DEBUGCHAN_FLAG
Definition: channel.h:648
#define ast_strdup(a)
Definition: astmm.h:109
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
const int argc
Definition: cli.h:154
unsigned long global_fin
Definition: channel.c:104
Definition: cli.h:146
unsigned long global_fout
Definition: channel.c:104
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int channel_set_debug(void *obj, void *arg, void *data, int flags)
Definition: cli.c:1280
Definition: ael.tab.c:203
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
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:1634
const char *const * argv
Definition: cli.h:155
static struct @350 args
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
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: cli.c:1547
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
static char * handle_help ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2220 of file cli.c.

References __ast_cli_generator(), ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_join(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, find_cli(), help1(), ast_cli_args::line, ast_cli_args::n, ast_cli_entry::usage, and ast_cli_args::word.

2221 {
2222  char fullcmd[80];
2223  struct ast_cli_entry *my_e;
2224  char *res = CLI_SUCCESS;
2225 
2226  if (cmd == CLI_INIT) {
2227  e->command = "core show help";
2228  e->usage =
2229  "Usage: core show help [topic]\n"
2230  " When called with a topic as an argument, displays usage\n"
2231  " information on the given command. If called without a\n"
2232  " topic, it provides a list of commands.\n";
2233  return NULL;
2234 
2235  } else if (cmd == CLI_GENERATE) {
2236  /* skip first 14 or 15 chars, "core show help " */
2237  int l = strlen(a->line);
2238 
2239  if (l > 15) {
2240  l = 15;
2241  }
2242  /* XXX watch out, should stop to the non-generator parts */
2243  return __ast_cli_generator(a->line + l, a->word, a->n, 0);
2244  }
2245  if (a->argc == e->args) {
2246  return help1(a->fd, NULL, 0);
2247  }
2248 
2250  my_e = find_cli(a->argv + 3, 1); /* try exact match first */
2251  if (!my_e) {
2252  res = help1(a->fd, a->argv + 3, 1 /* locked */);
2254  return res;
2255  }
2256  if (my_e->usage)
2257  ast_cli(a->fd, "%s", my_e->usage);
2258  else {
2259  ast_join(fullcmd, sizeof(fullcmd), a->argv + 3);
2260  ast_cli(a->fd, "No help text available for '%s'.\n", fullcmd);
2261  }
2263  return res;
2264 }
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
int args
This gets set in ast_cli_register()
Definition: cli.h:179
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
static struct ast_cli_entry * find_cli(const char *const cmds[], int match_type)
Definition: cli.c:1986
static char * __ast_cli_generator(const char *text, const char *word, int state, int lock)
Definition: cli.c:2442
const char *const * argv
Definition: cli.h:155
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: cli.c:2191
char * command
Definition: cli.h:180
void ast_join(char *s, size_t len, const char *const w[])
Definition: utils.c:1690
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
Definition: cli.c:225
static char* handle_load ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 249 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_load_resource(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_fn(), ast_cli_args::fd, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

250 {
251  /* "module load <mod>" */
252  switch (cmd) {
253  case CLI_INIT:
254  e->command = "module load";
255  e->usage =
256  "Usage: module load <module name>\n"
257  " Loads the specified module into Asterisk.\n";
258  return NULL;
259 
260  case CLI_GENERATE:
261  if (a->pos != e->args)
262  return NULL;
263  return complete_fn(a->word, a->n);
264  }
265  if (a->argc != e->args + 1)
266  return CLI_SHOWUSAGE;
267  if (ast_load_resource(a->argv[e->args])) {
268  ast_cli(a->fd, "Unable to load module %s\n", a->argv[e->args]);
269  return CLI_FAILURE;
270  }
271  ast_cli(a->fd, "Loaded %s\n", a->argv[e->args]);
272  return CLI_SUCCESS;
273 }
enum ast_module_load_result ast_load_resource(const char *resource_name)
Load a module.
Definition: loader.c:947
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
static char * complete_fn(const char *word, int state)
Definition: cli.c:227
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
static char* handle_logger_mute ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 571 of file cli.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_console_toggle_mute(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

572 {
573  switch (cmd) {
574  case CLI_INIT:
575  e->command = "logger mute";
576  e->usage =
577  "Usage: logger mute\n"
578  " Disables logging output to the current console, making it possible to\n"
579  " gather information without being disturbed by scrolling lines.\n";
580  return NULL;
581  case CLI_GENERATE:
582  return NULL;
583  }
584 
585  if (a->argc < 2 || a->argc > 3)
586  return CLI_SHOWUSAGE;
587 
588  if (a->argc == 3 && !strcasecmp(a->argv[2], "silent"))
590  else
592 
593  return CLI_SUCCESS;
594 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_console_toggle_mute(int fd, int silent)
mute or unmute a console from logging
Definition: asterisk.c:1159
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_modlist ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 752 of file cli.c.

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

753 {
754  const char *like;
755 
756  switch (cmd) {
757  case CLI_INIT:
758  e->command = "module show [like]";
759  e->usage =
760  "Usage: module show [like keyword]\n"
761  " Shows Asterisk modules currently in use, and usage statistics.\n";
762  return NULL;
763 
764  case CLI_GENERATE:
765  if (a->pos == e->args)
766  return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0);
767  else
768  return NULL;
769  }
770  /* all the above return, so we proceed with the handler.
771  * we are guaranteed to have argc >= e->args
772  */
773  if (a->argc == e->args - 1)
774  like = "";
775  else if (a->argc == e->args + 1 && !strcasecmp(a->argv[e->args-1], "like") )
776  like = a->argv[e->args];
777  else
778  return CLI_SHOWUSAGE;
779 
781  climodentryfd = a->fd; /* global, protected by climodentrylock */
782  ast_cli(a->fd, MODLIST_FORMAT2, "Module", "Description", "Use Count");
783  ast_cli(a->fd,"%d modules loaded\n", ast_update_module_list(modlist_modentry, like));
784  climodentryfd = -1;
786  return CLI_SUCCESS;
787 }
const int argc
Definition: cli.h:154
static ast_mutex_t climodentrylock
Definition: cli.c:648
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
Match modules names for the Asterisk cli.
Definition: loader.c:626
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
static int modlist_modentry(const char *module, const char *description, int usecnt, const char *like)
Definition: cli.c:651
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static int climodentryfd
Definition: cli.c:649
int ast_update_module_list(int(*modentry)(const char *module, const char *description, int usecnt, const char *like), const char *like)
Ask for a list of modules, descriptions, and use counts.
Definition: loader.c:1234
const int pos
Definition: cli.h:158
#define MODLIST_FORMAT2
Definition: cli.c:646
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* handle_nodebugchan_deprecated ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1361 of file cli.c.

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

1362 {
1363  char *res;
1364 
1365  switch (cmd) {
1366  case CLI_INIT:
1367  e->command = "no debug channel";
1368  return NULL;
1369  case CLI_HANDLER:
1370  /* exit out of switch statement */
1371  break;
1372  default:
1373  return NULL;
1374  }
1375 
1376  if (a->argc != e->args + 1)
1377  return CLI_SHOWUSAGE;
1378 
1379  /* add a 'magic' value to the CLI_HANDLER command so that
1380  * handle_core_set_debug_channel() will act as if 'off'
1381  * had been specified as part of the command
1382  */
1383  res = handle_core_set_debug_channel(e, CLI_HANDLER + 1000, a);
1384 
1385  return res;
1386 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
int args
This gets set in ast_cli_register()
Definition: cli.h:179
static char * handle_core_set_debug_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: cli.c:1304
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
static char* handle_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 275 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_module_helper(), ast_module_reload(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

276 {
277  int x;
278 
279  switch (cmd) {
280  case CLI_INIT:
281  e->command = "module reload";
282  e->usage =
283  "Usage: module reload [module ...]\n"
284  " Reloads configuration files for all listed modules which support\n"
285  " reloading, or for all supported modules if none are listed.\n";
286  return NULL;
287 
288  case CLI_GENERATE:
289  return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 1);
290  }
291  if (a->argc == e->args) {
292  ast_module_reload(NULL);
293  return CLI_SUCCESS;
294  }
295  for (x = e->args; x < a->argc; x++) {
296  int res = ast_module_reload(a->argv[x]);
297  /* XXX reload has multiple error returns, including -1 on error and 2 on success */
298  switch (res) {
299  case 0:
300  ast_cli(a->fd, "No such module '%s'\n", a->argv[x]);
301  break;
302  case 1:
303  ast_cli(a->fd, "Module '%s' does not support reload\n", a->argv[x]);
304  break;
305  }
306  }
307  return CLI_SUCCESS;
308 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
Match modules names for the Asterisk cli.
Definition: loader.c:626
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
int ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:721
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
static char* handle_showcalls ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 791 of file cli.c.

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

792 {
793  struct timeval curtime = ast_tvnow();
794  int showuptime, printsec;
795 
796  switch (cmd) {
797  case CLI_INIT:
798  e->command = "core show calls [uptime]";
799  e->usage =
800  "Usage: core show calls [uptime] [seconds]\n"
801  " Lists number of currently active calls and total number of calls\n"
802  " processed through PBX since last restart. If 'uptime' is specified\n"
803  " the system uptime is also displayed. If 'seconds' is specified in\n"
804  " addition to 'uptime', the system uptime is displayed in seconds.\n";
805  return NULL;
806 
807  case CLI_GENERATE:
808  if (a->pos != e->args)
809  return NULL;
810  return a->n == 0 ? ast_strdup("seconds") : NULL;
811  }
812 
813  /* regular handler */
814  if (a->argc >= e->args && !strcasecmp(a->argv[e->args-1],"uptime")) {
815  showuptime = 1;
816 
817  if (a->argc == e->args+1 && !strcasecmp(a->argv[e->args],"seconds"))
818  printsec = 1;
819  else if (a->argc == e->args)
820  printsec = 0;
821  else
822  return CLI_SHOWUSAGE;
823  } else if (a->argc == e->args-1) {
824  showuptime = 0;
825  printsec = 0;
826  } else
827  return CLI_SHOWUSAGE;
828 
829  if (option_maxcalls) {
830  ast_cli(a->fd, "%d of %d max active call%s (%5.2f%% of capacity)\n",
832  ((double)ast_active_calls() / (double)option_maxcalls) * 100.0);
833  } else {
834  ast_cli(a->fd, "%d active call%s\n", ast_active_calls(), ESS(ast_active_calls()));
835  }
836 
837  ast_cli(a->fd, "%d call%s processed\n", ast_processed_calls(), ESS(ast_processed_calls()));
838 
839  if (ast_startuptime.tv_sec && showuptime) {
840  print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec);
841  }
842 
843  return RESULT_SUCCESS;
844 }
int ast_active_calls(void)
Retrieve the number of active calls.
Definition: pbx.c:5931
#define ast_strdup(a)
Definition: astmm.h:109
const int argc
Definition: cli.h:154
Definition: cli.h:146
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
static void print_uptimestr(int fd, struct timeval timeval, const char *prefix, int printsec)
Definition: cli.c:661
int ast_processed_calls(void)
Retrieve the total number of calls processed through the PBX since last restart.
Definition: pbx.c:5936
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define ESS(x)
Definition: cli.h:58
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
struct timeval ast_startuptime
Definition: asterisk.c:218
const int pos
Definition: cli.h:158
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: utils.c:1601
#define RESULT_SUCCESS
Definition: cli.h:39
int option_maxcalls
Definition: asterisk.c:184
static char* handle_showchan ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

< Buffer for variable, CDR variable, and trace output.

< Accumulation buffer for all output.

Definition at line 1388 of file cli.c.

References ast_channel::_bridge, ast_channel::_state, ast_channel::appl, ast_cli_args::argc, ast_cli_args::argv, ast_bridged_channel(), ast_cdr_serialize_variables(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), AST_FLAG_BLOCKING, ast_free, ast_getformatname_multiple(), ast_state2str(), ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_thread_get(), ast_test_flag, ast_translate_path_to_str(), ast_tvnow(), ast_channel::blockproc, ast_channel::caller, ast_channel::callgroup, ast_channel::cdr, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel::connected, ast_channel::context, ast_channel::data, DEBUGCHAN_FLAG, ast_channel::dialed, ast_channel::exten, ast_cli_args::fd, ast_channel::fds, ast_channel::fin, ast_channel::fout, ast_party_caller::id, ast_party_connected_line::id, ast_channel::language, ast_cli_args::line, ast_channel::linkedid, ast_cli_args::n, name, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, ast_party_id::number, ast_party_dialed::number, pbx_builtin_serialize_variables(), ast_channel::pickupgroup, ast_cli_args::pos, ast_channel::priority, ast_channel::readformat, ast_channel::readtrans, ast_channel::rings, S_COR, S_OR, ast_cdr::start, ast_party_name::str, ast_party_number::str, ast_party_dialed::str, ast_channel::tech, ast_channel_tech::type, ast_channel::uniqueid, ast_cli_entry::usage, ast_party_name::valid, ast_party_number::valid, ast_channel::whentohangup, ast_cli_args::word, ast_channel::writeformat, and ast_channel::writetrans.

1389 {
1390  struct ast_channel *c=NULL;
1391  struct timeval now;
1392  char cdrtime[256];
1393  char nf[256], wf[256], rf[256];
1394  struct ast_str *write_transpath = ast_str_alloca(256);
1395  struct ast_str *read_transpath = ast_str_alloca(256);
1396  struct ast_str *obuf;/*!< Buffer for variable, CDR variable, and trace output. */
1397  struct ast_str *output;/*!< Accumulation buffer for all output. */
1398  long elapsed_seconds=0;
1399  int hour=0, min=0, sec=0;
1400 #ifdef CHANNEL_TRACE
1401  int trace_enabled;
1402 #endif
1403 
1404  switch (cmd) {
1405  case CLI_INIT:
1406  e->command = "core show channel";
1407  e->usage =
1408  "Usage: core show channel <channel>\n"
1409  " Shows lots of information about the specified channel.\n";
1410  return NULL;
1411  case CLI_GENERATE:
1412  return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
1413  }
1414 
1415  if (a->argc != 4) {
1416  return CLI_SHOWUSAGE;
1417  }
1418 
1419  now = ast_tvnow();
1420 
1421  if (!(c = ast_channel_get_by_name(a->argv[3]))) {
1422  ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
1423  return CLI_SUCCESS;
1424  }
1425 
1426  obuf = ast_str_thread_get(&ast_str_thread_global_buf, 16);
1427  if (!obuf) {
1428  return CLI_FAILURE;
1429  }
1430  output = ast_str_create(8192);
1431  if (!output) {
1432  return CLI_FAILURE;
1433  }
1434 
1435  ast_channel_lock(c);
1436 
1437  if (c->cdr) {
1438  elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
1439  hour = elapsed_seconds / 3600;
1440  min = (elapsed_seconds % 3600) / 60;
1441  sec = elapsed_seconds % 60;
1442  snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec);
1443  } else {
1444  strcpy(cdrtime, "N/A");
1445  }
1446 
1447  ast_str_append(&output, 0,
1448  " -- General --\n"
1449  " Name: %s\n"
1450  " Type: %s\n"
1451  " UniqueID: %s\n"
1452  " LinkedID: %s\n"
1453  " Caller ID: %s\n"
1454  " Caller ID Name: %s\n"
1455  "Connected Line ID: %s\n"
1456  "Connected Line ID Name: %s\n"
1457  " DNID Digits: %s\n"
1458  " Language: %s\n"
1459  " State: %s (%u)\n"
1460  " Rings: %d\n"
1461  " NativeFormats: %s\n"
1462  " WriteFormat: %s\n"
1463  " ReadFormat: %s\n"
1464  " WriteTranscode: %s %s\n"
1465  " ReadTranscode: %s %s\n"
1466  "1st File Descriptor: %d\n"
1467  " Frames in: %u%s\n"
1468  " Frames out: %u%s\n"
1469  " Time to Hangup: %ld\n"
1470  " Elapsed Time: %s\n"
1471  " Direct Bridge: %s\n"
1472  "Indirect Bridge: %s\n"
1473  " -- PBX --\n"
1474  " Context: %s\n"
1475  " Extension: %s\n"
1476  " Priority: %d\n"
1477  " Call Group: %llu\n"
1478  " Pickup Group: %llu\n"
1479  " Application: %s\n"
1480  " Data: %s\n"
1481  " Blocking in: %s\n",
1482  c->name, c->tech->type, c->uniqueid, c->linkedid,
1483  S_COR(c->caller.id.number.valid, c->caller.id.number.str, "(N/A)"),
1484  S_COR(c->caller.id.name.valid, c->caller.id.name.str, "(N/A)"),
1485  S_COR(c->connected.id.number.valid, c->connected.id.number.str, "(N/A)"),
1486  S_COR(c->connected.id.name.valid, c->connected.id.name.str, "(N/A)"),
1487  S_OR(c->dialed.number.str, "(N/A)"),
1488  c->language,
1489  ast_state2str(c->_state), c->_state, c->rings,
1490  ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats),
1491  ast_getformatname_multiple(wf, sizeof(wf), c->writeformat),
1492  ast_getformatname_multiple(rf, sizeof(rf), c->readformat),
1493  c->writetrans ? "Yes" : "No",
1494  ast_translate_path_to_str(c->writetrans, &write_transpath),
1495  c->readtrans ? "Yes" : "No",
1496  ast_translate_path_to_str(c->readtrans, &read_transpath),
1497  c->fds[0],
1498  c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
1499  c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
1500  (long)c->whentohangup.tv_sec,
1501  cdrtime, c->_bridge ? c->_bridge->name : "<none>", ast_bridged_channel(c) ? ast_bridged_channel(c)->name : "<none>",
1502  c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ),
1503  ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),
1504  (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
1505 
1506  if (pbx_builtin_serialize_variables(c, &obuf)) {
1507  ast_str_append(&output, 0, " Variables:\n%s\n", ast_str_buffer(obuf));
1508  }
1509 
1510  if (c->cdr && ast_cdr_serialize_variables(c->cdr, &obuf, '=', '\n', 1)) {
1511  ast_str_append(&output, 0, " CDR Variables:\n%s\n", ast_str_buffer(obuf));
1512  }
1513 
1514 #ifdef CHANNEL_TRACE
1515  trace_enabled = ast_channel_trace_is_enabled(c);
1516  ast_str_append(&output, 0, " Context Trace: %s\n",
1517  trace_enabled ? "Enabled" : "Disabled");
1518  if (trace_enabled && ast_channel_trace_serialize(c, &obuf)) {
1519  ast_str_append(&output, 0, " Trace:\n%s\n", ast_str_buffer(obuf));
1520  }
1521 #endif
1522 
1523  ast_channel_unlock(c);
1524  c = ast_channel_unref(c);
1525 
1526  ast_cli(a->fd, "%s", ast_str_buffer(output));
1527  ast_free(output);
1528  return CLI_SUCCESS;
1529 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
const char *const type
Definition: channel.h:508
int rings
Definition: channel.h:840
char * str
Subscriber phone number (Malloced)
Definition: channel.h:336
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
const ast_string_field uniqueid
Definition: channel.h:787
#define DEBUGCHAN_FLAG
Definition: channel.h:648
format_t writeformat
Definition: channel.h:854
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
const int argc
Definition: cli.h:154
unsigned int fout
Definition: channel.h:847
const char * blockproc
Definition: channel.h:753
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
Definition: cli.h:146
char * str
Subscriber name (Malloced)
Definition: channel.h:214
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:900
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
struct ast_cdr * cdr
Definition: channel.h:766
format_t nativeformats
Definition: channel.h:852
#define ast_str_alloca(init_len)
Definition: strings.h:608
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
Definition: channel.c:1007
const char * data
Definition: channel.h:755
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const ast_string_field linkedid
Definition: channel.h:787
ast_group_t pickupgroup
Definition: channel.h:819
const char * appl
Definition: channel.h:754
const char * line
Definition: cli.h:156
ast_group_t callgroup
Definition: channel.h:818
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
struct ast_party_dialed::@155 number
Dialed/Called number.
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
#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:83
struct ast_channel * _bridge
Definition: channel.h:748
const char *const * argv
Definition: cli.h:155
int fds[AST_MAX_FDS]
Definition: channel.h:829
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
struct ast_trans_pvt * writetrans
Definition: channel.h:762
int ast_cdr_serialize_variables(struct ast_cdr *cdr, struct ast_str **buf, char delim, char sep, int recur)
Definition: cdr.c:409
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
unsigned int fin
Definition: channel.h:845
#define CLI_SHOWUSAGE
Definition: cli.h:44
enum ast_channel_state _state
Definition: channel.h:839
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct timeval start
Definition: cdr.h:100
#define CLI_FAILURE
Definition: cli.h:45
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
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:630
format_t readformat
Definition: channel.h:853
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const int pos
Definition: cli.h:158
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
Definition: frame.c:591
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: cli.c:1547
struct timeval whentohangup
Definition: channel.h:789
struct ast_trans_pvt * readtrans
Definition: channel.h:763
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:669
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
struct ast_channel_tech * tech
Definition: channel.h:743
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int pbx_builtin_serialize_variables(struct ast_channel *chan, struct ast_str **buf)
Create a human-readable string, specifying all variables and their corresponding values.
Definition: pbx.c:10444
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static char* handle_showuptime ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 721 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_lastreloadtime, ast_startuptime, ast_tvnow(), ast_tvsub(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, print_uptimestr(), and ast_cli_entry::usage.

722 {
723  struct timeval curtime = ast_tvnow();
724  int printsec;
725 
726  switch (cmd) {
727  case CLI_INIT:
728  e->command = "core show uptime [seconds]";
729  e->usage =
730  "Usage: core show uptime [seconds]\n"
731  " Shows Asterisk uptime information.\n"
732  " The seconds word returns the uptime in seconds only.\n";
733  return NULL;
734 
735  case CLI_GENERATE:
736  return NULL;
737  }
738  /* regular handler */
739  if (a->argc == e->args && !strcasecmp(a->argv[e->args-1],"seconds"))
740  printsec = 1;
741  else if (a->argc == e->args-1)
742  printsec = 0;
743  else
744  return CLI_SHOWUSAGE;
745  if (ast_startuptime.tv_sec)
746  print_uptimestr(a->fd, ast_tvsub(curtime, ast_startuptime), "System uptime", printsec);
747  if (ast_lastreloadtime.tv_sec)
748  print_uptimestr(a->fd, ast_tvsub(curtime, ast_lastreloadtime), "Last reload", printsec);
749  return CLI_SUCCESS;
750 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
struct timeval ast_lastreloadtime
Definition: asterisk.c:219
const char *const * argv
Definition: cli.h:155
static void print_uptimestr(int fd, struct timeval timeval, const char *prefix, int printsec)
Definition: cli.c:661
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
struct timeval ast_startuptime
Definition: asterisk.c:218
#define CLI_SUCCESS
Definition: cli.h:43
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: utils.c:1601
static char* handle_softhangup ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 980 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_channel::name, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

981 {
982  struct ast_channel *c=NULL;
983 
984  switch (cmd) {
985  case CLI_INIT:
986  e->command = "channel request hangup";
987  e->usage =
988  "Usage: channel request hangup <channel>|<all>\n"
989  " Request that a channel be hung up. The hangup takes effect\n"
990  " the next time the driver reads or writes from the channel.\n"
991  " If 'all' is specified instead of a channel name, all channels\n"
992  " will see the hangup request.\n";
993  return NULL;
994  case CLI_GENERATE:
995  return ast_complete_channels(a->line, a->word, a->pos, a->n, e->args);
996  }
997 
998  if (a->argc != 4) {
999  return CLI_SHOWUSAGE;
1000  }
1001 
1002  if (!strcasecmp(a->argv[3], "all")) {
1003  struct ast_channel_iterator *iter = NULL;
1004  if (!(iter = ast_channel_iterator_all_new())) {
1005  return CLI_FAILURE;
1006  }
1007  for (; iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
1008  ast_channel_lock(c);
1009  ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name);
1011  ast_channel_unlock(c);
1012  }
1014  } else if ((c = ast_channel_get_by_name(a->argv[3]))) {
1015  ast_channel_lock(c);
1016  ast_cli(a->fd, "Requested Hangup on channel '%s'\n", c->name);
1018  ast_channel_unlock(c);
1019  c = ast_channel_unref(c);
1020  } else {
1021  ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]);
1022  }
1023 
1024  return CLI_SUCCESS;
1025 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1715
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1649
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: cli.c:1547
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1701
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
static char* handle_unload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 596 of file cli.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), AST_FORCE_FIRM, AST_FORCE_HARD, AST_FORCE_SOFT, ast_module_helper(), ast_unload_resource(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

597 {
598  /* "module unload mod_1 [mod_2 .. mod_N]" */
599  int x;
600  int force = AST_FORCE_SOFT;
601  const char *s;
602 
603  switch (cmd) {
604  case CLI_INIT:
605  e->command = "module unload";
606  e->usage =
607  "Usage: module unload [-f|-h] <module_1> [<module_2> ... ]\n"
608  " Unloads the specified module from Asterisk. The -f\n"
609  " option causes the module to be unloaded even if it is\n"
610  " in use (may cause a crash) and the -h module causes the\n"
611  " module to be unloaded even if the module says it cannot, \n"
612  " which almost always will cause a crash.\n";
613  return NULL;
614 
615  case CLI_GENERATE:
616  return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0);
617  }
618  if (a->argc < e->args + 1)
619  return CLI_SHOWUSAGE;
620  x = e->args; /* first argument */
621  s = a->argv[x];
622  if (s[0] == '-') {
623  if (s[1] == 'f')
624  force = AST_FORCE_FIRM;
625  else if (s[1] == 'h')
626  force = AST_FORCE_HARD;
627  else
628  return CLI_SHOWUSAGE;
629  if (a->argc < e->args + 2) /* need at least one module name */
630  return CLI_SHOWUSAGE;
631  x++; /* skip this argument */
632  }
633 
634  for (; x < a->argc; x++) {
635  if (ast_unload_resource(a->argv[x], force)) {
636  ast_cli(a->fd, "Unable to unload resource %s\n", a->argv[x]);
637  return CLI_FAILURE;
638  }
639  ast_cli(a->fd, "Unloaded %s\n", a->argv[x]);
640  }
641 
642  return CLI_SUCCESS;
643 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
char * ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
Match modules names for the Asterisk cli.
Definition: loader.c:626
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:551
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
static char* handle_verbose ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 389 of file cli.c.

References ast_cli_args::argc, args, ast_cli_entry::args, ast_cli_args::argv, ast_calloc, ast_clear_flag, ast_cli(), ast_complete_source_filename(), ast_free, AST_OPT_FLAG_DEBUG_MODULE, AST_OPT_FLAG_VERBOSE_MODULE, ast_options, AST_RWLIST_EMPTY, AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_set_flag, ast_strdup, ast_strdupa, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_number(), debug_modules, ast_cli_args::fd, find_module_level(), module_level::level, ast_cli_args::n, option_debug, option_verbose, ast_cli_args::pos, S_OR, ast_cli_entry::usage, and verbose_modules.

390 {
391  int oldval;
392  int newlevel;
393  unsigned int is_debug;
394  int atleast = 0;
395  int fd = a->fd;
396  int argc = a->argc;
397  const char * const *argv = a->argv;
398  const char *argv3 = a->argv ? S_OR(a->argv[3], "") : "";
399  int *dst;
400  char *what;
401  struct module_level_list *mll;
402  struct module_level *ml;
403 
404  switch (cmd) {
405  case CLI_INIT:
406  e->command = "core set {debug|verbose}";
407  e->usage =
408 #if !defined(LOW_MEMORY)
409  "Usage: core set {debug|verbose} [atleast] <level> [module]\n"
410 #else
411  "Usage: core set {debug|verbose} [atleast] <level>\n"
412 #endif
413  " core set {debug|verbose} off\n"
414 #if !defined(LOW_MEMORY)
415  " Sets level of debug or verbose messages to be displayed or\n"
416  " sets a module name to display debug messages from.\n"
417 #else
418  " Sets level of debug or verbose messages to be displayed.\n"
419 #endif
420  " 0 or off means no messages should be displayed.\n"
421  " Equivalent to -d[d[...]] or -v[v[v...]] on startup\n";
422  return NULL;
423 
424  case CLI_GENERATE:
425  if (a->pos == 3 || (a->pos == 4 && !strcasecmp(a->argv[3], "atleast"))) {
426  const char *pos = a->pos == 3 ? argv3 : S_OR(a->argv[4], "");
427  int numbermatch = (ast_strlen_zero(pos) || strchr("123456789", pos[0])) ? 0 : 21;
428  if (a->n < 21 && numbermatch == 0) {
429  return complete_number(pos, 0, 0x7fffffff, a->n);
430  } else if (pos[0] == '0') {
431  if (a->n == 0) {
432  return ast_strdup("0");
433  } else {
434  return NULL;
435  }
436  } else if (a->n == (21 - numbermatch)) {
437  if (a->pos == 3 && !strncasecmp(argv3, "off", strlen(argv3))) {
438  return ast_strdup("off");
439  } else if (a->pos == 3 && !strncasecmp(argv3, "atleast", strlen(argv3))) {
440  return ast_strdup("atleast");
441  }
442  } else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) {
443  return ast_strdup("atleast");
444  }
445 #if !defined(LOW_MEMORY)
446  } else if (a->pos == 4 || (a->pos == 5 && !strcasecmp(argv3, "atleast"))) {
447  return ast_complete_source_filename(a->pos == 4 ? S_OR(a->argv[4], "") : S_OR(a->argv[5], ""), a->n);
448 #endif
449  }
450  return NULL;
451  }
452  /* all the above return, so we proceed with the handler.
453  * we are guaranteed to be called with argc >= e->args;
454  */
455 
456  if (argc <= e->args)
457  return CLI_SHOWUSAGE;
458  if (!strcasecmp(argv[e->args - 1], "debug")) {
459  dst = &option_debug;
460  oldval = option_debug;
461  what = "Core debug";
462  is_debug = 1;
463  } else {
464  dst = &option_verbose;
465  oldval = option_verbose;
466  what = "Verbosity";
467  is_debug = 0;
468  }
469  if (argc == e->args + 1 && !strcasecmp(argv[e->args], "off")) {
470  newlevel = 0;
471 
472  mll = is_debug ? &debug_modules : &verbose_modules;
473 
474  AST_RWLIST_WRLOCK(mll);
475  while ((ml = AST_RWLIST_REMOVE_HEAD(mll, entry))) {
476  ast_free(ml);
477  }
479  AST_RWLIST_UNLOCK(mll);
480 
481  goto done;
482  }
483  if (!strcasecmp(argv[e->args], "atleast"))
484  atleast = 1;
485  if (argc != e->args + atleast + 1 && argc != e->args + atleast + 2)
486  return CLI_SHOWUSAGE;
487  if (sscanf(argv[e->args + atleast], "%30d", &newlevel) != 1)
488  return CLI_SHOWUSAGE;
489  if (argc == e->args + atleast + 2) {
490  /* We have specified a module name. */
491  char *mod = ast_strdupa(argv[e->args + atleast + 1]);
492 
493  if ((strlen(mod) > 3) && !strcasecmp(mod + strlen(mod) - 3, ".so")) {
494  mod[strlen(mod) - 3] = '\0';
495  }
496 
497  mll = is_debug ? &debug_modules : &verbose_modules;
498 
499  AST_RWLIST_WRLOCK(mll);
500 
501  ml = find_module_level(mod, is_debug);
502  if (!newlevel) {
503  if (!ml) {
504  /* Specified off for a nonexistent entry. */
505  AST_RWLIST_UNLOCK(mll);
506  return CLI_SUCCESS;
507  }
508  AST_RWLIST_REMOVE(mll, ml, entry);
509  if (AST_RWLIST_EMPTY(mll))
511  AST_RWLIST_UNLOCK(mll);
512  ast_cli(fd, "%s was %u and has been set to 0 for '%s'\n", what, ml->level, mod);
513  ast_free(ml);
514  return CLI_SUCCESS;
515  }
516 
517  if (ml) {
518  if ((atleast && newlevel < ml->level) || ml->level == newlevel) {
519  ast_cli(fd, "%s is %u for '%s'\n", what, ml->level, mod);
520  AST_RWLIST_UNLOCK(mll);
521  return CLI_SUCCESS;
522  }
523  oldval = ml->level;
524  ml->level = newlevel;
525  } else {
526  ml = ast_calloc(1, sizeof(*ml) + strlen(mod) + 1);
527  if (!ml) {
528  AST_RWLIST_UNLOCK(mll);
529  return CLI_FAILURE;
530  }
531  oldval = ml->level;
532  ml->level = newlevel;
533  strcpy(ml->module, mod);
534  AST_RWLIST_INSERT_TAIL(mll, ml, entry);
535  }
536 
538 
539  AST_RWLIST_UNLOCK(mll);
540 
541  ast_cli(fd, "%s was %d and has been set to %u for '%s'\n", what, oldval, ml->level, ml->module);
542 
543  return CLI_SUCCESS;
544  } else if (!newlevel) {
545  /* Specified level as 0 instead of off. */
546  mll = is_debug ? &debug_modules : &verbose_modules;
547 
548  AST_RWLIST_WRLOCK(mll);
549  while ((ml = AST_RWLIST_REMOVE_HEAD(mll, entry))) {
550  ast_free(ml);
551  }
553  AST_RWLIST_UNLOCK(mll);
554  }
555 
556 done:
557  if (!atleast || newlevel > *dst)
558  *dst = newlevel;
559  if (oldval > 0 && *dst == 0)
560  ast_cli(fd, "%s is now OFF\n", what);
561  else if (*dst > 0) {
562  if (oldval == *dst)
563  ast_cli(fd, "%s is at least %d\n", what, *dst);
564  else
565  ast_cli(fd, "%s was %d and is now %d\n", what, oldval, *dst);
566  }
567 
568  return CLI_SUCCESS;
569 }
#define ast_strdup(a)
Definition: astmm.h:109
unsigned int level
Definition: cli.c:88
int option_debug
Definition: asterisk.c:182
#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:154
static char * complete_number(const char *partial, unsigned int min, unsigned int max, int n)
Definition: cli.c:349
char * ast_complete_source_filename(const char *partial, int n)
Definition: asterisk.c:357
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
int option_verbose
Definition: asterisk.c:181
static struct module_level_list debug_modules
Definition: cli.c:96
map a debug or verbose level to a module name
Definition: cli.c:87
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const int n
Definition: cli.h:159
static struct module_level * find_module_level(const char *module, unsigned int debug)
Find the debug or verbose file setting.
Definition: cli.c:336
const char *const * argv
Definition: cli.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
static struct @350 args
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define CLI_FAILURE
Definition: cli.h:45
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:829
#define ast_clear_flag(p, flag)
Definition: utils.h:77
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
struct ast_flags ast_options
Definition: asterisk.c:178
#define ast_calloc(a, b)
Definition: astmm.h:82
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const int pos
Definition: cli.h:158
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:870
static struct module_level_list verbose_modules
Definition: cli.c:98
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 2191 of file cli.c.

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

Referenced by handle_help().

2192 {
2193  char matchstr[80] = "";
2194  struct ast_cli_entry *e = NULL;
2195  int len = 0;
2196  int found = 0;
2197 
2198  if (match) {
2199  ast_join(matchstr, sizeof(matchstr), match);
2200  len = strlen(matchstr);
2201  }
2202  if (!locked)
2204  while ( (e = cli_next(e)) ) {
2205  /* Hide commands that start with '_' */
2206  if (e->_full_cmd[0] == '_')
2207  continue;
2208  if (match && strncasecmp(matchstr, e->_full_cmd, len))
2209  continue;
2210  ast_cli(fd, "%30.30s %s\n", e->_full_cmd, S_OR(e->summary, "<no description available>"));
2211  found++;
2212  }
2213  if (!locked)
2215  if (!found && matchstr[0])
2216  ast_cli(fd, "No such command '%s'.\n", matchstr);
2217  return CLI_SUCCESS;
2218 }
char * _full_cmd
Definition: cli.h:175
descriptor for a cli entry.
Definition: cli.h:165
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#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)
static struct ast_cli_entry * cli_next(struct ast_cli_entry *e)
Definition: cli.c:712
void ast_join(char *s, size_t len, const char *const w[])
Definition: utils.c:1690
#define CLI_SUCCESS
Definition: cli.h:43
const char *const summary
Definition: cli.h:170
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
Definition: cli.c:225
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2069
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 1936 of file cli.c.

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

Referenced by __ast_cli_generator().

1938 {
1939  int lw;
1940  char *s, *t1;
1941 
1942  *actual = 0;
1943  if (ast_strlen_zero(token))
1944  return NULL;
1945  if (ast_strlen_zero(word))
1946  word = ""; /* dummy */
1947  lw = strlen(word);
1948  if (strcspn(word, cli_rsvd) != lw)
1949  return NULL; /* no match if word has reserved chars */
1950  if (strchr(cli_rsvd, token[0]) == NULL) { /* regular match */
1951  if (strncasecmp(token, word, lw)) /* no match */
1952  return NULL;
1953  *actual = 1;
1954  return (pos != 0) ? NULL : ast_strdup(token);
1955  }
1956  /* now handle regexp match */
1957 
1958  /* Wildcard always matches, so we never do is_prefix on them */
1959 
1960  t1 = ast_strdupa(token + 1); /* copy, skipping first char */
1961  while (pos >= 0 && (s = strsep(&t1, cli_rsvd)) && *s) {
1962  if (*s == '%') /* wildcard */
1963  continue;
1964  if (strncasecmp(s, word, lw)) /* no match */
1965  continue;
1966  (*actual)++;
1967  if (pos-- == 0)
1968  return ast_strdup(s);
1969  }
1970  return NULL;
1971 }
char * strsep(char **str, const char *delims)
#define ast_strdup(a)
Definition: astmm.h:109
Definition: ael.tab.c:203
static const char cli_rsvd[]
Definition: cli.c:1711
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static uint16_t t1
Definition: res_pktccops.c:159
static int modlist_modentry ( const char *  module,
const char *  description,
int  usecnt,
const char *  like 
)
static

Definition at line 651 of file cli.c.

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

Referenced by handle_modlist().

652 {
653  /* Comparing the like with the module */
654  if (strcasestr(module, like) ) {
656  return 1;
657  }
658  return 0;
659 }
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define MODLIST_FORMAT
Definition: cli.c:645
static int climodentryfd
Definition: cli.c:649
struct module * module
Definition: cli.h:174
char * strcasestr(const char *, const char *)
static int usecnt
Definition: chan_unistim.c:236
static int more_words ( const char *const *  dst)
static

returns true if there are more words to match

Definition at line 2429 of file cli.c.

Referenced by __ast_cli_generator().

2430 {
2431  int i;
2432  for (i = 0; dst[i]; i++) {
2433  if (dst[i][0] != '[')
2434  return -1;
2435  }
2436  return 0;
2437 }
static char* parse_args ( const char *  s,
int *  argc,
const char *  argv[],
int  max,
int *  trailingwhitespace 
)
static

Definition at line 2266 of file cli.c.

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

Referenced by __ast_cli_generator(), and ast_cli_command_full().

2267 {
2268  char *duplicate, *cur;
2269  int x = 0;
2270  int quoted = 0;
2271  int escaped = 0;
2272  int whitespace = 1;
2273  int dummy = 0;
2274 
2275  if (trailingwhitespace == NULL)
2276  trailingwhitespace = &dummy;
2277  *trailingwhitespace = 0;
2278  if (s == NULL) /* invalid, though! */
2279  return NULL;
2280  /* make a copy to store the parsed string */
2281  if (!(duplicate = ast_strdup(s)))
2282  return NULL;
2283 
2284  cur = duplicate;
2285 
2286  /* Remove leading spaces from the command */
2287  while (isspace(*s)) {
2288  cur++;
2289  s++;
2290  }
2291 
2292  /* scan the original string copying into cur when needed */
2293  for (; *s ; s++) {
2294  if (x >= max - 1) {
2295  ast_log(LOG_WARNING, "Too many arguments, truncating at %s\n", s);
2296  break;
2297  }
2298  if (*s == '"' && !escaped) {
2299  quoted = !quoted;
2300  if (quoted && whitespace) {
2301  /* start a quoted string from previous whitespace: new argument */
2302  argv[x++] = cur;
2303  whitespace = 0;
2304  }
2305  } else if ((*s == ' ' || *s == '\t') && !(quoted || escaped)) {
2306  /* If we are not already in whitespace, and not in a quoted string or
2307  processing an escape sequence, and just entered whitespace, then
2308  finalize the previous argument and remember that we are in whitespace
2309  */
2310  if (!whitespace) {
2311  *cur++ = '\0';
2312  whitespace = 1;
2313  }
2314  } else if (*s == '\\' && !escaped) {
2315  escaped = 1;
2316  } else {
2317  if (whitespace) {
2318  /* we leave whitespace, and are not quoted. So it's a new argument */
2319  argv[x++] = cur;
2320  whitespace = 0;
2321  }
2322  *cur++ = *s;
2323  escaped = 0;
2324  }
2325  }
2326  /* Null terminate */
2327  *cur++ = '\0';
2328  /* XXX put a NULL in the last argument, because some functions that take
2329  * the array may want a null-terminated array.
2330  * argc still reflects the number of non-NULL entries.
2331  */
2332  argv[x] = NULL;
2333  *argc = x;
2334  *trailingwhitespace = whitespace;
2335  return duplicate;
2336 }
#define ast_strdup(a)
Definition: astmm.h:109
#define LOG_WARNING
Definition: logger.h:144
static void dummy(char *unused,...)
Definition: chan_unistim.c:188
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void print_uptimestr ( int  fd,
struct timeval  timeval,
const char *  prefix,
int  printsec 
)
static

Definition at line 661 of file cli.c.

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

Referenced by handle_showcalls(), and handle_showuptime().

662 {
663  int x; /* the main part - years, weeks, etc. */
664  struct ast_str *out;
665 
666 #define SECOND (1)
667 #define MINUTE (SECOND*60)
668 #define HOUR (MINUTE*60)
669 #define DAY (HOUR*24)
670 #define WEEK (DAY*7)
671 #define YEAR (DAY*365)
672 #define NEEDCOMMA(x) ((x)? ",": "") /* define if we need a comma */
673  if (timeval.tv_sec < 0) /* invalid, nothing to show */
674  return;
675 
676  if (printsec) { /* plain seconds output */
677  ast_cli(fd, "%s: %lu\n", prefix, (u_long)timeval.tv_sec);
678  return;
679  }
680  out = ast_str_alloca(256);
681  if (timeval.tv_sec > YEAR) {
682  x = (timeval.tv_sec / YEAR);
683  timeval.tv_sec -= (x * YEAR);
684  ast_str_append(&out, 0, "%d year%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
685  }
686  if (timeval.tv_sec > WEEK) {
687  x = (timeval.tv_sec / WEEK);
688  timeval.tv_sec -= (x * WEEK);
689  ast_str_append(&out, 0, "%d week%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
690  }
691  if (timeval.tv_sec > DAY) {
692  x = (timeval.tv_sec / DAY);
693  timeval.tv_sec -= (x * DAY);
694  ast_str_append(&out, 0, "%d day%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
695  }
696  if (timeval.tv_sec > HOUR) {
697  x = (timeval.tv_sec / HOUR);
698  timeval.tv_sec -= (x * HOUR);
699  ast_str_append(&out, 0, "%d hour%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
700  }
701  if (timeval.tv_sec > MINUTE) {
702  x = (timeval.tv_sec / MINUTE);
703  timeval.tv_sec -= (x * MINUTE);
704  ast_str_append(&out, 0, "%d minute%s%s ", x, ESS(x),NEEDCOMMA(timeval.tv_sec));
705  }
706  x = timeval.tv_sec;
707  if (x > 0 || ast_str_strlen(out) == 0) /* if there is nothing, print 0 seconds */
708  ast_str_append(&out, 0, "%d second%s ", x, ESS(x));
709  ast_cli(fd, "%s: %s\n", prefix, ast_str_buffer(out));
710 }
#define NEEDCOMMA(x)
#define MINUTE
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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:900
#define ast_str_alloca(init_len)
Definition: strings.h:608
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define HOUR
#define WEEK
#define DAY
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define ESS(x)
Definition: cli.h:58
#define YEAR
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
static char prefix[MAX_PREFIX]
Definition: http.c:107
static int set_full_cmd ( struct ast_cli_entry e)
static

initialize the _full_cmd string and related parameters, return 0 on success, -1 on error.

Definition at line 1717 of file cli.c.

References ast_cli_entry::_full_cmd, ast_cli_entry::args, ast_join(), ast_log(), ast_strdup, ast_cli_entry::cmda, ast_cli_entry::cmdlen, and LOG_WARNING.

Referenced by __ast_cli_register().

1718 {
1719  int i;
1720  char buf[80];
1721 
1722  ast_join(buf, sizeof(buf), e->cmda);
1723  e->_full_cmd = ast_strdup(buf);
1724  if (!e->_full_cmd) {
1725  ast_log(LOG_WARNING, "-- cannot allocate <%s>\n", buf);
1726  return -1;
1727  }
1728  e->cmdlen = strcspn(e->_full_cmd, cli_rsvd);
1729  for (i = 0; e->cmda[i]; i++)
1730  ;
1731  e->args = i;
1732  return 0;
1733 }
char * _full_cmd
Definition: cli.h:175
int cmdlen
Definition: cli.h:176
#define ast_strdup(a)
Definition: astmm.h:109
#define LOG_WARNING
Definition: logger.h:144
int args
This gets set in ast_cli_register()
Definition: cli.h:179
static const char cli_rsvd[]
Definition: cli.c:1711
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_join(char *s, size_t len, const char *const w[])
Definition: utils.c:1690
const char *const cmda[AST_MAX_CMD_LEN]
Definition: cli.h:166
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 1897 of file cli.c.

References ast_strlen_zero(), and strcasestr().

Referenced by __ast_cli_generator(), and find_cli().

1898 {
1899  int l;
1900  char *pos;
1901 
1902  if (ast_strlen_zero(cmd) || ast_strlen_zero(cli_word))
1903  return -1;
1904  if (!strchr(cli_rsvd, cli_word[0])) /* normal match */
1905  return (strcasecmp(cmd, cli_word) == 0) ? 1 : -1;
1906  l = strlen(cmd);
1907  /* wildcard match - will extend in the future */
1908  if (l > 0 && cli_word[0] == '%') {
1909  return 1; /* wildcard */
1910  }
1911 
1912  /* Start a search for the command entered against the cli word in question */
1913  pos = strcasestr(cli_word, cmd);
1914  while (pos) {
1915 
1916  /*
1917  *Check if the word matched with is surrounded by reserved characters on both sides
1918  * and isn't at the beginning of the cli_word since that would make it check in a location we shouldn't know about.
1919  * If it is surrounded by reserved chars and isn't at the beginning, it's a match.
1920  */
1921  if (pos != cli_word && strchr(cli_rsvd, pos[-1]) && strchr(cli_rsvd, pos[l])) {
1922  return 1; /* valid match */
1923  }
1924 
1925  /* Ok, that one didn't match, strcasestr to the next appearance of the command and start over.*/
1926  pos = strcasestr(pos + 1, cmd);
1927  }
1928  /* If no matches were found over the course of the while loop, we hit the end of the string. It's a mismatch. */
1929  return -1;
1930 }
static const char cli_rsvd[]
Definition: cli.c:1711
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * strcasestr(const char *, const char *)

Variable Documentation

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

Definition at line 100 of file cli.c.

struct ast_cli_entry cli_cli[]
static

Definition at line 1661 of file cli.c.

int cli_default_perm = 1
static

Default permissions value 1=Permit 0=Deny.

Definition at line 76 of file cli.c.

Referenced by cli_has_permissions().

struct cli_perms cli_perms = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
const char cli_rsvd[] = "[]{}|*%"
static

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

Definition at line 1711 of file cli.c.

int climodentryfd = -1
static

Definition at line 649 of file cli.c.

ast_mutex_t climodentrylock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 648 of file cli.c.

Referenced by handle_modlist().

struct module_level_list debug_modules = AST_RWLIST_HEAD_INIT_VALUE
static

list of module names and their debug levels

Definition at line 96 of file cli.c.

Referenced by ast_debug_get_by_module(), find_module_level(), and handle_verbose().

struct helpers helpers = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
const char perms_config[] = "cli_permissions.conf"
static

CLI permissions config file.

Definition at line 74 of file cli.c.

Referenced by ast_cli_perms_init().

ast_mutex_t permsconfiglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

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

Definition at line 80 of file cli.c.

struct module_level_list verbose_modules = AST_RWLIST_HEAD_INIT_VALUE
static

list of module names and their verbose levels

Definition at line 98 of file cli.c.

Referenced by ast_verbose_get_by_module(), find_module_level(), and handle_verbose().