Commit dd25497c authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Move cli_dispatch into cli_serve.c and unroll stuff that only needs to

be done once.

Finally make the cli structure a miniobj.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@4474 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent edd5bb42
......@@ -94,7 +94,7 @@ CLI_AddFuncs(enum cli_set_e which, struct cli_proto *p)
}
static void
cli_cb_before(struct cli *cli)
cli_cb_before(const struct cli *cli)
{
VSL(SLT_CLI, 0, "Rd %s", cli->cmd);
......@@ -104,7 +104,7 @@ cli_cb_before(struct cli *cli)
}
static void
cli_cb_after(struct cli *cli)
cli_cb_after(const struct cli *cli)
{
Lck_Unlock(&cli_mtx);
VSL(SLT_CLI, 0, "Wr %03u %s", cli->result, vsb_data(cli->sb));
......
......@@ -381,7 +381,7 @@ mcf_help(struct cli *cli, const char * const *av, void *priv)
/*--------------------------------------------------------------------*/
static void
mgt_cli_cb_before(struct cli *cli)
mgt_cli_cb_before(const struct cli *cli)
{
if (params->syslog_cli_traffic)
......@@ -389,7 +389,7 @@ mgt_cli_cb_before(struct cli *cli)
}
static void
mgt_cli_cb_after(struct cli *cli)
mgt_cli_cb_after(const struct cli *cli)
{
if (params->syslog_cli_traffic)
......
......@@ -32,7 +32,8 @@
struct vlu;
struct cli {
/* XXX: should be MINI_OBJ */
unsigned magic;
#define CLI_MAGIC 0x4038d570
struct vsb *sb;
enum cli_status_e result;
const char *cmd;
......
......@@ -58,7 +58,6 @@ void cli_quote(struct cli *cli, const char *str);
void cli_result(struct cli *cli, unsigned r);
/* From libvarnish/cli.c */
void cli_dispatch(struct cli *cli, struct cli_proto *clp, const char *line);
cli_func_t cli_func_help;
cli_func_t cli_func_ping;
struct cli_proto *cli_concat(struct cli_proto *, struct cli_proto *);
......@@ -31,7 +31,7 @@
struct cls;
typedef void cls_cb_f(void *priv);
typedef void cls_cbc_f(struct cli*);
typedef void cls_cbc_f(const struct cli*);
struct cls *CLS_New(cls_cbc_f *before, cls_cbc_f *after, unsigned maxlen);
struct cli *CLS_AddFd(struct cls *cs, int fdi, int fdo, cls_cb_f *closefunc,
void *priv);
......
......@@ -71,75 +71,6 @@ cli_func_help(struct cli *cli, const char * const *av, void *priv)
cli_out(cli, "Unknown request.\nType 'help' for more info.\n");
cli_result(cli, CLIS_UNKNOWN);
}
void
cli_dispatch(struct cli *cli, struct cli_proto *clp, const char *line)
{
char **av;
unsigned u;
struct cli_proto *cp;
cli_result(cli, CLIS_OK);
/* XXX: syslog commands */
av = ParseArgv(line, 0);
AN(av);
do {
if (av[0] != NULL) {
cli_out(cli, "Syntax Error: %s\n", av[0]);
cli_result(cli, CLIS_SYNTAX);
break;
}
if (av[1] == NULL)
break;
if (isupper(av[1][0])) {
cli_out(cli,
"all commands are in lower-case.\n");
cli_result(cli, CLIS_UNKNOWN);
break;
}
for (cp = clp; cp->request != NULL; cp++) {
if (!strcmp(av[1], cp->request))
break;
if (!strcmp("*", cp->request))
break;
}
if (cp->request == NULL) {
cli_out(cli,
"Unknown request.\nType 'help' for more info.\n");
cli_result(cli, CLIS_UNKNOWN);
break;
}
if (cp->func == NULL) {
cli_out(cli, "Unimplemented\n");
cli_result(cli, CLIS_UNIMPL);
break;
}
for (u = 0; u <= cp->minarg; u++) {
if (av[u + 1] != NULL)
continue;
cli_out(cli, "Too few parameters\n");
cli_result(cli, CLIS_TOOFEW);
break;
}
if (u <= cp->minarg)
break;
for (; u <= cp->maxarg; u++)
if (av[u + 1] == NULL)
break;
if (av[u + 1] != NULL) {
cli_out(cli, "Too many parameters\n");
cli_result(cli, CLIS_TOOMANY);
break;
}
cp->func(cli, (const char * const *)av, cp->priv);
} while (0);
FreeArgv(av);
}
struct cli_proto *
cli_concat(struct cli_proto *c1, struct cli_proto *c2)
{
......
......@@ -80,46 +80,132 @@ struct cls {
unsigned maxlen;
};
/*--------------------------------------------------------------------
* Look for a CLI command to execute
*/
static int
cls_dispatch(struct cli *cli, struct cli_proto *clp, char * const * av,
unsigned ac)
{
struct cli_proto *cp;
AN(av);
for (cp = clp; cp->request != NULL; cp++) {
if (!strcmp(av[1], cp->request))
break;
if (!strcmp("*", cp->request))
break;
}
if (cp->request == NULL)
return (0);
if (cp->func == NULL) {
cli_out(cli, "Unimplemented\n");
cli_result(cli, CLIS_UNIMPL);
return(1);
}
if (ac - 1 < cp->minarg) {
cli_out(cli, "Too few parameters\n");
cli_result(cli, CLIS_TOOFEW);
return(1);
}
if (ac - 1> cp->maxarg) {
cli_out(cli, "Too many parameters\n");
cli_result(cli, CLIS_TOOMANY);
return(1);
}
cli->result = CLIS_OK;
vsb_clear(cli->sb);
cp->func(cli, (const char * const *)av, cp->priv);
return (1);
}
/*--------------------------------------------------------------------
* We have collected a full cli line, parse it and execute, if possible.
*/
static int
cls_vlu(void *priv, const char *p)
{
struct cls_fd *cfd;
struct cls *cs;
struct cls_func *cfn;
struct cli *cli;
char * * av;
unsigned na;
CAST_OBJ_NOTNULL(cfd, priv, CLS_FD_MAGIC);
cs = cfd->cls;
CHECK_OBJ_NOTNULL(cs, CLS_MAGIC);
/* Skip whitespace */
cli = cfd->cli;
CHECK_OBJ_NOTNULL(cli, CLI_MAGIC);
AZ(cli->cmd);
/*
* Lines with only whitespace are simply ignored, in order to not
* complicate CLI-client side scripts and TELNET users
*/
for (; isspace(*p); p++)
continue;
/* Ignore empty lines */
if (*p == '\0')
return (0);
cfd->cli->cmd = p;
cli->cmd = p;
av = ParseArgv(p, 0);
AN(av);
cli->result = CLIS_UNKNOWN;
vsb_clear(cli->sb);
cli_out(cli, "Unknown request.\nType 'help' for more info.\n");
if (cs->before != NULL)
cs->before(cfd->cli);
vsb_clear(cfd->cli->sb);
cfd->cli->result = CLIS_UNKNOWN;
VTAILQ_FOREACH(cfn, &cs->funcs, list) {
if (cfn->auth > cfd->cli->auth)
continue;
vsb_clear(cfd->cli->sb);
cfd->cli->result = CLIS_OK;
cli_dispatch(cfd->cli, cfn->clp, p);
if (cfd->cli->result != CLIS_UNKNOWN)
cs->before(cli);
do {
if (av[0] != NULL) {
cli_out(cli, "Syntax Error: %s\n", av[0]);
cli_result(cli, CLIS_SYNTAX);
break;
}
vsb_finish(cfd->cli->sb);
AZ(vsb_overflowed(cfd->cli->sb));
}
if (isupper(av[1][0])) {
cli_out(cli, "all commands are in lower-case.\n");
cli_result(cli, CLIS_UNKNOWN);
break;
}
if (!islower(av[1][0]))
break;
for (na = 0; av[na + 1] != NULL; na++)
continue;
VTAILQ_FOREACH(cfn, &cs->funcs, list) {
if (cfn->auth > cli->auth)
continue;
if (cls_dispatch(cli, cfn->clp, av, na))
break;
}
} while (0);
vsb_finish(cli->sb);
AZ(vsb_overflowed(cli->sb));
if (cs->after != NULL)
cs->after(cfd->cli);
if (cli_writeres(cfd->fdo, cfd->cli) || cfd->cli->result == CLIS_CLOSE)
cs->after(cli);
cli->cmd = NULL;
FreeArgv(av);
if (cli_writeres(cfd->fdo, cli) || cli->result == CLIS_CLOSE)
return (1);
cfd->cli->cmd = NULL;
return (0);
}
......@@ -152,6 +238,7 @@ CLS_AddFd(struct cls *cs, int fdi, int fdo, cls_cb_f *closefunc, void *priv)
cfd->fdi = fdi;
cfd->fdo = fdo;
cfd->cli = &cfd->clis;
cfd->cli->magic = CLI_MAGIC;
cfd->cli->vlu = VLU_New(cfd, cls_vlu, cs->maxlen);
cfd->cli->sb = vsb_newauto();
cfd->closefunc = closefunc;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment