Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:28 2007

Asterisk developer's documentation :: Codename Pineapple


cli.c File Reference


Detailed Description

Standard Command Line Interface.

Author:
Mark Spencer <markster@digium.com>

Definition in file cli.c.

#include "asterisk.h"
#include <unistd.h>
#include <stdlib.h>
#include <sys/signal.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <ctype.h>
#include <regex.h>
#include "asterisk/logger.h"
#include "asterisk/options.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 dependency graph for cli.c:

Go to the source code of this file.

Data Structures

struct  cli_iterator

Defines

#define AST_CLI_INITLEN   256
 Initial buffer size for resulting strings in ast_cli().
#define CONCISE_FORMAT_STRING   "%s!%s!%s!%d!%s!%s!%s!%s!%s!%d!%s!%s\n"
#define DAY   (HOUR*24)
#define FORMAT_STRING   "%-25s %-20s %-20s\n"
#define FORMAT_STRING   "%-20.20s %-20.20s %-7.7s %-30.30s\n"
#define FORMAT_STRING2   "%-20.20s %-20.20s %-7.7s %-30.30s\n"
#define HOUR   (MINUTE*60)
#define MINUTE   (SECOND*60)
#define MODLIST_FORMAT   "%-30s %-40.40s %-10d\n"
#define MODLIST_FORMAT2   "%-30s %-40.40s %-10s\n"
#define NEEDCOMMA(x)   ((x)? ",": "")
#define SECOND   (1)
#define VERBOSE_FORMAT_STRING   "%-20.20s %-20.20s %-16.16s %4d %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"
#define VERBOSE_FORMAT_STRING2   "%-20.20s %-20.20s %-16.16s %-4.4s %-7.7s %-12.12s %-25.25s %-15.15s %8.8s %-11.11s %-20.20s\n"
#define WEEK   (DAY*7)
#define YEAR   (DAY*365)

Functions

static char * __ast_cli_generator (const char *text, const char *word, int state, int lock)
static int __ast_cli_register (struct ast_cli_entry *e, struct ast_cli_entry *ed)
static int __ast_cli_unregister (struct ast_cli_entry *e, struct ast_cli_entry *ed)
void ast_builtins_init (void)
 initialize the _full_cmd string in * each of the builtins.
void ast_cli (int fd, char *fmt,...)
int ast_cli_command (int fd, const char *s)
 Interprets a command Interpret a command s, sending output to fd Returns 0 on succes, -1 on failure.
char * ast_cli_complete (const char *word, char *const choices[], int state)
char ** ast_cli_completion_matches (const char *text, const char *word)
 Generates a NULL-terminated array of strings that 1) begin with the string in the second parameter, and 2) are valid in a command after the string in the first parameter.
char * ast_cli_generator (const char *text, const char *word, int state)
 Readline madness Useful for readline, that's about it Returns 0 on success, -1 on failure.
int ast_cli_generatornummatches (const char *text, const char *word)
 Return the number of unique matches for the generator.
int ast_cli_register (struct ast_cli_entry *e)
 Registers a command or an array of commands.
void ast_cli_register_multiple (struct ast_cli_entry *e, int len)
 Register multiple commands.
int ast_cli_unregister (struct ast_cli_entry *e)
 Unregisters a command or an array of commands.
void ast_cli_unregister_multiple (struct ast_cli_entry *e, int len)
 Unregister multiple commands.
char * ast_complete_channels (const char *line, const char *word, int pos, int state, int rpos)
 Command completion for the list of active channels.
static AST_LIST_HEAD_STATIC (helpers, ast_cli_entry)
 AST_MUTEX_DEFINE_STATIC (climodentrylock)
 AST_THREADSTORAGE (ast_cli_buf)
static struct ast_cli_entrycli_next (struct cli_iterator *i)
static char * complete_ch_3 (const char *line, const char *word, int pos, int state)
static char * complete_ch_4 (const char *line, const char *word, int pos, int state)
static char * complete_fn (const char *word, int state)
static char * find_best (char *argv[])
static struct ast_cli_entryfind_cli (char *const cmds[], int match_type)
 locate a cli command in the 'helpers' list (which must be locked). exact has 3 values: 0 returns if the search key is equal or longer than the entry. note that trailing optional arguments are skipped. -1 true if the mismatch is on the last word XXX not true! 1 true only on complete, exact match.
static int group_show_channels (int fd, int argc, char *argv[])
static char * handle_chanlist (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int handle_commandcomplete (int fd, int argc, char *argv[])
static int handle_commandmatchesarray (int fd, int argc, char *argv[])
static int handle_commandnummatches (int fd, int argc, char *argv[])
static char * handle_core_set_debug_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_debugchan_deprecated (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_load_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int handle_logger_mute (int fd, int argc, char *argv[])
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_reload_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int handle_showchan (int fd, int argc, char *argv[])
static char * handle_showuptime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int handle_softhangup (int fd, int argc, char *argv[])
static char * handle_unload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_unload_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_verbose (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * help1 (int fd, char *match[], int locked)
 helper for final part of handle_help. if locked = 0 it's just "help_workhorse", otherwise assume the list is already locked and print an error message if not found.
static char * is_prefix (const char *word, const char *token, int pos, int *actual)
 if word is a valid prefix for token, returns the pos-th match as a malloced string, or NULL otherwise. Always tell in *actual how many matches we got.
static int modlist_modentry (const char *module, const char *description, int usecnt, const char *like)
static int more_words (char *const *dst)
 returns true if there are more words to match
static char * parse_args (const char *s, int *argc, char *argv[], int max, int *trailingwhitespace)
static void print_uptimestr (int fd, time_t 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_cli_entry builtins []
static struct ast_cli_entry cli_cli []
static struct ast_cli_entry cli_debug_channel_deprecated = NEW_CLI(handle_debugchan_deprecated, "Enable debugging on channel")
static struct ast_cli_entry cli_module_load_deprecated = NEW_CLI(handle_load_deprecated, "Load a module")
static struct ast_cli_entry cli_module_reload_deprecated = NEW_CLI(handle_reload_deprecated, "reload modules by name")
static struct ast_cli_entry cli_module_unload_deprecated = NEW_CLI(handle_unload_deprecated, "unload modules by name")
static const char cli_rsvd [] = "[]{}|*%"
static int climodentryfd = -1
static const char commandcomplete_help []
static const char commandmatchesarray_help []
static const char commandnummatches_help []
static const char group_show_channels_help []
static const char logger_mute_help []
static const char showchan_help []
static const char softhangup_help []


Define Documentation

#define AST_CLI_INITLEN   256
 

Initial buffer size for resulting strings in ast_cli().

Definition at line 55 of file cli.c.

Referenced by ast_cli().

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

Referenced by handle_chanlist().

#define DAY   (HOUR*24)
 

Referenced by print_uptimestr().

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

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

Referenced by group_show_channels(), and handle_chanlist().

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

Referenced by handle_chanlist().

#define HOUR   (MINUTE*60)
 

Referenced by print_uptimestr().

#define MINUTE   (SECOND*60)
 

Referenced by print_uptimestr().

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

Definition at line 314 of file cli.c.

Referenced by modlist_modentry().

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

Definition at line 315 of file cli.c.

Referenced by handle_modlist().

#define NEEDCOMMA  )     ((x)? ",": "")
 

Referenced by print_uptimestr().

#define SECOND   (1)
 

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

Referenced by handle_chanlist().

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

Referenced by handle_chanlist().

#define WEEK   (DAY*7)
 

Referenced by print_uptimestr().

#define YEAR   (DAY*365)
 

Referenced by print_uptimestr().


Function Documentation

static char * __ast_cli_generator const char *  text,
const char *  word,
int  state,
int  lock
[static]
 

Definition at line 1596 of file cli.c.

References ast_join(), AST_LIST_LOCK, AST_MAX_ARGS, ast_strlen_zero(), cli_next(), ast_cli_entry::cmda, free, cli_iterator::helpers, is_prefix(), more_words(), parse_args(), and word_match().

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

01597 {
01598    char *argv[AST_MAX_ARGS];
01599    struct ast_cli_entry *e;
01600    struct cli_iterator i = { NULL, NULL };
01601    int x = 0, argindex, matchlen;
01602    int matchnum=0;
01603    char *ret = NULL;
01604    char matchstr[80] = "";
01605    int tws = 0;
01606    /* Split the argument into an array of words */
01607    char *dup = parse_args(text, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws);
01608 
01609    if (!dup)   /* malloc error */
01610       return NULL;
01611 
01612    /* Compute the index of the last argument (could be an empty string) */
01613    argindex = (!ast_strlen_zero(word) && x>0) ? x-1 : x;
01614 
01615    /* rebuild the command, ignore terminating white space and flatten space */
01616    ast_join(matchstr, sizeof(matchstr)-1, argv);
01617    matchlen = strlen(matchstr);
01618    if (tws) {
01619       strcat(matchstr, " "); /* XXX */
01620       if (matchlen)
01621          matchlen++;
01622    }
01623    if (lock)
01624       AST_LIST_LOCK(&helpers);
01625    while ( (e = cli_next(&i)) ) {
01626       /* XXX repeated code */
01627       int src = 0, dst = 0, n = 0;
01628 
01629       /*
01630        * Try to match words, up to and excluding the last word, which
01631        * is either a blank or something that we want to extend.
01632        */
01633       for (;src < argindex; dst++, src += n) {
01634          n = word_match(argv[src], e->cmda[dst]);
01635          if (n < 0)
01636             break;
01637       }
01638 
01639       if (src != argindex && more_words(e->cmda + dst))  /* not a match */
01640          continue;
01641       ret = is_prefix(argv[src], e->cmda[dst], state - matchnum, &n);
01642       matchnum += n; /* this many matches here */
01643       if (ret) {
01644          /*
01645           * argv[src] is a valid prefix of the next word in this
01646           * command. If this is also the correct entry, return it.
01647           */
01648          if (matchnum > state)
01649             break;
01650          free(ret);
01651          ret = NULL;
01652       } else if (ast_strlen_zero(e->cmda[dst])) {
01653          /*
01654           * This entry is a prefix of the command string entered
01655           * (only one entry in the list should have this property).
01656           * Run the generator if one is available. In any case we are done.
01657           */
01658          if (e->generator)
01659             ret = e->generator(matchstr, word, argindex, state - matchnum);
01660          else if (e->new_handler) { /* new style command */
01661             struct ast_cli_args a = {
01662                .line = matchstr, .word = word,
01663                .pos = argindex,
01664                .n = state - matchnum };
01665             ret = e->new_handler(e, CLI_GENERATE, &a);
01666          }
01667          if (ret)
01668             break;
01669       }
01670    }
01671    if (lock)
01672       AST_LIST_UNLOCK(&helpers);
01673    free(dup);
01674    return ret;
01675 }

static int __ast_cli_register struct ast_cli_entry e,
struct ast_cli_entry ed
[static]
 

Definition at line 1266 of file cli.c.

References AST_MAX_CMD_LEN, ast_strdup, ast_strlen_zero(), CLI_INIT, ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::handler, ast_cli_entry::new_handler, and s.

Referenced by ast_cli_register().

01267 {
01268    struct ast_cli_entry *cur;
01269    int i, lf, ret = -1;
01270 
01271    if (e->handler == NULL) {  /* new style entry, run the handler to init fields */
01272       struct ast_cli_args a;  /* fake argument */
01273       char **dst = (char **)e->cmda;   /* need to cast as the entry is readonly */
01274       char *s;
01275 
01276       bzero (&a, sizeof(a));
01277       e->new_handler(e, CLI_INIT, &a);
01278       /* XXX check that usage and command are filled up */
01279       s = ast_skip_blanks(e->command);
01280       s = e->command = ast_strdup(s);
01281       for (i=0; !ast_strlen_zero(s) && i < AST_MAX_CMD_LEN-1; i++) {
01282          *dst++ = s; /* store string */
01283          s = ast_skip_nonblanks(s);
01284          if (*s == '\0')   /* we are done */
01285             break;
01286          *s++ = '\0';
01287          s = ast_skip_blanks(s);
01288       }
01289       *dst++ = NULL;
01290    }
01291    if (set_full_cmd(e))
01292       goto done;
01293    AST_LIST_LOCK(&helpers);
01294    
01295    if (find_cli(e->cmda, 1)) {
01296       ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", e->_full_cmd);
01297       free(e->_full_cmd);
01298       e->_full_cmd = NULL;
01299       goto done;
01300    }
01301    if (!ed) {
01302       e->deprecated = 0;
01303    } else {
01304       e->deprecated = 1;
01305       e->summary = ed->summary;
01306       e->usage = ed->usage;
01307       /* XXX If command A deprecates command B, and command B deprecates command C...
01308          Do we want to show command A or command B when telling the user to use new syntax?
01309          This currently would show command A.
01310          To show command B, you just need to always use ed->_full_cmd.
01311        */
01312       e->_deprecated_by = S_OR(ed->_deprecated_by, ed->_full_cmd);
01313    }
01314 
01315    lf = e->cmdlen;
01316    AST_LIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
01317       int len = cur->cmdlen;
01318       if (lf < len)
01319          len = lf;
01320       if (strncasecmp(e->_full_cmd, cur->_full_cmd, len) < 0) {
01321          AST_LIST_INSERT_BEFORE_CURRENT(&helpers, e, list); 
01322          break;
01323       }
01324    }
01325    AST_LIST_TRAVERSE_SAFE_END;
01326 
01327    if (!cur)
01328       AST_LIST_INSERT_TAIL(&helpers, e, list); 
01329    ret = 0; /* success */
01330 
01331 done:
01332    AST_LIST_UNLOCK(&helpers);
01333 
01334    if (e->deprecate_cmd) {
01335       /* This command deprecates another command.  Register that one also. */
01336       __ast_cli_register(e->deprecate_cmd, e);
01337    }
01338    
01339    return ret;
01340 }

static int __ast_cli_unregister struct ast_cli_entry e,
struct ast_cli_entry ed
[static]
 

Definition at line 1242 of file cli.c.

References ast_cli_entry::_full_cmd, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_cli_entry::cmda, ast_cli_entry::command, ast_cli_entry::deprecate_cmd, free, cli_iterator::helpers, ast_cli_entry::inuse, LOG_WARNING, ast_cli_entry::new_handler, and ast_cli_entry::usage.

Referenced by ast_cli_unregister().

01243 {
01244    if (e->deprecate_cmd) {
01245       __ast_cli_unregister(e->deprecate_cmd, e);
01246    }
01247    if (e->inuse) {
01248       ast_log(LOG_WARNING, "Can't remove command that is in use\n");
01249    } else {
01250       AST_LIST_LOCK(&helpers);
01251       AST_LIST_REMOVE(&helpers, e, list);
01252       AST_LIST_UNLOCK(&helpers);
01253       free(e->_full_cmd);
01254       e->_full_cmd = NULL;
01255       if (e->new_handler) {
01256          /* this is a new-style entry. Reset fields and free memory. */
01257          bzero((char **)(e->cmda), sizeof(e->cmda));
01258          free(e->command);
01259          e->command = NULL;
01260          e->usage = NULL;
01261       }
01262    }
01263    return 0;
01264 }

void ast_builtins_init void   ) 
 

initialize the _full_cmd string in * each of the builtins.

Provided by cli.c

Definition at line 1046 of file cli.c.

References ast_cli_register_multiple(), builtins, cli_cli, ast_cli_entry::cmda, and set_full_cmd().

01047 {
01048    struct ast_cli_entry *e;
01049 
01050    for (e = builtins; e->cmda[0] != NULL; e++)
01051       set_full_cmd(e);
01052 
01053    ast_cli_register_multiple(cli_cli, sizeof(cli_cli) / sizeof(struct ast_cli_entry));
01054 }

void ast_cli int  fd,
char *  fmt,
  ...
 

Definition at line 57 of file cli.c.

References ast_carefulwrite(), AST_CLI_INITLEN, ast_str_set_va, and ast_str::str.

Referenced by __iax2_show_peers(), __sip_show_channels(), _sip_show_device(), _sip_show_devices(), _sip_show_peer(), _sip_show_peers(), agent_logoff_cmd(), agents_show(), agents_show_online(), agi_do_debug(), agi_no_debug(), aji_do_reload(), aji_show_clients(), aji_test(), ast_cli_command(), ast_console_toggle_mute(), cli_audio_convert(), cli_files_show(), cli_realtime_load(), cli_realtime_update(), config_command(), console_active(), console_answer(), console_autoanswer(), console_dial(), console_flash(), console_hangup(), console_sendtext(), console_transfer(), database_del(), database_deltree(), database_get(), database_put(), database_show(), database_showkey(), do_boost(), dundi_do_debug(), dundi_do_lookup(), dundi_do_precache(), dundi_do_query(), dundi_do_store_history(), dundi_no_debug(), dundi_no_store_history(), dundi_show_entityid(), dundi_show_mappings(), dundi_show_peer(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), features_show(), group_show_channels(), gtalk_show_channels(), h323_do_debug(), h323_do_trace(), h323_no_debug(), h323_no_trace(), handle_agidumphtml(), handle_chanlist(), handle_cli_status(), handle_cli_submit(), handle_commandcomplete(), handle_commandnummatches(), handle_context_add_extension(), handle_context_add_ignorepat(), handle_context_add_include(), handle_context_remove_extension(), handle_context_remove_ignorepat(), handle_context_remove_include(), handle_core_set_debug_channel(), handle_help(), handle_load(), handle_logger_reload(), handle_logger_rotate(), handle_logger_show_channels(), handle_mandebug(), handle_modlist(), handle_parkedcalls(), handle_reload(), handle_restart_when_convenient(), handle_save_dialplan(), handle_set_global(), handle_show_application(), handle_show_applications(), handle_show_dialplan(), handle_show_function(), handle_show_functions(), handle_show_globals(), handle_show_hints(), handle_show_http(), handle_show_indications(), handle_show_switches(), handle_show_threads(), handle_show_version_files(), handle_showagi(), handle_showchan(), handle_showfeatures(), handle_showmanager(), handle_showmanagers(), handle_showmancmd(), handle_showmancmds(), handle_showmanconn(), handle_showmaneventq(), handle_shutdown_when_convenient(), handle_softhangup(), handle_unload(), handle_verbose(), handle_version(), help1(), help_workhorse(), iax2_do_debug(), iax2_do_jb_debug(), iax2_do_trunk_debug(), iax2_no_debug(), iax2_no_jb_debug(), iax2_no_trunk_debug(), iax2_prov_cmd(), iax2_prune_realtime(), iax2_set_mtu(), iax2_show_cache(), iax2_show_channels(), iax2_show_firmware(), iax2_show_netstats(), iax2_show_peer(), iax2_show_registry(), iax2_show_stats(), iax2_show_threads(), iax2_show_users(), iax_show_provisioning(), locals_show(), mgcp_audit_endpoint(), mgcp_do_debug(), mgcp_no_debug(), mgcp_show_endpoints(), misdn_reload(), misdn_send_cd(), misdn_send_digit(), misdn_send_display(), misdn_set_debug(), misdn_show_cls(), misdn_show_config(), misdn_show_port(), misdn_show_ports_stats(), misdn_show_stacks(), misdn_toggle_echocancel(), modlist_modentry(), moh_classes_show(), moh_cli(), odbc_show_command(), orig_app(), orig_exten(), print_bc_info(), print_codec_to_cli(), print_group(), print_uptimestr(), realtime_pgsql_status(), rtcp_do_debug(), rtcp_do_debug_ip(), rtcp_do_stats(), rtcp_no_debug(), rtcp_no_stats(), rtp_do_debug(), rtp_do_debug_ip(), rtp_no_debug(), show_channeltype(), show_channeltypes(), show_codec_n(), show_codecs(), show_config_description(), show_dialplan_helper(), show_file_formats(), show_image_formats(), show_keys(), show_license(), show_translation(), show_warranty(), sip_do_debug(), sip_do_debug_device(), sip_do_debug_ip(), sip_do_debug_peer(), sip_do_history(), sip_listconfighelper(), sip_listconfigs(), sip_no_debug(), sip_no_history(), sip_notify(), sip_options_print(), sip_show_channel(), sip_show_domains(), sip_show_history(), sip_show_inuse(), sip_show_objects(), sip_show_registry(), sip_show_settings(), sip_show_user(), sip_show_users(), skinny_do_debug(), skinny_no_debug(), skinny_show_devices(), skinny_show_lines(), stun_do_debug(), stun_no_debug(), udptl_do_debug(), udptl_do_debug_ip(), udptl_nodebug(), and zap_show_status().

00058 {
00059    int res;
00060    struct ast_str *buf;
00061    va_list ap;
00062 
00063    if (!(buf = ast_str_thread_get(&ast_cli_buf, AST_CLI_INITLEN)))
00064       return;
00065 
00066    va_start(ap, fmt);
00067    res = ast_str_set_va(&buf, 0, fmt, ap);
00068    va_end(ap);
00069 
00070    if (res != AST_DYNSTR_BUILD_FAILED)
00071       ast_carefulwrite(fd, buf->str, strlen(buf->str), 100);
00072 }

int ast_cli_command int  fd,
const char *  s
 

Interprets a command Interpret a command s, sending output to fd Returns 0 on succes, -1 on failure.

Definition at line 1682 of file cli.c.

References ast_cli_entry::_deprecated_by, ast_cli_entry::_full_cmd, ast_cli(), AST_LIST_LOCK, AST_LIST_UNLOCK, AST_MAX_ARGS, CLI_HANDLER, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::deprecated, ast_cli_args::fd, find_best(), find_cli(), free, ast_cli_entry::handler, ast_cli_entry::inuse, ast_cli_entry::new_handler, parse_args(), RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, S_OR, and ast_cli_entry::usage.

Referenced by action_command(), cli_activate(), consolehandler(), and exit_completely().

01683 {
01684    char *args[AST_MAX_ARGS + 1];
01685    struct ast_cli_entry *e;
01686    int x;
01687    int res;
01688    char *dup = parse_args(s, &x, args + 1, AST_MAX_ARGS, NULL);
01689 
01690    if (dup == NULL)
01691       return -1;
01692 
01693    if (x < 1)  /* We need at least one entry, otherwise ignore */
01694       goto done;
01695 
01696    AST_LIST_LOCK(&helpers);
01697    e = find_cli(args + 1, 0);
01698    if (e)
01699       ast_atomic_fetchadd_int(&e->inuse, 1);
01700    AST_LIST_UNLOCK(&helpers);
01701    if (e == NULL) {
01702       ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(args + 1));
01703       goto done;
01704    }
01705    /*
01706     * Within the handler, argv[-1] contains a pointer to the ast_cli_entry.
01707     * Remember that the array returned by parse_args is NULL-terminated.
01708     */
01709    args[0] = (char *)e;
01710 
01711    if (!e->new_handler) /* old style */
01712       res = e->handler(fd, x, args + 1);
01713    else {
01714       struct ast_cli_args a = {
01715          .fd = fd, .argc = x, .argv = args+1 };
01716       char *retval = e->new_handler(e, CLI_HANDLER, &a);
01717 
01718       if (retval == CLI_SUCCESS)
01719          res = RESULT_SUCCESS;
01720       else if (retval == CLI_SHOWUSAGE)
01721          res = RESULT_SHOWUSAGE;
01722       else
01723          res = RESULT_FAILURE;
01724    }
01725    switch (res) {
01726    case RESULT_SHOWUSAGE:
01727       ast_cli(fd, "%s", S_OR(e->usage, "Invalid usage, but no usage information available.\n"));
01728       break;
01729 
01730    case RESULT_FAILURE:
01731       ast_cli(fd, "Command '%s' failed.\n", s);
01732       /* FALLTHROUGH */
01733    default:
01734       AST_LIST_LOCK(&helpers);
01735       if (e->deprecated == 1) {
01736          ast_cli(fd, "The '%s' command is deprecated and will be removed in a future release. Please use '%s' instead.\n", e->_full_cmd, e->_deprecated_by);
01737          e->deprecated = 2;
01738       }
01739       AST_LIST_UNLOCK(&helpers);
01740       break;
01741    }
01742    ast_atomic_fetchadd_int(&e->inuse, -1);
01743 done:
01744    free(dup);
01745    return 0;
01746 }

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

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

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

Definition at line 858 of file cli.c.

References ast_strdup, ast_strlen_zero(), and len.

Referenced by complete_orig(), and complete_show_applications().

00859 {
00860    int i, which = 0, len;
00861    len = ast_strlen_zero(word) ? 0 : strlen(word);
00862 
00863    for (i = 0; choices[i]; i++) {
00864       if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state)
00865          return ast_strdup(choices[i]);
00866    }
00867    return NULL;
00868 }

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, followe by a NULL. All strings and the array itself are malloc'ed and must be freed by the caller.

Definition at line 1535 of file cli.c.

References ast_cli_generator(), and ast_realloc.

Referenced by cli_complete(), and handle_commandmatchesarray().

01536 {
01537    char **match_list = NULL, *retstr, *prevstr;
01538    size_t match_list_len, max_equal, which, i;
01539    int matches = 0;
01540 
01541    /* leave entry 0 free for the longest common substring */
01542    match_list_len = 1;
01543    while ((retstr = ast_cli_generator(text, word, matches)) != NULL) {
01544       if (matches + 1 >= match_list_len) {
01545          match_list_len <<= 1;
01546          if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(*match_list))))
01547             return NULL;
01548       }
01549       match_list[++matches] = retstr;
01550    }
01551 
01552    if (!match_list)
01553       return match_list; /* NULL */
01554 
01555    /* Find the longest substring that is common to all results
01556     * (it is a candidate for completion), and store a copy in entry 0.
01557     */
01558    prevstr = match_list[1];
01559    max_equal = strlen(prevstr);
01560    for (which = 2; which <= matches; which++) {
01561       for (i = 0; i < max_equal && toupper(prevstr[i]) == toupper(match_list[which][i]); i++)
01562          continue;
01563       max_equal = i;
01564    }
01565 
01566    if (!(retstr = ast_malloc(max_equal + 1)))
01567       return NULL;
01568    
01569    ast_copy_string(retstr, match_list[1], max_equal + 1);
01570    match_list[0] = retstr;
01571 
01572    /* ensure that the array is NULL terminated */
01573    if (matches + 1 >= match_list_len) {
01574       if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(*match_list))))
01575          return NULL;
01576    }
01577    match_list[matches + 1] = NULL;
01578 
01579    return match_list;
01580 }

char* ast_cli_generator const char *  text,
const char *  word,
int  state
 

Readline madness Useful for readline, that's about it Returns 0 on success, -1 on failure.

Definition at line 1677 of file cli.c.

References __ast_cli_generator().

Referenced by ast_cli_completion_matches(), and ast_cli_generatornummatches().

01678 {
01679    return __ast_cli_generator(text, word, state, 1);
01680 }

int ast_cli_generatornummatches const char *  text,
const char *  word
 

Return the number of unique matches for the generator.

Definition at line 1518 of file cli.c.

References ast_cli_generator(), and free.

Referenced by handle_commandnummatches().

01519 {
01520    int matches = 0, i = 0;
01521    char *buf = NULL, *oldbuf = NULL;
01522 
01523    while ((buf = ast_cli_generator(text, word, i++))) {
01524       if (!oldbuf || strcmp(buf,oldbuf))
01525          matches++;
01526       if (oldbuf)
01527          free(oldbuf);
01528       oldbuf = buf;
01529    }
01530    if (oldbuf)
01531       free(oldbuf);
01532    return matches;
01533 }

int ast_cli_register struct ast_cli_entry e  ) 
 

Registers a command or an array of commands.

Parameters:
e which cli entry to register Register your own command Returns 0 on success, -1 on failure

Definition at line 1349 of file cli.c.

References __ast_cli_register().

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

01350 {
01351    return __ast_cli_register(e, NULL);
01352 }

void ast_cli_register_multiple struct ast_cli_entry e,
int  len
 

Register multiple commands.

Parameters:
e pointer to first cli entry to register
len number of entries to register

Definition at line 1357 of file cli.c.

References ast_cli_register().

Referenced by __ast_register_translator(), ast_builtins_init(), ast_channels_init(), ast_file_init(), ast_http_init(), ast_image_init(), ast_rtp_init(), ast_udptl_init(), astdb_init(), crypto_init(), iax_provision_init(),