Sat Mar 10 01:54:14 2012

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

Generated on Sat Mar 10 01:54:15 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7