Switch from AST_CLI (formerly NEW_CLI) to AST_CLI_DEFINE, since the former didn't...
[asterisk/asterisk.git] / include / asterisk / cli.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  * \brief Standard Command Line Interface
21  */
22
23 #ifndef _ASTERISK_CLI_H
24 #define _ASTERISK_CLI_H
25
26 #if defined(__cplusplus) || defined(c_plusplus)
27 extern "C" {
28 #endif
29
30 #include <stdarg.h>
31
32 #include "asterisk/linkedlists.h"
33
34 void ast_cli(int fd, const char *fmt, ...)
35         __attribute__ ((format (printf, 2, 3)));
36
37 #define RESULT_SUCCESS          0
38 #define RESULT_SHOWUSAGE        1
39 #define RESULT_FAILURE          2
40
41 #define CLI_SUCCESS     (char *)RESULT_SUCCESS
42 #define CLI_SHOWUSAGE   (char *)RESULT_SHOWUSAGE
43 #define CLI_FAILURE     (char *)RESULT_FAILURE
44
45 #define AST_MAX_CMD_LEN         16
46
47 #define AST_MAX_ARGS 64
48
49 #define AST_CLI_COMPLETE_EOF    "_EOF_"
50
51 /*!
52  * In many cases we need to print singular or plural
53  * words depending on a count. This macro helps us e.g.
54  *     printf("we have %d object%s", n, ESS(n));
55  */
56 #define ESS(x) ((x) == 1 ? "" : "s")
57
58 /*! \page CLI_command_API CLI command API
59
60    CLI commands are described by a struct ast_cli_entry that contains
61    all the components for their implementation.
62
63    In the "old-style" format, the record must contain:
64    - a NULL-terminated array of words constituting the command, e.g.
65         { "set", "debug", "on", NULL },
66    - a summary string (short) and a usage string (longer);
67    - a handler which implements the command itself, invoked with
68      a file descriptor and argc/argv as typed by the user
69    - a 'generator' function which, given a partial string, can
70      generate legal completions for it.
71    An example is
72
73         int old_setdebug(int fd, int argc, char *argv[]);
74         char *dbg_complete(const char *line, const char *word, int pos, int n);
75
76         { { "set", "debug", "on", NULL }, do_setdebug, "Enable debugging",
77         set_debug_usage, dbg_complete },
78
79    In the "new-style" format, all the above functionalities are implemented
80    by a single function, and the arguments tell which output is required.
81    The prototype is the following:
82
83         char *new_setdebug(const struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
84
85         ...
86         // this is how we create the entry to register 
87         AST_CLI_DEFINE(new_setdebug, "short description")
88         ...
89
90    To help the transition, we make the pointer to the struct ast_cli_entry
91    available to old-style handlers via argv[-1].
92
93    An example of new-style handler is the following
94
95 \code
96 static char *test_new_cli(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
97 {
98         static char *choices = { "one", "two", "three", NULL };
99
100         switch (cmd) {
101         case CLI_INIT:
102                 e->command = "do this well";
103                 e->usage =
104                         "Usage: do this well <arg>\n"
105                         "       typically multiline with body indented\n";
106                 return NULL;
107
108         case CLI_GENERATE:
109                 if (a->pos > e->args)
110                         return NULL;
111                 return ast_cli_complete(a->word, choices, a->n);
112
113         default:        
114                 // we are guaranteed to be called with argc >= e->args;
115                 if (a->argc > e->args + 1) // we accept one extra argument
116                         return CLI_SHOWUSAGE;
117                 ast_cli(a->fd, "done this well for %s\n", e->args[argc-1]);
118                 return CLI_SUCCESS;
119         }
120 }
121
122 \endcode
123  
124  */
125
126 /*! \brief calling arguments for new-style handlers. 
127 * \arg \ref CLI_command_API
128 */
129 enum ast_cli_fn {
130         CLI_INIT = -2,          /* return the usage string */
131         CLI_GENERATE = -3,      /* behave as 'generator', remap argv to struct ast_cli_args */
132         CLI_HANDLER = -4,       /* run the normal handler */
133 };
134
135 /* argument for new-style CLI handler */
136 struct ast_cli_args {
137         int fd;
138         int argc;
139         char **argv;
140         const char *line;       /* the current input line */
141         const char *word;       /* the word we want to complete */
142         int pos;                /* position of the word to complete */
143         int n;                  /* the iteration count (n-th entry we generate) */
144 };
145
146 struct ast_cli_entry;
147 typedef int (*old_cli_fn)(int fd, int argc, char *argv[]);
148 typedef char *(*new_cli_fn)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
149
150 /*! \brief descriptor for a cli entry. 
151  * \arg \ref CLI_command_API
152  */
153 struct ast_cli_entry {
154         char * const cmda[AST_MAX_CMD_LEN];     /*!< words making up the command.
155                 * set the first entry to NULL for a new-style entry. */
156
157         /*! Handler for the command (fd for output, # of args, argument list).
158           Returns RESULT_SHOWUSAGE for improper arguments.
159           argv[] has argc 'useful' entries, and an additional NULL entry
160           at the end so that clients requiring NULL terminated arrays
161           can use it without need for copies.
162           You can overwrite argv or the strings it points to, but remember
163           that this memory is deallocated after the handler returns.
164          */
165         old_cli_fn handler;
166
167         const char *summary; /*!< Summary of the command (< 60 characters) */
168         const char *usage; /*!< Detailed usage information */
169
170         /*! Generate the n-th (starting from 0) possible completion
171           for a given 'word' following 'line' in position 'pos'.
172           'line' and 'word' must not be modified.
173           Must return a malloc'ed string with the n-th value when available,
174           or NULL if the n-th completion does not exist.
175           Typically, the function is called with increasing values for n
176           until a NULL is returned.
177          */
178         char *(*generator)(const char *line, const char *word, int pos, int n);
179         struct ast_cli_entry *deprecate_cmd;
180
181         int inuse; /*!< For keeping track of usage */
182         struct module *module;  /*!< module this belongs to */
183         char *_full_cmd;        /*!< built at load time from cmda[] */
184         int cmdlen;             /*!< len up to the first invalid char [<{% */
185         /*! \brief This gets set in ast_cli_register()
186           It then gets set to something different when the deprecated command
187           is run for the first time (ie; after we warn the user that it's deprecated)
188          */
189         int args;               /*!< number of non-null entries in cmda */
190         char *command;          /*!< command, non-null for new-style entries */
191         int deprecated;
192         new_cli_fn new_handler;
193         char *_deprecated_by;   /*!< copied from the "parent" _full_cmd, on deprecated commands */
194         /*! For linking */
195         AST_LIST_ENTRY(ast_cli_entry) list;
196 };
197
198 /* XXX the parser in gcc 2.95 gets confused if you don't put a space
199  * between the last arg before VA_ARGS and the comma */
200 #define AST_CLI_DEFINE(fn, txt , ... )  { .new_handler = fn, .summary = txt, ## __VA_ARGS__ }
201
202 /*!
203  * Helper function to generate cli entries from a NULL-terminated array.
204  * Returns the n-th matching entry from the array, or NULL if not found.
205  * Can be used to implement generate() for static entries as below
206  * (in this example we complete the word in position 2):
207   \code
208     char *my_generate(const char *line, const char *word, int pos, int n)
209     {
210         static char *choices = { "one", "two", "three", NULL };
211         if (pos == 2)
212                 return ast_cli_complete(word, choices, n);
213         else
214                 return NULL;
215     }
216   \endcode
217  */
218 char *ast_cli_complete(const char *word, char *const choices[], int pos);
219
220 /*! 
221  * \brief Interprets a command
222  * Interpret a command s, sending output to fd
223  * \retval 0 on success
224  * \retval -1 on failure
225  */
226 int ast_cli_command(int fd, const char *s);
227
228 /*! 
229  * \brief Executes multiple CLI commands
230  * Interpret strings separated by '\0' and execute each one, sending output to fd
231  * \param size is the total size of the string
232  * \retval number of commands executed
233  */
234 int ast_cli_command_multiple(int fd, size_t size, const char *s);
235
236 /*! \brief Registers a command or an array of commands
237  * \param e which cli entry to register
238  * Register your own command
239  * \retval 0 on success
240  * \retval -1 on failure
241  */
242 int ast_cli_register(struct ast_cli_entry *e);
243
244 /*!
245  * \brief Register multiple commands
246  * \param e pointer to first cli entry to register
247  * \param len number of entries to register
248  */
249 int ast_cli_register_multiple(struct ast_cli_entry *e, int len);
250
251 /*! 
252  * \brief Unregisters a command or an array of commands
253  * \param e which cli entry to unregister
254  * Unregister your own command.  You must pass a completed ast_cli_entry structure
255  * \return 0.
256  */
257 int ast_cli_unregister(struct ast_cli_entry *e);
258
259 /*!
260  * \brief Unregister multiple commands
261  * \param e pointer to first cli entry to unregister
262  * \param len number of entries to unregister
263  */
264 int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len);
265
266 /*! 
267  * \brief Readline madness
268  * Useful for readline, that's about it
269  * \retval 0 on success
270  * \retval -1 on failure
271  */
272 char *ast_cli_generator(const char *, const char *, int);
273
274 int ast_cli_generatornummatches(const char *, const char *);
275
276 /*!
277  * \brief Generates a NULL-terminated array of strings that
278  * 1) begin with the string in the second parameter, and
279  * 2) are valid in a command after the string in the first parameter.
280  *
281  * The first entry (offset 0) of the result is the longest common substring
282  * in the results, useful to extend the string that has been completed.
283  * Subsequent entries are all possible values, followe by a NULL.
284  * All strings and the array itself are malloc'ed and must be freed
285  * by the caller.
286  */
287 char **ast_cli_completion_matches(const char *, const char *);
288
289 /*!
290  * \brief Command completion for the list of active channels
291  *
292  * This can be called from a CLI command completion function that wants to
293  * complete from the list of active channels.  'rpos' is the required
294  * position in the command.  This function will return NULL immediately if
295  * 'rpos' is not the same as the current position, 'pos'.
296  */
297 char *ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos);
298
299 #if defined(__cplusplus) || defined(c_plusplus)
300 }
301 #endif
302
303 #endif /* _ASTERISK_CLI_H */