Thu Apr 28 2011 17:13:33

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