]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Support expansion of command abbreviations.
authorMartin Mares <mj@ucw.cz>
Sun, 27 Feb 2000 22:00:19 +0000 (22:00 +0000)
committerMartin Mares <mj@ucw.cz>
Sun, 27 Feb 2000 22:00:19 +0000 (22:00 +0000)
Client considered finished (modulo bugs).

TODO
client/client.c
client/client.h
client/commands.c
client/util.c

diff --git a/TODO b/TODO
index 7fa275e57ad7aa0e1537ee9257a45827da57bafa..f0c54866c52f3b6f48b1cd1277ac28003514d1d0 100644 (file)
--- a/TODO
+++ b/TODO
@@ -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]
index 9c6b4ae901fb14690e00fd3ab046c810d5cc925a..1e0496ed44d4a45dae5051be3ea7df1b28e305f4 100644 (file)
@@ -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);
 }
index f63c75c3f75536b81d6355cc97785e6bc8343ad4..64de97ec912d3392666a7d1d1bf4dd0dd4420bd0 100644 (file)
@@ -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);
index 09c5c344369ac5ca069ec71e0ada906bf12b9252..fdcb6d27c71aac1238d1daa643e897ca78070d53 100644 (file)
@@ -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;
+}
index 7699fafc7f6249ae2f2802d183b810d80157aec5..9f1a16b6473b025f2fddb49f4f74ae6b1386dd15 100644 (file)
 #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);
 }