diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/Makefile | 2 | ||||
-rw-r--r-- | nest/cli.c | 144 | ||||
-rw-r--r-- | nest/cli.h | 49 |
3 files changed, 194 insertions, 1 deletions
diff --git a/nest/Makefile b/nest/Makefile index d7689e0f..5b6b414e 100644 --- a/nest/Makefile +++ b/nest/Makefile @@ -1,4 +1,4 @@ -source=rt-table.c rt-fib.c rt-attr.c proto.c iface.c rt-dev.c password.c +source=rt-table.c rt-fib.c rt-attr.c proto.c iface.c rt-dev.c password.c cli.c root-rel=../ dir-name=nest diff --git a/nest/cli.c b/nest/cli.c new file mode 100644 index 00000000..09ebe96b --- /dev/null +++ b/nest/cli.c @@ -0,0 +1,144 @@ +/* + * BIRD Internet Routing Daemon -- Command-Line Interface + * + * (c) 1999 Martin Mares <mj@ucw.cz> + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#include "nest/bird.h" +#include "lib/string.h" +#include "nest/cli.h" + +pool *cli_pool; + +void +cli_printf(cli *c, int code, char *msg, ...) +{ + va_list args; + byte buf[1024]; + int flag = (code < 0) ? '-' : ' '; + int size; + struct cli_out *o; + + va_start(args, msg); + if (code < 0) + code = -code; + bsprintf(buf, "%04d%c", code, flag); + size = bvsnprintf(buf+5, sizeof(buf)-6, msg, args); + if (size < 0) + size = bsprintf(buf, "9999%c<line overflow>", flag); + else + size += 5; + buf[size++] = '\n'; + if (!(o = c->tx_write) || o->wpos + size > o->end) + { + o = mb_alloc(c->pool, sizeof(struct cli_out) + CLI_TX_BUF_SIZE); + if (c->tx_write) + c->tx_write->next = o; + else + c->tx_buf = o; + o->next = NULL; + o->wpos = o->outpos = o->buf; + o->end = o->buf + CLI_TX_BUF_SIZE; + c->tx_write = o; + } + memcpy(o->wpos, buf, size); + o->wpos += size; +} + +static void +cli_free_out(cli *c) +{ + struct cli_out *o, *p; + + if (o = c->tx_buf) + { + c->tx_write = o; + o->wpos = o->outpos = o->buf; + while (p = o->next) + { + o->next = p->next; + mb_free(p); + } + } +} + +static int +cli_flush(cli *c) +{ + if (cli_write(c)) + { + cli_free_out(c); + return 1; + } + return 0; +} + +static int +cli_event(void *data) +{ + cli *c = data; + int err; + + debug("CLI EVENT\n"); + if (!c->inited) + { + c->inited = 1; + cli_printf(c, 0, "Welcome!"); + cli_printf(c, 0, "Here"); + return cli_flush(c); + } + err = cli_get_command(c); + if (!err) + return 0; + if (err < 0) + debug("CLI CMD ERR\n"); + else + debug("CLI CMD %s\n", c->rx_buf); + return 1; +} + +cli * +cli_new(void *priv) +{ + pool *p = rp_new(cli_pool, "CLI"); + cli *c = mb_alloc(p, sizeof(cli)); + + c->pool = p; + c->priv = priv; + c->event = ev_new(p); + c->event->hook = cli_event; + c->event->data = c; + c->tx_buf = c->tx_pos = c->tx_write = NULL; + c->inited = 0; + cli_kick(c); + return c; +} + +void +cli_kick(cli *c) +{ + debug("CLI KICK\n"); + ev_schedule(c->event); +} + +void +cli_written(cli *c) +{ + debug("CLI WRITTEN\n"); + cli_free_out(c); + cli_kick(c); +} + +void +cli_free(cli *c) +{ + rfree(c->pool); +} + +void +cli_init(void) +{ + cli_pool = rp_new(&root_pool, "CLI"); +} diff --git a/nest/cli.h b/nest/cli.h new file mode 100644 index 00000000..69271fec --- /dev/null +++ b/nest/cli.h @@ -0,0 +1,49 @@ +/* + * BIRD Internet Routing Daemon -- Command-Line Interface + * + * (c) 1999 Martin Mares <mj@ucw.cz> + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#ifndef _BIRD_CLI_H_ +#define _BIRD_CLI_H_ + +#include "lib/resource.h" +#include "lib/event.h" + +#define CLI_RX_BUF_SIZE 4096 +#define CLI_TX_BUF_SIZE 4096 + +struct cli_out { + struct cli_out *next; + byte *wpos, *outpos, *end; + byte buf[0]; +}; + +typedef struct cli { + pool *pool; + void *priv; /* Private to sysdep layer */ + int inited; + byte rx_buf[CLI_RX_BUF_SIZE]; + byte *rx_pos, *rx_aux; /* sysdep */ + struct cli_out *tx_buf, *tx_pos, *tx_write; + event *event; +} cli; + +extern pool *cli_pool; + +cli *cli_new(void *); +void cli_init(void); +void cli_free(cli *); +void cli_kick(cli *); +void cli_written(cli *); +void cli_printf(cli *, int, char *, ...); + +/* Function provided by sysdep layer */ + +int cli_write(cli *); +void cli_disconnect(cli *); +int cli_get_command(cli *); + +#endif |