Code

sysdb: Implemented input scanner and simple command handling.
authorSebastian Harl <sh@tokkee.org>
Thu, 9 Jan 2014 06:47:46 +0000 (07:47 +0100)
committerSebastian Harl <sh@tokkee.org>
Thu, 9 Jan 2014 06:47:46 +0000 (07:47 +0100)
Reused the frontend parser lexer to identify single queries (terminated by
semicolon). No other parsing of the command is done by the client to make the
frontend the ultimate truth in regard to the parser (including simple stuff
like comments).

The query is then sent to the daemon and the reply will be printed to the
standard output channel.

src/Makefile.am
src/tools/sysdb/command.c [new file with mode: 0644]
src/tools/sysdb/command.h [new file with mode: 0644]
src/tools/sysdb/input.c
src/tools/sysdb/input.h
src/tools/sysdb/main.c
src/tools/sysdb/scanner.l

index 352bf885d2eb5ddcd9bfec01500b0638046e99c0..9206e27c956fab434980d3658e5438880aa10651 100644 (file)
@@ -102,6 +102,7 @@ noinst_LTLIBRARIES += libsysdb_scanner.la
 libsysdb_scanner_la_SOURCES = tools/sysdb/scanner.l
 libsysdb_scanner_la_CFLAGS = -DBUILD_DATE="\"$$( date --utc '+%F %T' ) (UTC)\""
 sysdb_SOURCES = tools/sysdb/main.c include/client/sysdb.h \
+               tools/sysdb/command.c tools/sysdb/command.h \
                tools/sysdb/input.c tools/sysdb/input.h
 sysdb_CFLAGS = -DBUILD_DATE="\"$$( date --utc '+%F %T' ) (UTC)\"" \
                $(AM_CFLAGS) @READLINE_CFLAGS@
diff --git a/src/tools/sysdb/command.c b/src/tools/sysdb/command.c
new file mode 100644 (file)
index 0000000..3b64def
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * SysDB - src/tools/sysdb/command.c
+ * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_CONFIG_H
+#      include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include "tools/sysdb/command.h"
+#include "tools/sysdb/input.h"
+
+#include "frontend/proto.h"
+#include "utils/strbuf.h"
+
+#include <assert.h>
+#include <ctype.h>
+
+/*
+ * public API
+ */
+
+int
+sdb_command_exec(sdb_input_t *input)
+{
+       const char *query;
+       uint32_t query_len;
+
+       query = sdb_strbuf_string(input->input);
+       query_len = (uint32_t)input->query_len;
+
+       assert(input->query_len <= input->tokenizer_pos);
+
+       /* removing leading and trailing whitespace */
+       while (isspace((int)*query) && query_len) {
+               ++query;
+               --query_len;
+       }
+       while (query_len && (isspace((int)query[query_len - 1])
+                               || (query[query_len - 1] == ';')))
+               --query_len;
+
+       if (query_len) {
+               sdb_strbuf_t *recv_buf;
+               uint32_t rcode = 0;
+
+               recv_buf = sdb_strbuf_create(1024);
+               if (! recv_buf)
+                       return -1;
+
+               sdb_client_send(input->client, CONNECTION_QUERY, query_len, query);
+               if (sdb_client_recv(input->client, &rcode, recv_buf) < 0)
+                       rcode = UINT32_MAX;
+
+               if (rcode == UINT32_MAX)
+                       printf("ERROR: ");
+               printf("%s\n", sdb_strbuf_string(recv_buf));
+
+               sdb_strbuf_destroy(recv_buf);
+       }
+
+       sdb_strbuf_skip(input->input, 0, input->query_len);
+       input->tokenizer_pos -= input->query_len;
+       input->query_len = 0;
+       return 0;
+} /* sdb_command_exec */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
diff --git a/src/tools/sysdb/command.h b/src/tools/sysdb/command.h
new file mode 100644 (file)
index 0000000..3cf9fca
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * SysDB - src/tools/sysdb/command.h
+ * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tools/sysdb/input.h"
+
+#ifndef SYSDB_COMMAND_H
+#define SYSDB_COMMAND_H 1
+
+/*
+ * sdb_command_exec:
+ * Execute the current command buffer.
+ *
+ * Returns:
+ *  - 0 on success
+ *  - a negative value else
+ */
+int
+sdb_command_exec(sdb_input_t *input);
+
+#endif /* SYSDB_COMMAND_H */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
index 72e360cd5a87fcf61deaca181c8cc5a5ccd0a271..d5deb1dd61b9cf6f26a215ae0efba955a233a48d 100644 (file)
  */
 
 static size_t
-input_readline(sdb_strbuf_t *buf)
+input_readline(sdb_input_t *input)
 {
        const char *prompt = "sysdb=> ";
        char *line;
 
        size_t len;
 
-       if (sdb_strbuf_len(buf))
+       if (input->query_len)
                prompt = "sysdb-> ";
 
        line = readline(prompt);
@@ -77,8 +77,8 @@ input_readline(sdb_strbuf_t *buf)
 
        len = strlen(line) + 1;
 
-       sdb_strbuf_append(buf, line);
-       sdb_strbuf_append(buf, "\n");
+       sdb_strbuf_append(input->input, line);
+       sdb_strbuf_append(input->input, "\n");
        free(line);
        return len;
 } /* input_readline */
@@ -91,13 +91,12 @@ ssize_t
 sdb_input_readline(sdb_input_t *input, char *buf,
                int *n_chars, size_t max_chars)
 {
-       const char *query;
        size_t len;
 
-       len = sdb_strbuf_len(input->buf) - input->tokenizer_pos;
+       len = sdb_strbuf_len(input->input) - input->tokenizer_pos;
 
        if (! len) {
-               size_t n = input_readline(input->buf);
+               size_t n = input_readline(input);
                if (! n) {
                        *n_chars = 0; /* YY_NULL */
                        return 0;
@@ -105,18 +104,11 @@ sdb_input_readline(sdb_input_t *input, char *buf,
                len += n;
        }
 
-       query = sdb_strbuf_string(input->buf);
-
        len = (len < max_chars) ? len : max_chars;
-       strncpy(buf, sdb_strbuf_string(input->buf) + input->tokenizer_pos, len);
+       strncpy(buf, sdb_strbuf_string(input->input) + input->tokenizer_pos, len);
        input->tokenizer_pos += len;
        *n_chars = (int)len;
 
-       /* XXX */
-       if (! strchr(query, (int)';'))
-               return (ssize_t)len;
-       sdb_strbuf_clear(input->buf);
-       input->tokenizer_pos = 0;
        return (ssize_t)len;
 } /* sdb_input_readline */
 
index 4632b4f40c3b5150560363d43538caf0f7fd26c8..7fd8d587de8961f70a2107048ca782ed53a39659 100644 (file)
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "client/sock.h"
 #include "utils/strbuf.h"
 
 #ifndef SYSDB_INPUT_H
 #define SYSDB_INPUT_H 1
 
 typedef struct {
-       sdb_strbuf_t *buf;
+       sdb_client_t *client;
 
+       sdb_strbuf_t *input;
        size_t tokenizer_pos;
+       size_t query_len;
 } sdb_input_t;
 
-#define SDB_INPUT_INIT { NULL, 0 }
+#define SDB_INPUT_INIT { NULL, NULL, 0, 0 }
 
 /*
  * sdb_input_readline:
index d895de7184cb9bdb7cea1bf8b98db2939151e272..06f4de2f0fb858152a74849300173627281de1cb 100644 (file)
@@ -167,8 +167,6 @@ get_homedir(const char *username)
 int
 main(int argc, char **argv)
 {
-       sdb_client_t *client;
-
        const char *host = NULL;
        const char *user = NULL;
 
@@ -213,14 +211,14 @@ main(int argc, char **argv)
                        exit(1);
        }
 
-       client = sdb_client_create(host);
-       if (! client) {
+       input.client = sdb_client_create(host);
+       if (! input.client) {
                sdb_log(SDB_LOG_ERR, "Failed to create client object");
                exit(1);
        }
-       if (sdb_client_connect(client, user)) {
+       if (sdb_client_connect(input.client, user)) {
                sdb_log(SDB_LOG_ERR, "Failed to connect to SysDBd");
-               sdb_client_destroy(client);
+               sdb_client_destroy(input.client);
                exit(1);
        }
 
@@ -242,7 +240,7 @@ main(int argc, char **argv)
                }
        }
 
-       input.buf = sdb_strbuf_create(2048);
+       input.input = sdb_strbuf_create(2048);
        sdb_input_set(&input);
        yylex();
 
@@ -255,7 +253,8 @@ main(int argc, char **argv)
                }
        }
 
-       sdb_client_destroy(client);
+       sdb_client_destroy(input.client);
+       sdb_strbuf_destroy(input.input);
        return 0;
 } /* main */
 
index 07a941370d9eb5f419674806544d9337f3f21f36..c9b527e7d9cdb74785f891b6ea99553ff478a9b3 100644 (file)
  */
 
 #include "tools/sysdb/input.h"
+#include "tools/sysdb/command.h"
+
+#include <string.h>
 
 #ifdef YY_INPUT
 #      undef YY_INPUT
 #endif
 #define YY_INPUT(buf, result, max_size) \
+       sdb_input_readline(sdb_input, (buf), &(result), (max_size))
+
+#define APPEND() \
        do { \
-               sdb_input_readline(sdb_input, (buf), &(result), (max_size)); \
+               sdb_input->query_len += strlen(yytext); \
        } while (0)
 
 static sdb_input_t *sdb_input;
@@ -54,9 +60,39 @@ static sdb_input_t *sdb_input;
 %option verbose
 %option warn
 
+%x CSC
+
+whitespace             ([ \t\n\r\f]+)
+simple_comment ("--"[^\n\r]*)
+
+/*
+ * C style comments
+ */
+csc_start      \/\*
+csc_inside     ([^*/]+|[^*]\/|\*[^/])
+csc_end                \*\/
+
+identifier     ([A-Za-z_][A-Za-z_0-9$]*)
+
 %%
 
-. { /* do nothing */ }
+{whitespace}           { APPEND(); }
+{simple_comment}       { APPEND(); }
+
+{csc_start}                    { APPEND(); BEGIN(CSC); }
+<CSC>{csc_inside}      { APPEND(); }
+<CSC>{csc_end}         { APPEND(); BEGIN(INITIAL); }
+<CSC><<EOF>>           { return -1; }
+
+{identifier}           { APPEND(); }
+
+       /*
+        * The following rules are specific to the command line tool.
+        */
+
+";"    { APPEND(); sdb_command_exec(sdb_input); }
+
+.      { APPEND(); }
 
 %%