incorporates r159808 from branches/1.4:
[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 "asterisk/linkedlists.h"
31
32 void ast_cli(int fd, const char *fmt, ...)
33         __attribute__((format(printf, 2, 3)));
34
35 #define RESULT_SUCCESS          0
36 #define RESULT_SHOWUSAGE        1
37 #define RESULT_FAILURE          2
38
39 #define CLI_SUCCESS     (char *)RESULT_SUCCESS
40 #define CLI_SHOWUSAGE   (char *)RESULT_SHOWUSAGE
41 #define CLI_FAILURE     (char *)RESULT_FAILURE
42
43 #define AST_MAX_CMD_LEN         16
44
45 #define AST_MAX_ARGS 64
46
47 #define AST_CLI_COMPLETE_EOF    "_EOF_"
48
49 /*!
50  * In many cases we need to print singular or plural
51  * words depending on a count. This macro helps us e.g.
52  *     printf("we have %d object%s", n, ESS(n));
53  */
54 #define ESS(x) ((x) == 1 ? "" : "s")
55
56 /*! \page CLI_command_API CLI command API
57
58    CLI commands are described by a struct ast_cli_entry that contains
59    all the components for their implementation.
60
61    In the "old-style" format, the record must contain:
62    - a NULL-terminated array of words constituting the command, e.g.
63         { "set", "debug", "on", NULL },
64    - a summary string (short) and a usage string (longer);
65    - a handler which implements the command itself, invoked with
66      a file descriptor and argc/argv as typed by the user
67    - a 'generator' function which, given a partial string, can
68      generate legal completions for it.
69    An example is
70
71         int old_setdebug(int fd, int argc, char *argv[]);
72         char *dbg_complete(const char *line, const char *word, int pos, int n);
73
74         { { "set", "debug", "on", NULL }, do_setdebug, "Enable debugging",
75         set_debug_usage, dbg_complete },
76
77    In the "new-style" format, all the above functionalities are implemented
78    by a single function, and the arguments tell which output is required.
79    The prototype is the following:
80
81         char *new_setdebug(const struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
82
83         ...
84         // this is how we create the entry to register 
85         AST_CLI_DEFINE(new_setdebug, "short description")
86         ...
87
88    To help the transition, we make the pointer to the struct ast_cli_entry
89    available to old-style handlers via argv[-1].
90
91    An example of new-style handler is the following
92
93 \code
94 static char *test_new_cli(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
95 {
96         static char *choices = { "one", "two", "three", NULL };
97
98         switch (cmd) {
99         case CLI_INIT:
100                 e->command = "do this well";
101                 e->usage =
102                         "Usage: do this well <arg>\n"
103                         "       typically multiline with body indented\n";
104                 return NULL;
105
106         case CLI_GENERATE:
107                 if (a->pos > e->args)
108                         return NULL;
109                 return ast_cli_complete(a->word, choices, a->n);
110
111         default:        
112                 // we are guaranteed to be called with argc >= e->args;
113                 if (a->argc > e->args + 1) // we accept one extra argument
114                         return CLI_SHOWUSAGE;
115                 ast_cli(a->fd, "done this well for %s\n", e->args[argc-1]);
116                 return CLI_SUCCESS;
117         }
118 }
119
120 \endcode
121  
122  */
123
124 /*! \brief calling arguments for new-style handlers. 
125 * \arg \ref CLI_command_API
126 */
127 enum ast_cli_fn {
128         CLI_INIT = -2,          /* return the usage string */
129         CLI_GENERATE = -3,      /* behave as 'generator', remap argv to struct ast_cli_args */
130         CLI_HANDLER = -4,       /* run the normal handler */
131 };
132
133 /* argument for new-style CLI handler */
134 struct ast_cli_args {
135         int fd;
136         int argc;
137         char **argv;
138         const char *line;       /* the current input line */
139         const char *word;       /* the word we want to complete */
140         int pos;                /* position of the word to complete */
141         int n;                  /* the iteration count (n-th entry we generate) */
142 };
143
144 struct ast_cli_entry;
145 typedef char *(*cli_fn)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
146
147 /*! \brief descriptor for a cli entry. 
148  * \arg \ref CLI_command_API
149  */
150 struct ast_cli_entry {
151         char * const cmda[AST_MAX_CMD_LEN];     /*!< words making up the command.
152                                                 * set the first entry to NULL for a new-style entry. */
153
154         const char *summary;                    /*!< Summary of the command (< 60 characters) */
155         const char *usage;                      /*!< Detailed usage information */
156
157         int inuse;                              /*!< For keeping track of usage */
158         struct module *module;                  /*!< module this belongs to */
159         char *_full_cmd;                        /*!< built at load time from cmda[] */
160         int cmdlen;                             /*!< len up to the first invalid char [<{% */
161         /*! \brief This gets set in ast_cli_register()
162          */
163         int args;                               /*!< number of non-null entries in cmda */
164         char *command;                          /*!< command, non-null for new-style entries */
165         cli_fn handler;
166         /*! For linking */
167         AST_LIST_ENTRY(ast_cli_entry) list;
168 };
169
170 /* XXX the parser in gcc 2.95 gets confused if you don't put a space
171  * between the last arg before VA_ARGS and the comma */
172 #define AST_CLI_DEFINE(fn, txt , ... )  { .handler = fn, .summary = txt, ## __VA_ARGS__ }
173
174 /*!
175  * Helper function to generate cli entries from a NULL-terminated array.
176  * Returns the n-th matching entry from the array, or NULL if not found.
177  * Can be used to implement generate() for static entries as below
178  * (in this example we complete the word in position 2):
179   \code
180     char *my_generate(const char *line, const char *word, int pos, int n)
181     {
182         static char *choices = { "one", "two", "three", NULL };
183         if (pos == 2)
184                 return ast_cli_complete(word, choices, n);
185         else
186                 return NULL;
187     }
188   \endcode
189  */
190 char *ast_cli_complete(const char *word, char *const choices[], int pos);
191
192 /*! 
193  * \brief Interprets a command
194  * Interpret a command s, sending output to fd
195  * \param fd pipe
196  * \param s incoming string
197  * \retval 0 on success
198  * \retval -1 on failure
199  */
200 int ast_cli_command(int fd, const char *s);
201
202 /*! 
203  * \brief Executes multiple CLI commands
204  * Interpret strings separated by NULL and execute each one, sending output to fd
205  * \param fd pipe
206  * \param size is the total size of the string
207  * \param s incoming string
208  * \retval number of commands executed
209  */
210 int ast_cli_command_multiple(int fd, size_t size, const char *s);
211
212 /*! \brief Registers a command or an array of commands
213  * \param e which cli entry to register.
214  * Register your own command
215  * \retval 0 on success
216  * \retval -1 on failure
217  */
218 int ast_cli_register(struct ast_cli_entry *e);
219
220 /*!
221  * \brief Register multiple commands
222  * \param e pointer to first cli entry to register
223  * \param len number of entries to register
224  */
225 int ast_cli_register_multiple(struct ast_cli_entry *e, int len);
226
227 /*! 
228  * \brief Unregisters a command or an array of commands
229  * \param e which cli entry to unregister
230  * Unregister your own command.  You must pass a completed ast_cli_entry structure
231  * \return 0
232  */
233 int ast_cli_unregister(struct ast_cli_entry *e);
234
235 /*!
236  * \brief Unregister multiple commands
237  * \param e pointer to first cli entry to unregister
238  * \param len number of entries to unregister
239  */
240 int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len);
241
242 /*! 
243  * \brief Readline madness
244  * Useful for readline, that's about it
245  * \retval 0 on success
246  * \retval -1 on failure
247  */
248 char *ast_cli_generator(const char *, const char *, int);
249
250 int ast_cli_generatornummatches(const char *, const char *);
251
252 /*!
253  * \brief Generates a NULL-terminated array of strings that
254  * 1) begin with the string in the second parameter, and
255  * 2) are valid in a command after the string in the first parameter.
256  *
257  * The first entry (offset 0) of the result is the longest common substring
258  * in the results, useful to extend the string that has been completed.
259  * Subsequent entries are all possible values, followed by a NULL.
260  * All strings and the array itself are malloc'ed and must be freed
261  * by the caller.
262  */
263 char **ast_cli_completion_matches(const char *, const char *);
264
265 /*!
266  * \brief Command completion for the list of active channels.
267  *
268  * This can be called from a CLI command completion function that wants to
269  * complete from the list of active channels.  'rpos' is the required
270  * position in the command.  This function will return NULL immediately if
271  * 'rpos' is not the same as the current position, 'pos'.
272  */
273 char *ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos);
274
275 #if defined(__cplusplus) || defined(c_plusplus)
276 }
277 #endif
278
279 #endif /* _ASTERISK_CLI_H */