]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Pull out independent routines from client_full.c
authorTomas Hlavacek <tmshlvck@gmail.com>
Wed, 23 Jan 2013 16:14:53 +0000 (17:14 +0100)
committerTomas Hlavacek <tmshlvck@gmail.com>
Tue, 19 Mar 2013 17:03:49 +0000 (18:03 +0100)
Pull out routines for interacting with the server and interpreting
internal commands which are not dependent on libreadline and
ncurses libraries.

This is a preparation step for a new lightweight birdc client.

client/Makefile
client/client.h
client/client_common.c [new file with mode: 0644]
client/client_full.c

index 74b30b777160daec9db1cab410bba865396ec4ef..fdefe6ab189ddb618e83b0fbdbad7f3fa8bf0145 100644 (file)
@@ -1,4 +1,4 @@
-source=client_full.c commands.c util.c
+source=client_full.c commands.c util.c client_common.c
 root-rel=../
 dir-name=client
 
index 64de97ec912d3392666a7d1d1bf4dd0dd4420bd0..373b1c6f66e743eeefc150a54ff2c0fc19226f41 100644 (file)
@@ -18,3 +18,17 @@ 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);
+
+/* client_common.c */
+
+#define STATE_PROMPT           0
+#define STATE_CMD_SERVER       1
+#define STATE_CMD_USER         2
+
+#define SERVER_READ_BUF_LEN 4096
+
+int handle_internal_command(char *cmd);
+void submit_server_command(char *cmd);
+void server_connect(void);
+void server_read(void);
+void server_send(char *cmd);
diff --git a/client/client_common.c b/client/client_common.c
new file mode 100644 (file)
index 0000000..5f0a36d
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ *     BIRD Client
+ *
+ *     (c) 1999--2004 Martin Mares <mj@ucw.cz>
+ *     (c) 2013 Tomas Hlavacek <tmshlvck@gmail.com>
+ *
+ *     Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/types.h>
+
+#include "nest/bird.h"
+#include "lib/resource.h"
+#include "lib/string.h"
+#include "client/client.h"
+#include "sysdep/unix/unix.h"
+
+char *server_path = PATH_CONTROL_SOCKET;
+int server_fd;
+byte server_read_buf[SERVER_READ_BUF_LEN];
+byte *server_read_pos = server_read_buf;
+
+int input_initialized;
+int input_hidden_end;
+int cstate = STATE_CMD_SERVER;
+int nstate = STATE_CMD_SERVER;
+
+int num_lines, skip_input, interactive;
+
+
+/*** Input ***/
+
+int
+handle_internal_command(char *cmd)
+{
+  if (!strncmp(cmd, "exit", 4) || !strncmp(cmd, "quit", 4))
+    {
+      cleanup();
+      exit(0);
+    }
+  if (!strncmp(cmd, "help", 4))
+    {
+      puts("Press `?' for context sensitive help.");
+      return 1;
+    }
+  return 0;
+}
+
+void
+submit_server_command(char *cmd)
+{
+  server_send(cmd);
+  nstate = STATE_CMD_SERVER;
+  num_lines = 2;
+}
+
+/*** Communication with server ***/
+
+void
+server_connect(void)
+{
+  struct sockaddr_un sa;
+
+  server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+  if (server_fd < 0)
+    die("Cannot create socket: %m");
+
+  if (strlen(server_path) >= sizeof(sa.sun_path))
+    die("server_connect: path too long");
+
+  bzero(&sa, sizeof(sa));
+  sa.sun_family = AF_UNIX;
+  strcpy(sa.sun_path, server_path);
+  if (connect(server_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) < 0)
+    die("Unable to connect to server control socket (%s): %m", server_path);
+  if (fcntl(server_fd, F_SETFL, O_NONBLOCK) < 0)
+    die("fcntl: %m");
+}
+
+void
+server_read(void)
+{
+  int c;
+  byte *start, *p;
+
+ redo:
+  c = read(server_fd, server_read_pos, server_read_buf + sizeof(server_read_buf) - server_read_pos);
+  if (!c)
+    die("Connection closed by server.");
+  if (c < 0)
+    {
+      if (errno == EINTR)
+       goto redo;
+      else
+       die("Server read error: %m");
+    }
+
+  start = server_read_buf;
+  p = server_read_pos;
+  server_read_pos += c;
+  while (p < server_read_pos)
+    if (*p++ == '\n')
+      {
+       p[-1] = 0;
+       server_got_reply(start);
+       start = p;
+      }
+  if (start != server_read_buf)
+    {
+      int l = server_read_pos - start;
+      memmove(server_read_buf, start, l);
+      server_read_pos = server_read_buf + l;
+    }
+  else if (server_read_pos == server_read_buf + sizeof(server_read_buf))
+    {
+      strcpy(server_read_buf, "?<too-long>");
+      server_read_pos = server_read_buf + 11;
+    }
+}
+
+void
+wait_for_write(int fd)
+{
+  while (1)
+    {
+      int rv;
+      fd_set set;
+      FD_ZERO(&set);
+      FD_SET(fd, &set);
+
+      rv = select(fd+1, NULL, &set, NULL, NULL);
+      if (rv < 0)
+       {
+         if (errno == EINTR)
+           continue;
+         else
+           die("select: %m");
+       }
+
+      if (FD_ISSET(server_fd, &set))
+       return;
+    }
+}
+
+void
+server_send(char *cmd)
+{
+  int l = strlen(cmd);
+  byte *z = alloca(l + 1);
+
+  memcpy(z, cmd, l);
+  z[l++] = '\n';
+  while (l)
+    {
+      int cnt = write(server_fd, z, l);
+
+      if (cnt < 0)
+       {
+         if (errno == EAGAIN)
+           wait_for_write(server_fd);
+         else if (errno == EINTR)
+           continue;
+         else
+           die("Server write error: %m");
+       }
+      else
+       {
+         l -= cnt;
+         z += cnt;
+       }
+    }
+}
index d8f0060c9f875b47140b2bf5639f1e2132b34088..9b4dd2fb8d6f69a5e4f39a7862b0b0e14fbe6a58 100644 (file)
@@ -31,21 +31,17 @@ static char *init_cmd;
 static int once;
 static int restricted;
 
-static char *server_path = PATH_CONTROL_SOCKET;
-static int server_fd;
-static byte server_read_buf[4096];
-static byte *server_read_pos = server_read_buf;
+extern char *server_path;
+extern int server_fd;
+extern byte server_read_buf[SERVER_READ_BUF_LEN];
+extern byte *server_read_pos;
 
-#define STATE_PROMPT           0
-#define STATE_CMD_SERVER       1
-#define STATE_CMD_USER         2
+extern int input_initialized;
+extern int input_hidden_end;
+extern int cstate;
+extern int nstate;
 
-static int input_initialized;
-static int input_hidden_end;
-static int cstate = STATE_CMD_SERVER;
-static int nstate = STATE_CMD_SERVER;
-
-static int num_lines, skip_input, interactive;
+extern int num_lines, skip_input, interactive;
 
 /*** Parsing of arguments ***/
 
@@ -102,37 +98,11 @@ parse_args(int argc, char **argv)
 
 /*** Input ***/
 
-static void server_send(char *);
-
 /* HACK: libreadline internals we need to access */
 extern int _rl_vis_botlin;
 extern void _rl_move_vert(int);
 extern Function *rl_last_func;
 
-static int
-handle_internal_command(char *cmd)
-{
-  if (!strncmp(cmd, "exit", 4) || !strncmp(cmd, "quit", 4))
-    {
-      cleanup();
-      exit(0);
-    }
-  if (!strncmp(cmd, "help", 4))
-    {
-      puts("Press `?' for context sensitive help.");
-      return 1;
-    }
-  return 0;
-}
-
-void
-submit_server_command(char *cmd)
-{
-  server_send(cmd);
-  nstate = STATE_CMD_SERVER;
-  num_lines = 2;
-}
-
 static void
 add_history_dedup(char *cmd)
 {
@@ -142,8 +112,7 @@ add_history_dedup(char *cmd)
     add_history(cmd);
 }
 
-static void
-got_line(char *cmd_buffer)
+void got_line(char *cmd_buffer)
 {
   char *cmd;
 
@@ -156,16 +125,16 @@ got_line(char *cmd_buffer)
     {
       cmd = cmd_expand(cmd_buffer);
       if (cmd)
-       {
-         add_history_dedup(cmd);
+       {
+         add_history_dedup(cmd);
 
-         if (!handle_internal_command(cmd))
-           submit_server_command(cmd);
+         if (!handle_internal_command(cmd))
+           submit_server_command(cmd);
 
-         free(cmd);
-       }
+         free(cmd);
+       }
       else
-       add_history_dedup(cmd_buffer);
+       add_history_dedup(cmd_buffer);
     }
   free(cmd_buffer);
 }
@@ -284,17 +253,6 @@ input_reveal(void)
   rl_forced_update_display();
 }
 
-void
-cleanup(void)
-{
-  if (input_initialized)
-    {
-      input_initialized = 0;
-      input_hide();
-      rl_callback_handler_remove();
-    }
-}
-
 void
 update_state(void)
 {
@@ -364,111 +322,18 @@ more(void)
   fflush(stdout);
 }
 
-
-/*** Communication with server ***/
-
-static void
-server_connect(void)
-{
-  struct sockaddr_un sa;
-
-  server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
-  if (server_fd < 0)
-    die("Cannot create socket: %m");
-
-  if (strlen(server_path) >= sizeof(sa.sun_path))
-    die("server_connect: path too long");
-
-  bzero(&sa, sizeof(sa));
-  sa.sun_family = AF_UNIX;
-  strcpy(sa.sun_path, server_path);
-  if (connect(server_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) < 0)
-    die("Unable to connect to server control socket (%s): %m", server_path);
-  if (fcntl(server_fd, F_SETFL, O_NONBLOCK) < 0)
-    die("fcntl: %m");
-}
-
-#define PRINTF(LEN, PARGS...) do { if (!skip_input) len = printf(PARGS); } while(0)
-
-static void
-server_got_reply(char *x)
+void cleanup(void)
 {
-  int code;
-  int len = 0;
-
-  if (*x == '+')                       /* Async reply */
-    PRINTF(len, ">>> %s\n", x+1);
-  else if (x[0] == ' ')                        /* Continuation */
-    PRINTF(len, "%s%s\n", verbose ? "     " : "", x+1);
-  else if (strlen(x) > 4 &&
-          sscanf(x, "%d", &code) == 1 && code >= 0 && code < 10000 &&
-          (x[4] == ' ' || x[4] == '-'))
-    {
-      if (code)
-       PRINTF(len, "%s\n", verbose ? x : x+5);
-      if (x[4] == ' ')
-      {
-       nstate = STATE_PROMPT;
-       skip_input = 0;
-       return;
-      }
-    }
-  else
-    PRINTF(len, "??? <%s>\n", x);
-
-  if (skip_input)
-    return;
-
-  if (interactive && input_initialized && (len > 0))
+  if (input_initialized)
     {
-      int lns = LINES ? LINES : 25;
-      int cls = COLS ? COLS : 80;
-      num_lines += (len + cls - 1) / cls; /* Divide and round up */
-      if ((num_lines >= lns)  && (cstate == STATE_CMD_SERVER))
-       more();
+      input_initialized = 0;
+      input_hide();
+      rl_callback_handler_remove();
     }
 }
 
-static void
-server_read(void)
-{
-  int c;
-  byte *start, *p;
-
- redo:
-  c = read(server_fd, server_read_pos, server_read_buf + sizeof(server_read_buf) - server_read_pos);
-  if (!c)
-    die("Connection closed by server.");
-  if (c < 0)
-    {
-      if (errno == EINTR)
-       goto redo;
-      else
-       die("Server read error: %m");
-    }
 
-  start = server_read_buf;
-  p = server_read_pos;
-  server_read_pos += c;
-  while (p < server_read_pos)
-    if (*p++ == '\n')
-      {
-       p[-1] = 0;
-       server_got_reply(start);
-       start = p;
-      }
-  if (start != server_read_buf)
-    {
-      int l = server_read_pos - start;
-      memmove(server_read_buf, start, l);
-      server_read_pos = server_read_buf + l;
-    }
-  else if (server_read_pos == server_read_buf + sizeof(server_read_buf))
-    {
-      strcpy(server_read_buf, "?<too-long>");
-      server_read_pos = server_read_buf + 11;
-    }
-}
+/*** Communication with server ***/
 
 static fd_set select_fds;
 
@@ -508,56 +373,43 @@ select_loop(void)
     }
 }
 
-static void
-wait_for_write(int fd)
-{
-  while (1)
-    {
-      int rv;
-      fd_set set;
-      FD_ZERO(&set);
-      FD_SET(fd, &set);
+#define PRINTF(LEN, PARGS...) do { if (!skip_input) len = printf(PARGS); } while(0)
 
-      rv = select(fd+1, NULL, &set, NULL, NULL);
-      if (rv < 0)
-       {
-         if (errno == EINTR)
-           continue;
-         else
-           die("select: %m");
-       }
+void server_got_reply(char *x)
+{
+  int code;
+  int len = 0;
 
-      if (FD_ISSET(server_fd, &set))
-       return;
+  if (*x == '+')                        /* Async reply */
+    PRINTF(len, ">>> %s\n", x+1);
+  else if (x[0] == ' ')                 /* Continuation */
+    PRINTF(len, "%s%s\n", verbose ? "     " : "", x+1);
+  else if (strlen(x) > 4 &&
+           sscanf(x, "%d", &code) == 1 && code >= 0 && code < 10000 &&
+           (x[4] == ' ' || x[4] == '-'))
+    {
+      if (code)
+        PRINTF(len, "%s\n", verbose ? x : x+5);
+      if (x[4] == ' ')
+      {
+        nstate = STATE_PROMPT;
+        skip_input = 0;
+        return;
+      }
     }
-}
+  else
+    PRINTF(len, "??? <%s>\n", x);
 
-static void
-server_send(char *cmd)
-{
-  int l = strlen(cmd);
-  byte *z = alloca(l + 1);
+  if (skip_input)
+    return;
 
-  memcpy(z, cmd, l);
-  z[l++] = '\n';
-  while (l)
+  if (interactive && input_initialized && (len > 0))
     {
-      int cnt = write(server_fd, z, l);
-
-      if (cnt < 0)
-       {
-         if (errno == EAGAIN)
-           wait_for_write(server_fd);
-         else if (errno == EINTR)
-           continue;
-         else
-           die("Server write error: %m");
-       }
-      else
-       {
-         l -= cnt;
-         z += cnt;
-       }
+      int lns = LINES ? LINES : 25;
+      int cls = COLS ? COLS : 80;
+      num_lines += (len + cls - 1) / cls; /* Divide and round up */
+      if ((num_lines >= lns)  && (cstate == STATE_CMD_SERVER))
+        more();
     }
 }