new-style for 'core show uptime', include 'complete' support and better error checking
[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, 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 AST_MAX_CMD_LEN         16
42
43 #define AST_MAX_ARGS 64
44
45 #define AST_CLI_COMPLETE_EOF    "_EOF_"
46
47 /*!
48    CLI commands are described by a struct ast_cli_entry that contains
49    all the components for their implementation.
50    In the "old-style" format, the record must contain:
51    - a NULL-terminated array of words constituting the command, e.g.
52         { "set", "debug", "on", NULL },
53    - a summary string (short) and a usage string (longer);
54    - a handler which implements the command itself, invoked with
55      a file descriptor and argc/argv as typed by the user
56    - a 'generator' function which, given a partial string, can
57      generate legal completions for it.
58    An example is
59
60         int old_setdebug(int fd, int argc, char *argv[]);
61         char *dbg_complete(const char *line, const char *word, int pos, int n);
62
63         { { "set", "debug", "on", NULL }, do_setdebug, "Enable debugging",
64         set_debug_usage, dbg_complete },
65
66    In the "new-style" format, all the above functionalities are implemented
67    by a single function, and the arguments tell which output is required.
68
69    NOTE: ideally, the new-style handler would have a different prototype,
70    i.e. something like
71         int new_setdebug(const struct ast_cli *e, int function,
72             int fd, int argc, char *argv[],     // handler args
73             int n, int pos, const char *line, const char *word // -complete args)
74    but at this moment we want to help the transition from old-style to new-style
75    functions so we keep the same interface and override some of the traditional
76    arguments.
77
78    To help the transition, a new-style entry has the same interface as the old one,
79    but it is declared as follows:
80
81         int new_setdebug(int fd, int argc, char *argv[]);
82
83         ...
84         // this is how we create the entry to register
85         NEW_CLI(new_setdebug, "short description")
86         ...
87
88    Called with the default arguments (argc > 0), the new_handler implements
89    the command as before.
90    A negative argc indicates one of the other functions, namely
91    generate the usage string, the full command, or implement the generator.
92    As a trick to extend the interface while being backward compatible,
93    argv[-1] points to a struct ast_cli_args, and, for the generator,
94    argv[0] is really a pointer to a struct ast_cli_args.
95    The return string is obtained by casting the result to char *
96
97    An example of new-style handler is the following
98
99 \code
100 static int test_new_cli(int fd, int argc, char *argv[])
101 {
102         struct ast_cli_entry *e = (struct ast_cli_entry *)argv[-1];
103         struct ast_cli_args *a;
104         static char *choices = { "one", "two", "three", NULL };
105
106         switch(argc) {
107         case CLI_USAGE:
108                 return (int)
109                         "Usage: do this well <arg>\n"
110                         "       typically multiline with body indented\n";
111
112         case CLI_CMD_STRING:
113                 return (int)"do this well";
114
115         case CLI_GENERATE:
116                 a = (struct ast_cli_args *)argv[0];
117                 if (a->pos > e->args)
118                         return NULL;
119                 return ast_cli_complete(a->word, choices, a->n);
120
121         default:        
122                 // we are guaranteed to be called with argc >= e->args;
123                 if (argc > e->args + 1) // we accept one extra argument
124                         return RESULT_SHOWUSAGE;
125                 ast_cli(fd, "done this well for %s\n", e->args[argc-1]);
126                 return RESULT_SUCCESS;
127         }
128 }
129
130 \endcode
131  *
132  */
133
134 /*! \brief calling arguments for new-style handlers */
135 enum ast_cli_fn {
136         CLI_USAGE = -1,         /* return the usage string */
137         CLI_CMD_STRING = -2,    /* return the command string */
138         CLI_GENERATE = -3,      /* behave as 'generator', remap argv to struct ast_cli_args */
139 };
140
141 typedef int (*old_cli_fn)(int fd, int argc, char *argv[]);
142
143 /*! \brief descriptor for a cli entry */
144 struct ast_cli_entry {
145         char * const cmda[AST_MAX_CMD_LEN];     /*!< words making up the command.
146                 * set the first entry to NULL for a new-style entry. */
147         /*! Handler for the command (fd for output, # of args, argument list).
148           Returns RESULT_SHOWUSAGE for improper arguments.
149           argv[] has argc 'useful' entries, and an additional NULL entry
150           at the end so that clients requiring NULL terminated arrays
151           can use it without need for copies.
152           You can overwrite argv or the strings it points to, but remember
153           that this memory is deallocated after the handler returns.
154          */
155         int (*handler)(int fd, int argc, char *argv[]);
156         const char *summary; /*!< Summary of the command (< 60 characters) */
157         const char *usage; /*!< Detailed usage information */
158         /*! Generate the n-th (starting from 0) possible completion
159           for a given 'word' following 'line' in position 'pos'.
160           'line' and 'word' must not be modified.
161           Must return a malloc'ed string with the n-th value when available,
162           or NULL if the n-th completion does not exist.
163           Typically, the function is called with increasing values for n
164           until a NULL is returned.
165          */
166         char *(*generator)(const char *line, const char *word, int pos, int n);
167         struct ast_cli_entry *deprecate_cmd;
168         int inuse; /*!< For keeping track of usage */
169         struct module *module;  /*!< module this belongs to */
170         char *_full_cmd;        /* built at load time from cmda[] */
171         /* This gets set in ast_cli_register()
172           It then gets set to something different when the deprecated command
173           is run for the first time (ie; after we warn the user that it's deprecated)
174          */
175         int args;               /*!< number of non-null entries in cmda */
176         char *command;          /*!< command, non-null for new-style entries */
177         int deprecated;
178         char *_deprecated_by;   /* copied from the "parent" _full_cmd, on deprecated commands */
179         /*! For linking */
180         AST_LIST_ENTRY(ast_cli_entry) list;
181 };
182
183 #define NEW_CLI(fn, txt)        { .handler = (old_cli_fn)fn, .summary = txt }
184
185 /* argument for new-style CLI handler */
186 struct ast_cli_args {
187         char fake[4];           /* a fake string, in the first position, for safety */
188         const char *line;       /* the current input line */
189         const char *word;       /* the word we want to complete */
190         int pos;                /* position of the word to complete */
191         int n;                  /* the iteration count (n-th entry we generate) */
192 };
193
194 /*!
195  * Helper function to generate cli entries from a NULL-terminated array.
196  * Returns the n-th matching entry from the array, or NULL if not found.
197  * Can be used to implement generate() for static entries as below
198  * (in this example we complete the word in position 2):
199   \code
200     char *my_generate(const char *line, const char *word, int pos, int n)
201     {
202         static char *choices = { "one", "two", "three", NULL };
203         if (pos == 2)
204                 return ast_cli_complete(word, choices, n);
205         else
206                 return NULL;
207     }
208   \endcode
209  */
210 char *ast_cli_complete(const char *word, char *const choices[], int pos);
211
212 /*! \brief Interprets a command
213  * Interpret a command s, sending output to fd
214  * Returns 0 on succes, -1 on failure
215  */
216 int ast_cli_command(int fd, const char *s);
217
218 /*! \brief Registers a command or an array of commands
219  * \param e which cli entry to register
220  * Register your own command
221  * Returns 0 on success, -1 on failure
222  */
223 int ast_cli_register(struct ast_cli_entry *e);
224
225 /*!
226  * \brief Register multiple commands
227  * \param e pointer to first cli entry to register
228  * \param len number of entries to register
229  */
230 void ast_cli_register_multiple(struct ast_cli_entry *e, int len);
231
232 /*! \brief Unregisters a command or an array of commands
233  *
234  * \param e which cli entry to unregister
235  * Unregister your own command.  You must pass a completed ast_cli_entry structure
236  * Returns 0.
237  */
238 int ast_cli_unregister(struct ast_cli_entry *e);
239
240 /*!
241  * \brief Unregister multiple commands
242  * \param e pointer to first cli entry to unregister
243  * \param len number of entries to unregister
244  */
245 void ast_cli_unregister_multiple(struct ast_cli_entry *e, int len);
246
247 /*! \brief Readline madness
248  * Useful for readline, that's about it
249  * Returns 0 on success, -1 on failure
250  */
251 char *ast_cli_generator(const char *, const char *, int);
252
253 int ast_cli_generatornummatches(const char *, const char *);
254
255 /*!
256  * \brief Generates a NULL-terminated array of strings that
257  * 1) begin with the string in the second parameter, and
258  * 2) are valid in a command after the string in the first parameter.
259  *
260  * The first entry (offset 0) of the result is the longest common substring
261  * in the results, useful to extend the string that has been completed.
262  * Subsequent entries are all possible values, followe by a NULL.
263  * All strings and the array itself are malloc'ed and must be freed
264  * by the caller.
265  */
266 char **ast_cli_completion_matches(const char *, const char *);
267
268 /*!
269  * \brief Command completion for the list of active channels
270  *
271  * This can be called from a CLI command completion function that wants to
272  * complete from the list of active channels.  'rpos' is the required
273  * position in the command.  This function will return NULL immediately if
274  * 'rpos' is not the same as the current position, 'pos'.
275  */
276 char *ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos);
277
278 #if defined(__cplusplus) || defined(c_plusplus)
279 }
280 #endif
281
282 #endif /* _ASTERISK_CLI_H */