libcli libcli emulates a cisco style telnet command-line interface. To compile: make make install This will install libcli.so into /usr/local/lib. If you want to change the location, edit Makefile. There is a test application built called clitest. Run this and telnet to port 8000. By default, a single username and password combination is enabled. Username: fred Password: nerk Get help by entering "help" or hitting ?. libcli provides support for using the arrow keys for command-line editing. Up and Down arrows will cycle through the command history, and Left & Right can be used for editing the current command line. libcli also works out the shortest way of entering a command, so if you have a command "show users grep foobar" defined, you can enter "sh us g foobar" if that is the shortest possible way of doing it. Enter "sh?" at the command line to get a list of commands starting with "sh" A few commands are defined in every libcli program: help quit exit logout history Use in your own code: First of all, make sure you #include <libcli.h> in your C code, and link with -lcli. If you have any trouble with this, have a look at clitest.c for a demonstration. Start your program off with a cli_init(). This sets up the internal data structures required. When a user connects, they are presented with a greeting if one is set using the cli_set_banner(banner) function. By default, the command-line session is not authenticated, which means users will get full access as soon as they connect. As this may not be always the best thing, 2 methods of authentication are available. First, you can add username / password combinations with the cli_allow_user(username, password) function. When a user connects, they can connect with any of these username / password combinations. Secondly, you can add a callback using the cli_set_auth_callback(callback) function. This function is passed the username and password as char *, and must return CLI_OK if the user is to have access and CLI_ERROR if they are not. The library itself will take care of prompting the user for credentials. Commands are built using a tree-like structure. You define commands with the cli_register_command(parent, command, callback, privilege, mode, help) function. parent is a cli_command * reference to a previously added command. Using a parent you can build up complex commands. e.g. to provide commands "show users", "show sessions" and "show people", use the following sequence: cli_command *c = cli_register_command(NULL, "show", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL); cli_register_command(c, "sessions", fn_sessions, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the sessions connected"); cli_register_command(c, "users", fn_users, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the users connected"); cli_register_command(c, "people", fn_people, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show a list of the people I like"); If callback is NULL, the command can be used as part of a tree, but cannot be individually run. If you decide later that you don't want a command to be run, you can call cli_unregister_command(command). You can use this to build dynamic command trees. It is possible to carry along a user-defined context to all command callbacks using cli_set_context(cli, context) and cli_get_context(cli) functions. Hooks may be defined for default commands (help, quit, logout, exit, history, enable, disable) as follows: cli_register_hook(cli, "exit", hook_exit); The hook is defined the same as a command callback. It must return one of the following, which defines what libcli will do upon completion of the hook callback: CLI_HOOK_CONTINUE -- Continue with default implmentation CLI_HOOK_STOP -- Return CLI_OK immediately upon completion CLI_HOOK_ERROR -- Return CLI_ERROR immediately upon completion Command-specific completion: It is possible to specify a callback for processing tab-completion on parameter values using the following: void cli_register_completion_cb(struct cli_command *cmd, int (*callback)(struct cli_def *, const char *, char **, int, char **, int)); The completion callback is defined as follows: int completion_cb(struct cli_def *cli, const char *command, char *argv[], int argc, char **completion_buf, int max_completions) In order to define a completion callback, a function must be defined to free() memory that it allocates. Do this via: void cli_register_completion_free(struct cli_def *cli, void (*callback)(char **, int)); The completion-free callback is defined as follows: void completion_free_cb(char **completion_buf, int num_completions) You are responsible for accepting a TCP connection, and for creating a process or thread to run the cli. Once you are ready to process the connection, call cli_loop(cli, sock) to interact with the user on the given socket. This function will return when the user exits the cli, either by breaking the connection or entering "quit". Call cli_done() to free the data structures. - David Parrish (david@dparrish.com) Fork: https://github.com/kevkeys/libcli Maintainer: Kevin Barrett <kevin@baymicrosystems.com> Changelog: 2014-Dec-05 Fork from https://github.com/dparrish/libcli ID a61be59b8b7c40b3acf1dc4acaafc247da22e5d3 2014-Dec-07 Add support for hooks for default commands 2014-Dec-07 Add command-specific completion