/*
* $Id$
+ *
+ * Public definition of the CLI protocol, part of the published Varnish-API.
+ *
+ */
+
+/*
+ * These macros define the common data for requests in the CLI protocol.
+ * The fields are:
+ * const char * request_name
+ * const char * request_syntax (for short help)
+ * const char * request_help (for long help)
+ * unsigned minimum_arguments
+ * unsigned maximum_arguments
+ *
+ * If you only want a subset of these fields do this:
+ * #define CLIF145(a,b,c,d,e) a,d,e
+ * [...]
+ * CLIF145(CLI_URL_QUERY)
+ *
*/
#define CLI_URL_QUERY \
"\tClose connection", \
0, 0
+/*
+ * Status/return codes in the CLI protocol
+ */
+
enum cli_status_e {
CLIS_SYNTAX = 100,
CLIS_UNKNOWN = 101,
--- /dev/null
+/*
+ * $Id$
+ *
+ * Varnish process internal CLI stuff.
+ *
+ * XXX: at a latter date we may want to move some to cli.h/libvarnishapi
+ *
+ */
+
+struct cli; /* NB: struct cli is opaque at this level. */
+
+typedef void cli_func_t(struct cli*, char **av, void *priv);
+
+struct cli_proto {
+ /* These must match the CLI_* macros in cli.h */
+ const char *request;
+ const char *syntax;
+ const char *help;
+ unsigned minarg;
+ unsigned maxarg;
+
+ /* Dispatch information */
+ cli_func_t *func;
+ void *priv;
+};
+
+/* The implementation must provide these functions */
+void cli_out(struct cli *cli, const char *fmt, ...);
+void cli_param(struct cli *cli);
+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;
--- /dev/null
+/*
+ * $Id$
+ *
+ * Stuff for handling the CLI protocol
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+
+#include <cli.h>
+#include <cli_priv.h>
+#include <libvarnish.h>
+
+/*
+ * Generic help function.
+ *
+ * priv must point to cli_proto array
+ */
+
+void
+cli_func_help(struct cli *cli, char **av, void *priv)
+{
+ unsigned u;
+ struct cli_proto *cp;
+
+ if (av[2] == NULL) {
+ cli_out(cli, "Available commands:\n");
+ for (cp = priv; cp->request != NULL; cp++)
+ cli_out(cli, "%s\n", cp->syntax);
+ return;
+ }
+ for (cp = priv; cp->request != NULL; cp++) {
+ if (!strcmp(cp->request, av[2])) {
+ cli_out(cli, "%s\n%s\n", cp->syntax, cp->help);
+ return;
+ }
+ }
+ cli_param(cli);
+}
+
+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);
+ 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 (cp->request == NULL) {
+ cli_out(cli,
+ "Unknown request, type '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, av, cp->priv);
+
+ } while (0);
+ FreeArgv(av);
+}