diff --git a/nest/cli.c b/nest/cli.c index 09ebe96b..f094a7c4 100644 --- a/nest/cli.c +++ b/nest/cli.c @@ -17,36 +17,60 @@ cli_printf(cli *c, int code, char *msg, ...) { va_list args; byte buf[1024]; - int flag = (code < 0) ? '-' : ' '; - int size; + int cd = code; + int size, cnt; 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", flag); + if (cd < 0) + { + cd = -cd; + if (cd == c->last_reply) + size = bsprintf(buf, " "); + else + size = bsprintf(buf, "%04d-", cd); + } else - size += 5; + size = bsprintf(buf, "%04d ", cd); + c->last_reply = cd; + cnt = bvsnprintf(buf+size, sizeof(buf)-size-1, msg, args); + if (cnt < 0) + { + cli_printf(c, code < 0 ? -8000 : 8000, ""); + return; + } + size += cnt; 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; + if (!o && c->tx_buf) + o = c->tx_buf; else - c->tx_buf = o; - o->next = NULL; - o->wpos = o->outpos = o->buf; - o->end = o->buf + CLI_TX_BUF_SIZE; + { + 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; + if (!c->tx_pos) + c->tx_pos = o; } memcpy(o->wpos, buf, size); o->wpos += size; } +static void +cli_hello(cli *c) +{ + cli_printf(c, 1, "BIRD " BIRD_VERSION " ready."); + c->cont = NULL; +} + static void cli_free_out(cli *c) { @@ -54,7 +78,7 @@ cli_free_out(cli *c) if (o = c->tx_buf) { - c->tx_write = o; + c->tx_write = NULL; o->wpos = o->outpos = o->buf; while (p = o->next) { @@ -65,8 +89,28 @@ cli_free_out(cli *c) } static int -cli_flush(cli *c) +cli_event(void *data) { + cli *c = data; + int err; + + if (c->tx_pos) + ; + else if (c->cont) + c->cont(c); + else + { + err = cli_get_command(c); + if (!err) + return 0; + if (err < 0) + cli_printf(c, 9000, "Command too long"); + else + { + cli_printf(c, -9001, "Parse error in:"); + cli_printf(c, 9001, c->rx_buf); + } + } if (cli_write(c)) { cli_free_out(c); @@ -75,30 +119,6 @@ cli_flush(cli *c) 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) { @@ -111,24 +131,24 @@ cli_new(void *priv) 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); + c->cont = cli_hello; + c->last_reply = 0; + ev_schedule(c->event); return c; } void cli_kick(cli *c) { - debug("CLI KICK\n"); - ev_schedule(c->event); + if (!c->cont && !c->tx_pos) + ev_schedule(c->event); } void cli_written(cli *c) { - debug("CLI WRITTEN\n"); cli_free_out(c); - cli_kick(c); + ev_schedule(c->event); } void diff --git a/nest/cli.h b/nest/cli.h index 69271fec..9670f69a 100644 --- a/nest/cli.h +++ b/nest/cli.h @@ -24,26 +24,32 @@ struct cli_out { 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; + void (*cont)(struct cli *c); + void *rover; /* Private to continuation routine */ + int last_reply; } cli; extern pool *cli_pool; +/* Functions to be called by command handlers */ + +void cli_printf(cli *, int, char *, ...); + +/* Functions provided to sysdep layer */ + 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 */ +/* Functions provided by sysdep layer */ int cli_write(cli *); -void cli_disconnect(cli *); int cli_get_command(cli *); #endif diff --git a/sysdep/config.h b/sysdep/config.h index 4699b4f7..08526c87 100644 --- a/sysdep/config.h +++ b/sysdep/config.h @@ -6,6 +6,9 @@ #ifndef _BIRD_CONFIG_H_ #define _BIRD_CONFIG_H_ +/* BIRD version */ +#define BIRD_VERSION "0.0.0" + /* Include parameters determined by configure script */ #include "sysdep/autoconf.h" diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index f717fb0c..d5ea10bd 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -93,12 +93,6 @@ async_config(void) static sock *cli_sk; -void -cli_disconnect(cli *c) -{ - bug("CLI DISCONNECT: Not implemented"); /* FIXME */ -} - int cli_write(cli *c) { @@ -146,7 +140,6 @@ cli_get_command(cli *c) static int cli_rx(sock *s, int size) { - debug("CLI RX\n"); cli_kick(s->data); return 0; } @@ -156,7 +149,6 @@ cli_tx(sock *s) { cli *c = s->data; - debug("CLI TX\n"); if (cli_write(c)) cli_written(c); } @@ -313,7 +305,7 @@ main(int argc, char **argv) setvbuf(stderr, NULL, _IONBF, 0); parse_args(argc, argv); - log(L_INFO "Launching BIRD 0.0.0..."); + log(L_INFO "Launching BIRD " BIRD_VERSION "..."); debug("Initializing.\n"); resource_init(); diff --git a/tools/Makefile.in b/tools/Makefile.in index 337c1b43..bbf4db07 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -32,7 +32,7 @@ tags: clean: find . -name "*.[oa]" -or -name core -or -name depend | xargs rm -f - rm -f $(exedir)/bird $(exedir)/birdc .dep-stamp + rm -f $(exedir)/bird $(exedir)/birdc $(exedir)/bird.ctl .dep-stamp distclean: clean rm -f config.* configure sysdep/autoconf.h Makefile Rules