Statistics
| Branch: | Revision:

iof-bird-daemon / nest / cli.c @ b9672a84

History | View | Annotate | Download (2.65 KB)

1
/*
2
 *        BIRD Internet Routing Daemon -- Command-Line Interface
3
 *
4
 *        (c) 1999 Martin Mares <mj@ucw.cz>
5
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

    
9
#include "nest/bird.h"
10
#include "lib/string.h"
11
#include "nest/cli.h"
12

    
13
pool *cli_pool;
14

    
15
void
16
cli_printf(cli *c, int code, char *msg, ...)
17
{
18
  va_list args;
19
  byte buf[1024];
20
  int cd = code;
21
  int size, cnt;
22
  struct cli_out *o;
23

    
24
  va_start(args, msg);
25
  if (cd < 0)
26
    {
27
      cd = -cd;
28
      if (cd == c->last_reply)
29
        size = bsprintf(buf, " ");
30
      else
31
        size = bsprintf(buf, "%04d-", cd);
32
    }
33
  else
34
    size = bsprintf(buf, "%04d ", cd);
35
  c->last_reply = cd;
36
  cnt = bvsnprintf(buf+size, sizeof(buf)-size-1, msg, args);
37
  if (cnt < 0)
38
    {
39
      cli_printf(c, code < 0 ? -8000 : 8000, "<line overflow>");
40
      return;
41
    }
42
  size += cnt;
43
  buf[size++] = '\n';
44
  if (!(o = c->tx_write) || o->wpos + size > o->end)
45
    {
46
      if (!o && c->tx_buf)
47
        o = c->tx_buf;
48
      else
49
        {
50
          o = mb_alloc(c->pool, sizeof(struct cli_out) + CLI_TX_BUF_SIZE);
51
          if (c->tx_write)
52
            c->tx_write->next = o;
53
          else
54
            c->tx_buf = o;
55
          o->next = NULL;
56
          o->wpos = o->outpos = o->buf;
57
          o->end = o->buf + CLI_TX_BUF_SIZE;
58
        }
59
      c->tx_write = o;
60
      if (!c->tx_pos)
61
        c->tx_pos = o;
62
    }
63
  memcpy(o->wpos, buf, size);
64
  o->wpos += size;
65
}
66

    
67
static void
68
cli_hello(cli *c)
69
{
70
  cli_printf(c, 1, "BIRD " BIRD_VERSION " ready.");
71
  c->cont = NULL;
72
}
73

    
74
static void
75
cli_free_out(cli *c)
76
{
77
  struct cli_out *o, *p;
78

    
79
  if (o = c->tx_buf)
80
    {
81
      c->tx_write = NULL;
82
      o->wpos = o->outpos = o->buf;
83
      while (p = o->next)
84
        {
85
          o->next = p->next;
86
          mb_free(p);
87
        }
88
    }
89
}
90

    
91
static int
92
cli_event(void *data)
93
{
94
  cli *c = data;
95
  int err;
96

    
97
  if (c->tx_pos)
98
    ;
99
  else if (c->cont)
100
    c->cont(c);
101
  else
102
    {
103
      err = cli_get_command(c);
104
      if (!err)
105
        return 0;
106
      if (err < 0)
107
        cli_printf(c, 9000, "Command too long");
108
      else
109
        {
110
          cli_printf(c, -9001, "Parse error in:");
111
          cli_printf(c, 9001, c->rx_buf);
112
        }
113
    }
114
  if (cli_write(c))
115
    {
116
      cli_free_out(c);
117
      return 1;
118
    }
119
  return 0;
120
}
121

    
122
cli *
123
cli_new(void *priv)
124
{
125
  pool *p = rp_new(cli_pool, "CLI");
126
  cli *c = mb_alloc(p, sizeof(cli));
127

    
128
  c->pool = p;
129
  c->priv = priv;
130
  c->event = ev_new(p);
131
  c->event->hook = cli_event;
132
  c->event->data = c;
133
  c->tx_buf = c->tx_pos = c->tx_write = NULL;
134
  c->cont = cli_hello;
135
  c->last_reply = 0;
136
  ev_schedule(c->event);
137
  return c;
138
}
139

    
140
void
141
cli_kick(cli *c)
142
{
143
  if (!c->cont && !c->tx_pos)
144
    ev_schedule(c->event);
145
}
146

    
147
void
148
cli_written(cli *c)
149
{
150
  cli_free_out(c);
151
  ev_schedule(c->event);
152
}
153

    
154
void
155
cli_free(cli *c)
156
{
157
  rfree(c->pool);
158
}
159

    
160
void
161
cli_init(void)
162
{
163
  cli_pool = rp_new(&root_pool, "CLI");
164
}