summaryrefslogtreecommitdiffstats
path: root/nest
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>1999-10-31 16:43:44 +0100
committerMartin Mares <mj@ucw.cz>1999-10-31 16:43:44 +0100
commitb9672a845f7ff7d2441e21746566eacc51f274b7 (patch)
treebb2fad2a4b30083234474698c4ef935c2c0548fc /nest
parent7d3aab1c1643e8b2bcff7f856e0d4455fa0ba4b4 (diff)
downloadbird-b9672a845f7ff7d2441e21746566eacc51f274b7.tar
bird-b9672a845f7ff7d2441e21746566eacc51f274b7.zip
The CLI I/O functions work as desired.
Diffstat (limited to 'nest')
-rw-r--r--nest/cli.c116
-rw-r--r--nest/cli.h14
2 files changed, 78 insertions, 52 deletions
diff --git a/nest/cli.c b/nest/cli.c
index 09ebe96..f094a7c 100644
--- a/nest/cli.c
+++ b/nest/cli.c
@@ -17,44 +17,68 @@ 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<line overflow>", 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, "<line overflow>");
+ 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)
{
struct cli_out *o, *p;
if (o = c->tx_buf)
{
- c->tx_write = o;
+ c->tx_write = NULL;
o->wpos = o->outpos = o->buf;
while (p = o->next)
{
@@ -65,38 +89,34 @@ cli_free_out(cli *c)
}
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)
+ if (c->tx_pos)
+ ;
+ else if (c->cont)
+ c->cont(c);
+ else
{
- 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)
+ cli_printf(c, 9000, "Command too long");
+ else
+ {
+ cli_printf(c, -9001, "Parse error in:");
+ cli_printf(c, 9001, c->rx_buf);
+ }
}
- 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;
+ if (cli_write(c))
+ {
+ cli_free_out(c);
+ return 1;
+ }
+ return 0;
}
cli *
@@ -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 69271fe..9670f69 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