birdcl.c 2.39 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 *	BIRD Client - Light variant I/O
 *
 *	(c) 1999--2004 Martin Mares <mj@ucw.cz>
 *      (c) 2013 Tomas Hlavacek <tomas.hlavacek@nic.cz>
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
14
#include <errno.h>
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112

#include <sys/ioctl.h>
#include <signal.h>

#include "nest/bird.h"
#include "lib/resource.h"
#include "lib/string.h"
#include "client/client.h"
#include "sysdep/unix/unix.h"

#define INPUT_BUF_LEN 2048

struct termios tty_save;

void
input_start_list(void)
{
  /* Empty in non-ncurses version. */
}

void
input_stop_list(void)
{
  /* Empty in non-ncurses version. */
}

void
input_notify(int prompt)
{
  /* No ncurses -> no status to reveal/hide, print prompt manually. */
  if (!prompt)
    return;

  printf("bird> ");
  fflush(stdout);
}


static int
lastnb(char *str, int i)
{
  while (i--)
    if ((str[i] != ' ') && (str[i] != '\t'))
      return str[i];

  return 0;
}

void
input_read(void)
{
  char buf[INPUT_BUF_LEN];

  if ((fgets(buf, INPUT_BUF_LEN, stdin) == NULL) || (buf[0] == 0))
  {
    putchar('\n');
    cleanup();
    exit(0);
  }

  int l = strlen(buf);
  if ((l+1) == INPUT_BUF_LEN)
    {
      printf("Input too long.\n");
      return;
    }

  if (buf[l-1] == '\n')
    buf[--l] = '\0';

  if (!interactive)
    printf("%s\n", buf);

  if (l == 0)
    return;

  if (lastnb(buf, l) == '?')
    {
      cmd_help(buf, strlen(buf));
      return;
    }

  submit_command(buf);
}

static struct termios stored_tty;
static int more_active = 0;

void
more_begin(void)
{
  static struct termios tty;

  tty = stored_tty;
  tty.c_lflag &= (~ECHO);
  tty.c_lflag &= (~ICANON);

  if (tcsetattr (0, TCSANOW, &tty) < 0)
113
    DIE("tcsetattr");
114 115 116 117 118 119 120 121 122 123

  more_active = 1;
}

void
more_end(void)
{
  more_active = 0;

  if (tcsetattr (0, TCSANOW, &stored_tty) < 0)
124
    DIE("tcsetattr");
125 126 127
}

static void
128
sig_handler(int signal UNUSED)
129 130 131 132 133 134 135 136 137 138 139 140
{
  cleanup();
  exit(0);
}

void
input_init(void)
{
  if (!interactive)
    return;

  if (tcgetattr(0, &stored_tty) < 0)
141
    DIE("tcgetattr");
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161

  if (signal(SIGINT, sig_handler) == SIG_IGN)
    signal(SIGINT, SIG_IGN);
  if (signal(SIGTERM, sig_handler) == SIG_IGN)
    signal(SIGTERM, SIG_IGN);

  struct winsize tws;
  if (ioctl(0, TIOCGWINSZ, &tws) == 0)
    {
      term_lns = tws.ws_row;
      term_cls = tws.ws_col;
    }
}

void
cleanup(void)
{
  if (more_active)
    more_end();
}