diff options
author | Martin Mares <mj@ucw.cz> | 2000-02-27 23:00:19 +0100 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 2000-02-27 23:00:19 +0100 |
commit | e69e4ed9349ee28262fe74f70e7e52c181d5d098 (patch) | |
tree | 33dcb70e608d36460ff7ac0484cc438c7f9a7289 | |
parent | de30342f97490e3a3626c4a5fbf3352d1d0aa9c8 (diff) | |
download | bird-e69e4ed9349ee28262fe74f70e7e52c181d5d098.tar bird-e69e4ed9349ee28262fe74f70e7e52c181d5d098.zip |
Support expansion of command abbreviations.
Client considered finished (modulo bugs).
-rw-r--r-- | TODO | 19 | ||||
-rw-r--r-- | client/client.c | 24 | ||||
-rw-r--r-- | client/client.h | 1 | ||||
-rw-r--r-- | client/commands.c | 53 | ||||
-rw-r--r-- | client/util.c | 17 |
5 files changed, 80 insertions, 34 deletions
@@ -1,7 +1,5 @@ Core ~~~~ -- IPv6: router advertisements -- IPv6: test it! - IPv6: hashing functions etc. - krt-iface: check whether the interface alias hack works @@ -36,21 +34,6 @@ Commands ~~~~~~~~ - showing of routing table as seen by given protocol -Roadmap -~~~~~~~ -- Allocators and data structures -- Client -- Remaining bits of IPv6 support (radvd) -- RIPv6 -- BGP? - -Client -~~~~~~ -- command completion -- online help -- builtin command and aliases -- access control - Documentation ~~~~~~~~~~~~~ - write doctool @@ -74,6 +57,8 @@ Globals Various ideas ~~~~~~~~~~~~~ +- client: access control +- IPv6 router advertisements - real multipath (doesn't seem to be simple at all :() - fake multipath (even less simple) - route recalculation timing and flap dampening [see RFC2439 for algorithms] diff --git a/client/client.c b/client/client.c index 9c6b4ae..1e0496e 100644 --- a/client/client.c +++ b/client/client.c @@ -79,6 +79,8 @@ extern Function *rl_last_func; static void got_line(char *cmd_buffer) { + char *cmd; + if (!cmd_buffer) { cleanup(); @@ -86,12 +88,22 @@ got_line(char *cmd_buffer) } if (cmd_buffer[0]) { - add_history(cmd_buffer); - /* FIXME: Builtin commands: exit, ... */ - server_send(cmd_buffer); - input_hidden = -1; - io_loop(0); - input_hidden = 0; + cmd = cmd_expand(cmd_buffer); + if (cmd) + { + add_history(cmd); + puts(cmd); + if (!strcmp(cmd, "exit") || !strcmp(cmd, "quit")) + { + cleanup(); + exit(0); + } + server_send(cmd); + input_hidden = -1; + io_loop(0); + input_hidden = 0; + free(cmd); + } } free(cmd_buffer); } diff --git a/client/client.h b/client/client.h index f63c75c..64de97e 100644 --- a/client/client.h +++ b/client/client.h @@ -17,3 +17,4 @@ void input_stop_list(void); void cmd_build_tree(void); void cmd_help(char *cmd, int len); int cmd_complete(char *cmd, int len, char *buf, int again); +char *cmd_expand(char *cmd); diff --git a/client/commands.c b/client/commands.c index 09c5c34..fdcb6d2 100644 --- a/client/commands.c +++ b/client/commands.c @@ -25,8 +25,6 @@ static struct cmd_info command_table[] = { #include "conf/commands.h" }; -/* FIXME: There should exist some system of aliases, so that `show' can be abbreviated as `s' etc. */ - struct cmd_node { struct cmd_node *sibling, *son, **plastson; struct cmd_info *cmd, *help; @@ -53,7 +51,7 @@ cmd_build_tree(void) while (*c) { char *d = c; - while (*c && *c != ' ') + while (*c && !isspace(*c)) c++; for(new=old->son; new; new=new->sibling) if (new->len == c-d && !memcmp(new->token, d, c-d)) @@ -70,7 +68,7 @@ cmd_build_tree(void) memcpy(new->token, d, c-d); } old = new; - while (*c == ' ') + while (isspace(*c)) c++; } if (cmd->is_real_cmd) @@ -143,13 +141,13 @@ cmd_help(char *cmd, int len) n = &cmd_root; while (cmd < end) { - if (*cmd == ' ' || *cmd == '\t') + if (isspace(*cmd)) { cmd++; continue; } z = cmd; - while (cmd < end && *cmd != ' ' && *cmd != '\t') + while (cmd < end && !isspace(*cmd)) cmd++; m = cmd_find_abbrev(n, z, cmd-z, &ambig); if (ambig) @@ -213,7 +211,7 @@ cmd_complete(char *cmd, int len, char *buf, int again) n = &cmd_root; while (cmd < fin && n->son) { - if (*cmd == ' ' || *cmd == '\t') + if (isspace(*cmd)) { cmd++; continue; @@ -262,3 +260,44 @@ cmd_complete(char *cmd, int len, char *buf, int again) input_stop_list(); return 0; } + +char * +cmd_expand(char *cmd) +{ + struct cmd_node *n, *m; + char *c, *b, *args; + int ambig; + + args = c = cmd; + n = &cmd_root; + while (*c) + { + if (isspace(*c)) + { + c++; + continue; + } + b = c; + while (*c && !isspace(*c)) + c++; + m = cmd_find_abbrev(n, b, c-b, &ambig); + if (!m) + { + if (!ambig) + break; + puts("Ambiguous command, possible expansions are:"); + cmd_list_ambiguous(n, b, c-b); + return NULL; + } + args = c; + n = m; + } + if (!n->cmd) + { + puts("No such command."); + return NULL; + } + b = malloc(strlen(n->cmd->command) + strlen(args) + 1); + sprintf(b, "%s%s", n->cmd->command, args); + return b; +} diff --git a/client/util.c b/client/util.c index 7699faf..9f1a16b 100644 --- a/client/util.c +++ b/client/util.c @@ -12,11 +12,21 @@ #include <stdarg.h> #include "nest/bird.h" +#include "lib/string.h" #include "client/client.h" /* Client versions of logging functions */ -/* FIXME: Use bsprintf, so that %m works */ +static void +vlog(char *msg, va_list args) +{ + char buf[1024]; + + if (bvsnprintf(buf, sizeof(buf)-1, msg, args) < 0) + bsprintf(buf + sizeof(buf) - 100, " ... <too long>"); + fputs(buf, stderr); + fputc('\n', stderr); +} void bug(char *msg, ...) @@ -26,8 +36,8 @@ bug(char *msg, ...) va_start(args, msg); cleanup(); fputs("Internal error: ", stderr); + vlog(msg, args); vfprintf(stderr, msg, args); - fputc('\n', stderr); exit(1); } @@ -38,7 +48,6 @@ die(char *msg, ...) va_start(args, msg); cleanup(); - vfprintf(stderr, msg, args); - fputc('\n', stderr); + vlog(msg, args); exit(1); } |