From: Sebastian Harl Date: Thu, 9 Jan 2014 06:47:46 +0000 (+0100) Subject: sysdb: Implemented input scanner and simple command handling. X-Git-Tag: sysdb-0.1.0~246 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=a006a526f16e790dbeae6ef96ed61f506310b66f sysdb: Implemented input scanner and simple command handling. 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. --- diff --git a/src/Makefile.am b/src/Makefile.am index 352bf88..9206e27 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 0000000..3b64def --- /dev/null +++ b/src/tools/sysdb/command.c @@ -0,0 +1,91 @@ +/* + * SysDB - src/tools/sysdb/command.c + * Copyright (C) 2014 Sebastian 'tokkee' Harl + * 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 +#include + +/* + * 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 index 0000000..3cf9fca --- /dev/null +++ b/src/tools/sysdb/command.h @@ -0,0 +1,47 @@ +/* + * SysDB - src/tools/sysdb/command.h + * Copyright (C) 2014 Sebastian 'tokkee' Harl + * 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 : */ + diff --git a/src/tools/sysdb/input.c b/src/tools/sysdb/input.c index 72e360c..d5deb1d 100644 --- a/src/tools/sysdb/input.c +++ b/src/tools/sysdb/input.c @@ -60,14 +60,14 @@ */ 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 */ diff --git a/src/tools/sysdb/input.h b/src/tools/sysdb/input.h index 4632b4f..7fd8d58 100644 --- a/src/tools/sysdb/input.h +++ b/src/tools/sysdb/input.h @@ -25,18 +25,21 @@ * 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: diff --git a/src/tools/sysdb/main.c b/src/tools/sysdb/main.c index d895de7..06f4de2 100644 --- a/src/tools/sysdb/main.c +++ b/src/tools/sysdb/main.c @@ -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 */ diff --git a/src/tools/sysdb/scanner.l b/src/tools/sysdb/scanner.l index 07a9413..c9b527e 100644 --- a/src/tools/sysdb/scanner.l +++ b/src/tools/sysdb/scanner.l @@ -33,13 +33,19 @@ */ #include "tools/sysdb/input.h" +#include "tools/sysdb/command.h" + +#include #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_inside} { APPEND(); } +{csc_end} { APPEND(); BEGIN(INITIAL); } +<> { return -1; } + +{identifier} { APPEND(); } + + /* + * The following rules are specific to the command line tool. + */ + +";" { APPEND(); sdb_command_exec(sdb_input); } + +. { APPEND(); } %%