]> err.no Git - varnish/commitdiff
Change the CLI protocol in a subtle but useful way:
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 4 Aug 2006 06:53:26 +0000 (06:53 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 4 Aug 2006 06:53:26 +0000 (06:53 +0000)
The first line of the response has a fixed format ("%-3d %-8u\n")
and consequently fixed length (CLI_LINE0_LEN == 13).

This makes parsing responses more efficient.  Add a function
in common_cli to do so.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@630 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/common_cli.c
varnish-cache/bin/varnishd/common_cli.h
varnish-cache/bin/varnishd/mgt_cli.c
varnish-cache/include/cli.h

index 932b169db4d4fc13dfa733707d51ee4550df95e2..2ff16d522c4738370ff57ef11d479222ab791ae9 100644 (file)
@@ -52,9 +52,14 @@ cli_writeres(int fd, struct cli *cli)
 {
        int i, l;
        struct iovec iov[3];
-       char res[32];
+       char res[CLI_LINE0_LEN + 2];    /*
+                                        * NUL + one more so we can catch
+                                        * any misformats by snprintf
+                                        */
 
-       sprintf(res, "%d %d\n", cli->result, sbuf_len(cli->sb));
+       i = snprintf(res, sizeof res,
+           "%-3d %-8d\n", cli->result, sbuf_len(cli->sb));
+       assert(i == CLI_LINE0_LEN);
        iov[0].iov_base = (void*)(uintptr_t)res;
        iov[1].iov_base = (void*)(uintptr_t)sbuf_data(cli->sb);
        iov[2].iov_base = (void*)(uintptr_t)"\n";
@@ -65,3 +70,36 @@ cli_writeres(int fd, struct cli *cli)
        i = writev(fd, iov, 3);
        return (i != l);
 }
+
+int
+cli_readres(int fd, unsigned *status, char **ptr)
+{
+       char res[CLI_LINE0_LEN + 1];    /* For NUL */
+       int i, j;
+       unsigned u, v;
+       char *p;
+
+       i = read(fd, res, CLI_LINE0_LEN);
+       if (i < 0)
+               return (i);
+       assert(i == CLI_LINE0_LEN);     /* XXX: handle */
+       assert(res[3] == ' ');
+       assert(res[CLI_LINE0_LEN - 1] == '\n');
+       j = sscanf(res, "%u %u\n", &u, &v);
+       assert(j == 2);
+       if (status != NULL)
+               *status = u;
+       p = malloc(v + 1);
+       assert(p != NULL);
+       i = read(fd, p, v + 1);
+       if (i < 0)
+               return (i);
+       assert(i == v + 1);
+       assert(p[v] == '\n');
+       p[v] = '\0';
+       if (ptr == NULL)
+               free(p);
+       else
+               *ptr = p;
+       return (0);
+}
index 5c62b13fa871bc2e800c8b3c4f37cb9942f0c3d3..fedeaaa83764eb713498b6732626221db35f77fc 100644 (file)
@@ -13,4 +13,5 @@ struct cli {
 void cli_suspend(struct cli *cli);
 void cli_resume(struct cli *cli);
 int cli_writeres(int fd, struct cli *cli);
+int cli_readres(int fd, unsigned *status, char **ptr);
 extern struct cli_proto CLI_cmds[];
index 0b6b3b22fe9e456e7ad8c95f8e31a81e49ba00bc..e6630b174bb63e7c1ae7c4ed8d96a46e2ad312de 100644 (file)
@@ -37,18 +37,21 @@ mcf_server_startstop(struct cli *cli, char **av, void *priv)
 }
 
 /*--------------------------------------------------------------------
- * Passthru of cli commands.
+ * Passthru of cli commands.  It is more or less just undoing what
+ * the cli parser did, but such is life...
  */
 
 static void
 mcf_passthru(struct cli *cli, char **av, void *priv)
 {
-       char buf[BUFSIZ], *bp, *be;
-       char *p;
+       char *p, *q, *r;
        unsigned u, v;
-       int i, j, k;
+       int i;
+
+       (void)priv;
 
        AZ(pthread_mutex_lock(&cli_mtx));
+
        /* Request */
        if (cli_o <= 0) {
                AZ(pthread_mutex_unlock(&cli_mtx));
@@ -56,46 +59,37 @@ mcf_passthru(struct cli *cli, char **av, void *priv)
                cli_out(cli, "Cache process not running");
                return;
        }
-       (void)priv;
-       bp = buf;
-       be = bp + sizeof buf;
+       v = 0;
+       for (u = 1; av[u] != NULL; u++)
+               v += strlen(av[u]) + 3;
+       p = malloc(v);
+       assert(p != NULL);
+       q = p;
        for (u = 1; av[u] != NULL; u++) {
-               v = strlen(av[u]);
-               if (5 + bp + 4 * v > be) {
-                       *bp = '\0';
-                       v = bp - buf;
-                       i = write(cli_o, buf, v);
-                       assert(i == v);
-                       bp = buf;
-               }
-               *bp++ = '"';
-               for (p = av[u]; *p; p++) {
-                       switch (*p) {
-                       case '\\':      *bp++ = '\\'; *bp++ = '\\'; break;
-                       case '\n':      *bp++ = '\\'; *bp++ = 'n'; break;
-                       case '"':       *bp++ = '\\'; *bp++ = '"'; break;
-                       default:        *bp++ = *p; break;
+               *q++ = '"';
+               for (r = av[u]; *r; r++) {
+                       switch (*r) {
+                       case '\\':      *q++ = '\\'; *q++ = '\\'; break;
+                       case '\n':      *q++ = '\\'; *q++ = 'n'; break;
+                       case '"':       *q++ = '\\'; *q++ = '"'; break;
+                       default:        *q++ = *r; break;
                        }
                }
-               *bp++ = '"';
-               *bp++ = ' ';
-       }
-       if (bp != buf) {
-               *bp++ = '\n';
-               v = bp - buf;
-               i = write(cli_o, buf, v);
-               assert(i == v);
+               *q++ = '"';
+               *q++ = ' ';
        }
-
-       /* Response */
-       i = read(cli_i, buf, sizeof buf - 1);
-       assert(i > 0);
-       buf[i] = '\0';
-       j = sscanf(buf, "%u %u\n%n", &u, &v, &k);
-       assert(j == 2);
-       assert(i == k + v + 1);
+       *q++ = '\n';
+       v = q - p;
+       i = write(cli_o, p, v);
+       assert(i == v);
+       free(p);
+
+       i = cli_readres(cli_i, &u, &p);
+       assert(i == 0);
        cli_result(cli, u);
-       cli_out(cli, "%*.*s", v, v, buf + k);
+       cli_out(cli, "%s", p);
+       free(p);
+
        AZ(pthread_mutex_unlock(&cli_mtx));
 }
 
index b6c54ea9afb5298d3d7a6b71c869412874802285..146011b08bea0eca53374352fa1f2fbde1b86d79 100644 (file)
@@ -181,3 +181,6 @@ enum cli_status_e {
        CLIS_OK         = 200,
        CLIS_CANT       = 300
 };
+
+/* Length of first line of response */
+#define CLI_LINE0_LEN  13