Fri Jul 24 00:40:54 2009

Asterisk developer's documentation


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

Generated on Fri Jul 24 00:40:54 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7