]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
kresc: add a mock-up of the client
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 11 Nov 2016 20:51:11 +0000 (21:51 +0100)
committerŠtěpán Balážik <stepan.balazik@nic.cz>
Fri, 3 Feb 2017 18:29:12 +0000 (19:29 +0100)
The build system is prepared for libedit.

Makefile
daemon/daemon.mk
daemon/kresc.c [new file with mode: 0644]

index c52877e446620fcb7157ee3d4fb1a2be226549a8..ecd964cba195d377520926825b5c16a2cbf9137a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,10 +2,11 @@ include config.mk
 include platform.mk
 
 # Targets
-all: info lib daemon modules
-install: lib-install daemon-install modules-install etc-install
+all: info lib daemon client modules
+install: lib-install daemon-install client-install modules-install etc-install
 check: all tests
-clean: contrib-clean lib-clean daemon-clean modules-clean tests-clean doc-clean bench-clean
+clean: contrib-clean lib-clean daemon-clean client-clean modules-clean \
+       tests-clean doc-clean bench-clean
 doc: doc-html
 .PHONY: all install check clean doc info
 
@@ -33,6 +34,7 @@ $(eval $(call find_lib,hiredis,,yes))
 $(eval $(call find_lib,socket_wrapper))
 $(eval $(call find_lib,libsystemd,227))
 $(eval $(call find_lib,gnutls))
+$(eval $(call find_lib,libedit))
 
 # Lookup SONAME
 $(eval $(call find_soname,libknot))
@@ -109,6 +111,7 @@ info:
        $(info [$(HAS_nettle)] nettle (modules/cookies))
        $(info [$(HAS_ltn12)] Lua socket ltn12 (trust anchor bootstrapping))
        $(info [$(HAS_ssl.https)] Lua ssl.https (trust anchor bootstrapping))
+       $(info [$(HAS_libedit)] libedit (client))
        $(info )
 
 # Verify required dependencies are met, as listed above
index 2ab212133471a1a5ef04eb531e927b4d07658096..ca0e3908340c077bc12dde75a671283a6a07890e 100644 (file)
@@ -58,4 +58,15 @@ daemon/lua/kres-gen.lua: | $(libkres)
        daemon/lua/kres-gen.sh > $@
 .DELETE_ON_ERROR: daemon/lua/kres-gen.lua
 
-.PHONY: daemon daemon-install daemon-clean
+# Client
+ifeq ($(HAS_libedit), yes)
+kresc_SOURCES := daemon/kresc.c
+kresc_CFLAGS += -fPIE $(libedit_CFLAGS)
+kresc_LIBS += $(libedit_LIBS)
+$(eval $(call make_sbin,kresc,daemon,yes))
+client: $(kresc)
+client-install: kresc-install
+client-clean: kresc-clean
+endif
+
+.PHONY: daemon daemon-install daemon-clean client client-install client-clean
\ No newline at end of file
diff --git a/daemon/kresc.c b/daemon/kresc.c
new file mode 100644 (file)
index 0000000..9c36ec9
--- /dev/null
@@ -0,0 +1,124 @@
+/*  Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+FILE *g_tty = NULL;            //!< connection to the daemon
+
+//! Initialize connection to the daemon; return 0 on success.
+static int init_tty(const char *path)
+{
+       int fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (fd < 0)
+               return 1;
+
+       struct sockaddr_un addr;
+       addr.sun_family = AF_UNIX;
+       size_t plen = strlen(path);
+       if (plen + 1 > sizeof(addr.sun_path)) {
+               fprintf(stderr, "Path too long\n");
+               return 1;
+       }
+       memcpy(addr.sun_path, path, plen + 1);
+       if (connect(fd, (const struct sockaddr *)&addr, sizeof(addr))) {
+               perror("While connecting to daemon");
+               return 1;
+       }
+
+       g_tty = fdopen(fd, "r+");
+       if (!g_tty) {
+               perror("While opening TTY");
+
+               return 1;
+       }
+       // Switch to binary mode and consume the text "> ".
+       if (fprintf(g_tty, "__binary\n") < 0 || !fread(&addr, 2, 1, g_tty)
+           || fflush(g_tty)) {
+               perror("While initializing TTY");
+               return 1;
+       }
+
+       return 0;
+}
+
+//! Run a command on the daemon; return the answer or NULL on failure.
+static char *run_cmd(const char *cmd)
+{
+       if (!g_tty || !cmd) {
+               assert(false);
+               return NULL;
+       }
+       if (fprintf(g_tty, "%s", cmd) < 0 || fflush(g_tty))
+               return NULL;
+       uint32_t len;
+       if (!fread(&len, sizeof(len), 1, g_tty))
+               return NULL;
+       char *msg = malloc(len);
+       if (!msg)
+               return NULL;
+       if (!fread(msg, len, 1, g_tty)) {
+               free(msg);
+               return NULL;
+       }
+       return msg;
+}
+
+//! Prototype; TODO: editline.
+static int interact()
+{
+       char *buf = NULL;
+       size_t buf_len = 0;
+       ssize_t len;
+       while (getline(&buf, &buf_len, stdin) >= 0) {
+               char *msg = run_cmd(buf);
+               if (!msg) {
+                       perror("While communication with daemon");
+                       free(buf);
+                       return 1;
+               }
+               printf("%s", msg);
+               free(msg);
+       }
+       free(buf);
+
+       if (feof(stdin))
+               return 0;
+       perror("While reading input");
+       return 1;
+}
+
+int main(int argc, char **argv)
+{
+       if (argc != 2) {
+               fprintf(stderr, "Usage: %s tty/xxxxx\n", argv[0]);
+               return 1;
+       }
+
+       int res = init_tty(argv[1]);
+
+       if (!res)
+               res = interact();
+
+       if (g_tty)
+               fclose(g_tty);
+       return res;
+}