Revision b9672a84 nest/cli.c

View differences:

nest/cli.c
17 17
{
18 18
  va_list args;
19 19
  byte buf[1024];
20
  int flag = (code < 0) ? '-' : ' ';
21
  int size;
20
  int cd = code;
21
  int size, cnt;
22 22
  struct cli_out *o;
23 23

  
24 24
  va_start(args, msg);
25
  if (code < 0)
26
    code = -code;
27
  bsprintf(buf, "%04d%c", code, flag);
28
  size = bvsnprintf(buf+5, sizeof(buf)-6, msg, args);
29
  if (size < 0)
30
    size = bsprintf(buf, "9999%c<line overflow>", flag);
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
    }
31 33
  else
32
    size += 5;
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;
33 43
  buf[size++] = '\n';
34 44
  if (!(o = c->tx_write) || o->wpos + size > o->end)
35 45
    {
36
      o = mb_alloc(c->pool, sizeof(struct cli_out) + CLI_TX_BUF_SIZE);
37
      if (c->tx_write)
38
	c->tx_write->next = o;
46
      if (!o && c->tx_buf)
47
	o = c->tx_buf;
39 48
      else
40
	c->tx_buf = o;
41
      o->next = NULL;
42
      o->wpos = o->outpos = o->buf;
43
      o->end = o->buf + CLI_TX_BUF_SIZE;
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
	}
44 59
      c->tx_write = o;
60
      if (!c->tx_pos)
61
	c->tx_pos = o;
45 62
    }
46 63
  memcpy(o->wpos, buf, size);
47 64
  o->wpos += size;
48 65
}
49 66

  
50 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
51 75
cli_free_out(cli *c)
52 76
{
53 77
  struct cli_out *o, *p;
54 78

  
55 79
  if (o = c->tx_buf)
56 80
    {
57
      c->tx_write = o;
81
      c->tx_write = NULL;
58 82
      o->wpos = o->outpos = o->buf;
59 83
      while (p = o->next)
60 84
	{
......
65 89
}
66 90

  
67 91
static int
68
cli_flush(cli *c)
69
{
70
  if (cli_write(c))
71
    {
72
      cli_free_out(c);
73
      return 1;
74
    }
75
  return 0;
76
}
77

  
78
static int
79 92
cli_event(void *data)
80 93
{
81 94
  cli *c = data;
82 95
  int err;
83 96

  
84
  debug("CLI EVENT\n");
85
  if (!c->inited)
97
  if (c->tx_pos)
98
    ;
99
  else if (c->cont)
100
    c->cont(c);
101
  else
86 102
    {
87
      c->inited = 1;
88
      cli_printf(c, 0, "Welcome!");
89
      cli_printf(c, 0, "Here");
90
      return cli_flush(c);
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
	}
91 113
    }
92
  err = cli_get_command(c);
93
  if (!err)
94
    return 0;
95
  if (err < 0)
96
    debug("CLI CMD ERR\n");
97
  else
98
    debug("CLI CMD %s\n", c->rx_buf);
99
  return 1;
114
  if (cli_write(c))
115
    {
116
      cli_free_out(c);
117
      return 1;
118
    }
119
  return 0;
100 120
}
101 121

  
102 122
cli *
......
111 131
  c->event->hook = cli_event;
112 132
  c->event->data = c;
113 133
  c->tx_buf = c->tx_pos = c->tx_write = NULL;
114
  c->inited = 0;
115
  cli_kick(c);
134
  c->cont = cli_hello;
135
  c->last_reply = 0;
136
  ev_schedule(c->event);
116 137
  return c;
117 138
}
118 139

  
119 140
void
120 141
cli_kick(cli *c)
121 142
{
122
  debug("CLI KICK\n");
123
  ev_schedule(c->event);
143
  if (!c->cont && !c->tx_pos)
144
    ev_schedule(c->event);
124 145
}
125 146

  
126 147
void
127 148
cli_written(cli *c)
128 149
{
129
  debug("CLI WRITTEN\n");
130 150
  cli_free_out(c);
131
  cli_kick(c);
151
  ev_schedule(c->event);
132 152
}
133 153

  
134 154
void

Also available in: Unified diff