lib/vty: add vty_stdio()

this introduces a new public/API function to the vty code for opening a
VTY on stdin/stdout.  Intended for unrestricted use by the individual
daemons, i.e. "offical API".

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/lib/vty.c b/lib/vty.c
index 4b44589..24df32c 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -1610,6 +1610,34 @@
   return 0;
 }
 
+/* allocate and initialise vty */
+static struct vty *
+vty_new_init (int vty_sock)
+{
+  struct vty *vty;
+
+  vty = vty_new ();
+  vty->fd = vty_sock;
+  vty->wfd = vty_sock;
+  vty->type = VTY_TERM;
+  vty->node = AUTH_NODE;
+  vty->fail = 0;
+  vty->cp = 0;
+  vty_clear_buf (vty);
+  vty->length = 0;
+  memset (vty->hist, 0, sizeof (vty->hist));
+  vty->hp = 0;
+  vty->hindex = 0;
+  vector_set_index (vtyvec, vty_sock, vty);
+  vty->status = VTY_NORMAL;
+  vty->lines = -1;
+  vty->iac = 0;
+  vty->iac_sb_in_progress = 0;
+  vty->sb_len = 0;
+
+  return vty;
+}
+
 /* Create new vty structure. */
 static struct vty *
 vty_create (int vty_sock, union sockunion *su)
@@ -1620,10 +1648,10 @@
   sockunion2str(su, buf, SU_ADDRSTRLEN);
 
   /* Allocate new vty structure and set up default values. */
-  vty = vty_new ();
-  vty->fd = vty_sock;
-  vty->wfd = vty_sock;
-  vty->type = VTY_TERM;
+  vty = vty_new_init (vty_sock);
+
+  /* configurable parameters not part of basic init */
+  vty->v_timeout = vty_timeout_val;
   strcpy (vty->address, buf);
   if (no_password_check)
     {
@@ -1634,25 +1662,8 @@
       else
 	vty->node = VIEW_NODE;
     }
-  else
-    vty->node = AUTH_NODE;
-  vty->fail = 0;
-  vty->cp = 0;
-  vty_clear_buf (vty);
-  vty->length = 0;
-  memset (vty->hist, 0, sizeof (vty->hist));
-  vty->hp = 0;
-  vty->hindex = 0;
-  vector_set_index (vtyvec, vty_sock, vty);
-  vty->status = VTY_NORMAL;
-  vty->v_timeout = vty_timeout_val;
   if (host.lines >= 0)
     vty->lines = host.lines;
-  else
-    vty->lines = -1;
-  vty->iac = 0;
-  vty->iac_sb_in_progress = 0;
-  vty->sb_len = 0;
 
   if (! no_password_check)
     {
@@ -1688,6 +1699,30 @@
   return vty;
 }
 
+/* create vty for stdio */
+struct vty *
+vty_stdio (void)
+{
+  struct vty *vty;
+
+  vty = vty_new_init (0);
+  vty->wfd = 1;
+
+  /* always have stdio vty in a known _unchangeable_ state, don't want config
+   * to have any effect here to make sure scripting this works as intended */
+  vty->node = ENABLE_NODE;
+  vty->v_timeout = 0;
+  strcpy (vty->address, "console");
+
+  vty_prompt (vty);
+
+  /* Add read/write thread. */
+  vty_event (VTY_WRITE, 1, vty);
+  vty_event (VTY_READ, 0, vty);
+
+  return vty;
+}
+
 /* Accept connection from the network. */
 static int
 vty_accept (struct thread *thread)
diff --git a/lib/vty.h b/lib/vty.h
index b758df3..abac3dd 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -237,6 +237,7 @@
 extern void vty_terminate (void);
 extern void vty_reset (void);
 extern struct vty *vty_new (void);
+extern struct vty *vty_stdio (void);
 extern int vty_out (struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3);
 extern void vty_read_config (char *, char *);
 extern void vty_time_print (struct vty *, int);