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

Generated on Thu Apr 16 06:27:30 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6