![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
cli.h
Go to the documentation of this file.
00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 1999 - 2005, Digium, Inc. 00005 * 00006 * Mark Spencer <markster@digium.com> 00007 * 00008 * See http://www.asterisk.org for more information about 00009 * the Asterisk project. Please do not directly contact 00010 * any of the maintainers of this project for assistance; 00011 * the project provides a web site, mailing lists and IRC 00012 * channels for your use. 00013 * 00014 * This program is free software, distributed under the terms of 00015 * the GNU General Public License Version 2. See the LICENSE file 00016 * at the top of the source tree. 00017 */ 00018 00019 /*! \file 00020 * \brief Standard Command Line Interface 00021 */ 00022 00023 #ifndef _ASTERISK_CLI_H 00024 #define _ASTERISK_CLI_H 00025 00026 #if defined(__cplusplus) || defined(c_plusplus) 00027 extern "C" { 00028 #endif 00029 00030 #include <stdarg.h> 00031 00032 #include "asterisk/linkedlists.h" 00033 00034 void ast_cli(int fd, char *fmt, ...) 00035 __attribute__ ((format (printf, 2, 3))); 00036 00037 #define RESULT_SUCCESS 0 00038 #define RESULT_SHOWUSAGE 1 00039 #define RESULT_FAILURE 2 00040 00041 #define CLI_SUCCESS (char *)RESULT_SUCCESS 00042 #define CLI_SHOWUSAGE (char *)RESULT_SHOWUSAGE 00043 #define CLI_FAILURE (char *)RESULT_FAILURE 00044 00045 #define AST_MAX_CMD_LEN 16 00046 00047 #define AST_MAX_ARGS 64 00048 00049 #define AST_CLI_COMPLETE_EOF "_EOF_" 00050 00051 /*! 00052 * In many cases we need to print singular or plural 00053 * words depending on a count. This macro helps us e.g. 00054 * printf("we have %d object%s", n, ESS(n)); 00055 */ 00056 #define ESS(x) ((x) == 1 ? "" : "s") 00057 00058 /*! \page CLI_command_api CLI command API 00059 00060 CLI commands are described by a struct ast_cli_entry that contains 00061 all the components for their implementation. 00062 00063 In the "old-style" format, the record must contain: 00064 - a NULL-terminated array of words constituting the command, e.g. 00065 { "set", "debug", "on", NULL }, 00066 - a summary string (short) and a usage string (longer); 00067 - a handler which implements the command itself, invoked with 00068 a file descriptor and argc/argv as typed by the user 00069 - a 'generator' function which, given a partial string, can 00070 generate legal completions for it. 00071 An example is 00072 00073 int old_setdebug(int fd, int argc, char *argv[]); 00074 char *dbg_complete(const char *line, const char *word, int pos, int n); 00075 00076 { { "set", "debug", "on", NULL }, do_setdebug, "Enable debugging", 00077 set_debug_usage, dbg_complete }, 00078 00079 In the "new-style" format, all the above functionalities are implemented 00080 by a single function, and the arguments tell which output is required. 00081 The prototype is the following: 00082 00083 char *new_setdebug(const struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); 00084 00085 ... 00086 // this is how we create the entry to register 00087 NEW_CLI(new_setdebug, "short description") 00088 ... 00089 00090 To help the transition, we make the pointer to the struct ast_cli_entry 00091 available to old-style handlers via argv[-1]. 00092 00093 An example of new-style handler is the following 00094 00095 \code 00096 static char *test_new_cli(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) 00097 { 00098 static char *choices = { "one", "two", "three", NULL }; 00099 00100 switch (cmd) { 00101 case CLI_INIT: 00102 e->command = "do this well"; 00103 e->usage = 00104 "Usage: do this well <arg>\n" 00105 " typically multiline with body indented\n"; 00106 return NULL; 00107 00108 case CLI_GENERATE: 00109 if (a->pos > e->args) 00110 return NULL; 00111 return ast_cli_complete(a->word, choices, a->n); 00112 00113 default: 00114 // we are guaranteed to be called with argc >= e->args; 00115 if (a->argc > e->args + 1) // we accept one extra argument 00116 return CLI_SHOWUSAGE; 00117 ast_cli(a->fd, "done this well for %s\n", e->args[argc-1]); 00118 return CLI_SUCCESS; 00119 } 00120 } 00121 00122 \endcode 00123 00124 */ 00125 00126 /*! \brief calling arguments for new-style handlers 00127 See \ref CLI_command_API 00128 */ 00129 enum ast_cli_fn { 00130 CLI_INIT = -2, /* return the usage string */ 00131 CLI_GENERATE = -3, /* behave as 'generator', remap argv to struct ast_cli_args */ 00132 CLI_HANDLER = -4, /* run the normal handler */ 00133 }; 00134 00135 /* argument for new-style CLI handler */ 00136 struct ast_cli_args { 00137 int fd; 00138 int argc; 00139 char **argv; 00140 const char *line; /* the current input line */ 00141 const char *word; /* the word we want to complete */ 00142 int pos; /* position of the word to complete */ 00143 int n; /* the iteration count (n-th entry we generate) */ 00144 }; 00145 00146 struct ast_cli_entry; 00147 typedef int (*old_cli_fn)(int fd, int argc, char *argv[]); 00148 typedef char *(*new_cli_fn)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); 00149 00150 /*! \brief descriptor for a cli entry 00151 See \ref CLI_command_API 00152 */ 00153 struct ast_cli_entry { 00154 char * const cmda[AST_MAX_CMD_LEN]; /*!< words making up the command. 00155 * set the first entry to NULL for a new-style entry. */ 00156 00157 /*! Handler for the command (fd for output, # of args, argument list). 00158 Returns RESULT_SHOWUSAGE for improper arguments. 00159 argv[] has argc 'useful' entries, and an additional NULL entry 00160 at the end so that clients requiring NULL terminated arrays 00161 can use it without need for copies. 00162 You can overwrite argv or the strings it points to, but remember 00163 that this memory is deallocated after the handler returns. 00164 */ 00165 old_cli_fn handler; 00166 00167 const char *summary; /*!< Summary of the command (< 60 characters) */ 00168 const char *usage; /*!< Detailed usage information */ 00169 00170 /*! Generate the n-th (starting from 0) possible completion 00171 for a given 'word' following 'line' in position 'pos'. 00172 'line' and 'word' must not be modified. 00173 Must return a malloc'ed string with the n-th value when available, 00174 or NULL if the n-th completion does not exist. 00175 Typically, the function is called with increasing values for n 00176 until a NULL is returned. 00177 */ 00178 char *(*generator)(const char *line, const char *word, int pos, int n); 00179 struct ast_cli_entry *deprecate_cmd; 00180 00181 int inuse; /*!< For keeping track of usage */ 00182 struct module *module; /*!< module this belongs to */ 00183 char *_full_cmd; /*!< built at load time from cmda[] */ 00184 int cmdlen; /*!< len up to the first invalid char [<{% */ 00185 /*! \brief This gets set in ast_cli_register() 00186 It then gets set to something different when the deprecated command 00187 is run for the first time (ie; after we warn the user that it's deprecated) 00188 */ 00189 int args; /*!< number of non-null entries in cmda */ 00190 char *command; /*!< command, non-null for new-style entries */ 00191 int deprecated; 00192 new_cli_fn new_handler; 00193 char *_deprecated_by; /*!< copied from the "parent" _full_cmd, on deprecated commands */ 00194 /*! For linking */ 00195 AST_LIST_ENTRY(ast_cli_entry) list; 00196 }; 00197 00198 /* XXX the parser in gcc 2.95 gets confused if you don't put a space 00199 * between the last arg before VA_ARGS and the comma */ 00200 #define NEW_CLI(fn, txt , ... ) { .new_handler = fn, .summary = txt, ## __VA_ARGS__ } 00201 00202 /*! 00203 * Helper function to generate cli entries from a NULL-terminated array. 00204 * Returns the n-th matching entry from the array, or NULL if not found. 00205 * Can be used to implement generate() for static entries as below 00206 * (in this example we complete the word in position 2): 00207 \code 00208 char *my_generate(const char *line, const char *word, int pos, int n) 00209 { 00210 static char *choices = { "one", "two", "three", NULL }; 00211 if (pos == 2) 00212 return ast_cli_complete(word, choices, n); 00213 else 00214 return NULL; 00215 } 00216 \endcode 00217 */ 00218 char *ast_cli_complete(const char *word, char *const choices[], int pos); 00219 00220 /*! \brief Interprets a command 00221 * Interpret a command s, sending output to fd 00222 * Returns 0 on succes, -1 on failure 00223 */ 00224 int ast_cli_command(int fd, const char *s); 00225 00226 /*! \brief Registers a command or an array of commands 00227 * \param e which cli entry to register 00228 * Register your own command 00229 * Returns 0 on success, -1 on failure 00230 */ 00231 int ast_cli_register(struct ast_cli_entry *e); 00232 00233 /*! 00234 * \brief Register multiple commands 00235 * \param e pointer to first cli entry to register 00236 * \param len number of entries to register 00237 */ 00238 void ast_cli_register_multiple(struct ast_cli_entry *e, int len); 00239 00240 /*! \brief Unregisters a command or an array of commands 00241 * 00242 * \param e which cli entry to unregister 00243 * Unregister your own command. You must pass a completed ast_cli_entry structure 00244 * Returns 0. 00245 */ 00246 int ast_cli_unregister(struct ast_cli_entry *e); 00247 00248 /*! 00249 * \brief Unregister multiple commands 00250 * \param e pointer to first cli entry to unregister 00251 * \param len number of entries to unregister 00252 */ 00253 void ast_cli_unregister_multiple(struct ast_cli_entry *e, int len); 00254 00255 /*! \brief Readline madness 00256 * Useful for readline, that's about it 00257 * Returns 0 on success, -1 on failure 00258 */ 00259 char *ast_cli_generator(const char *, const char *, int); 00260 00261 int ast_cli_generatornummatches(const char *, const char *); 00262 00263 /*! 00264 * \brief Generates a NULL-terminated array of strings that 00265 * 1) begin with the string in the second parameter, and 00266 * 2) are valid in a command after the string in the first parameter. 00267 * 00268 * The first entry (offset 0) of the result is the longest common substring 00269 * in the results, useful to extend the string that has been completed. 00270 * Subsequent entries are all possible values, followe by a NULL. 00271 * All strings and the array itself are malloc'ed and must be freed 00272 * by the caller. 00273 */ 00274 char **ast_cli_completion_matches(const char *, const char *); 00275 00276 /*! 00277 * \brief Command completion for the list of active channels 00278 * 00279 * This can be called from a CLI command completion function that wants to 00280 * complete from the list of active channels. 'rpos' is the required 00281 * position in the command. This function will return NULL immediately if 00282 * 'rpos' is not the same as the current position, 'pos'. 00283 */ 00284 char *ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos); 00285 00286 #if defined(__cplusplus) || defined(c_plusplus) 00287 } 00288 #endif 00289 00290 #endif /* _ASTERISK_CLI_H */