summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorVladimír Čunát <vladimir.cunat@nic.cz>2023-06-13 09:09:51 +0200
committerVladimír Čunát <vladimir.cunat@nic.cz>2023-06-28 09:32:14 +0200
commit2db9970ae0b3f8e21de79d12cd0fc42f80de09e4 (patch)
treed37d0d5c35f090542c0a95f65659ed7630998e03 /utils
parentMerge !1417: distro/pkg/deb: make manager package arch specific (diff)
downloadknot-resolver-2db9970ae0b3f8e21de79d12cd0fc42f80de09e4.tar.xz
knot-resolver-2db9970ae0b3f8e21de79d12cd0fc42f80de09e4.zip
kresc: remove this client
It's never gone beyond experiment/alpha and now we have kresctl which should be much better. Keeping installed bin/kresc could confuse users.
Diffstat (limited to 'utils')
-rw-r--r--utils/client/kresc.c458
-rw-r--r--utils/client/meson.build37
-rw-r--r--utils/meson.build1
3 files changed, 0 insertions, 496 deletions
diff --git a/utils/client/kresc.c b/utils/client/kresc.c
deleted file mode 100644
index 16782a13..00000000
--- a/utils/client/kresc.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-#include <arpa/inet.h>
-#include <contrib/ccan/asprintf/asprintf.h>
-#include <editline/readline.h>
-#include <errno.h>
-#include <histedit.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#define HISTORY_FILE "kresc_history"
-#define PROGRAM_NAME "kresc"
-
-FILE *g_tty = NULL; //!< connection to the daemon
-
-static char *run_cmd(const char *cmd, size_t * out_len);
-
-const char *prompt(EditLine * e)
-{
- return PROGRAM_NAME "> ";
-}
-
-bool starts_with(const char *a, const char *b)
-{
- if (strncmp(a, b, strlen(b)) == 0)
- return 1;
- return 0;
-}
-
-//! Returns Lua name of type of value, NULL on error. Puts length of type in name_len;
-char *get_type_name(const char *value)
-{
- if (value == NULL) {
- return NULL;
- }
-
- for (int i = 0; value[i]; i++) {
- if (value[i] == ')') {
- //Return NULL to prevent unexpected function call
- return NULL;
- }
- }
-
- char *cmd = afmt("type(%s)", value);
- if (!cmd) {
- perror("While tab-completing.");
- return NULL;
- }
-
- size_t name_len;
- char *type = run_cmd(cmd, &name_len);
- if (!type) {
- return NULL;
- }
- free(cmd);
-
- if (starts_with(type, "[")) {
- //Return "nil" on non-valid name.
- free(type);
- return strdup("nil");
- } else {
- type[strlen(type) - 1] = '\0';
- return type;
- }
-}
-
-static void complete_function(EditLine * el)
-{
- //Add left parenthesis to function name.
- el_insertstr(el, "(");
-}
-
-static void complete_members(EditLine * el, const char *str,
- const char *str_type, int str_len, char *dot)
-{
- char *table = strdup(str);
- if (!table) {
- perror("While tab-completing");
- return;
- }
- //Get only the table name (without partial member name).
- if (dot) {
- *(table + (dot - str)) = '\0';
- }
- //Insert a dot after the table name.
- if (!strncmp(str_type, "table", 5)) {
- el_insertstr(el, ".");
- str_len++;
- }
- //Check if the substring before dot is a valid table name.
- const char *t_type = get_type_name(table);
- if (t_type && !strncmp("table", t_type, 5)) {
- //Get string of members of the table.
- char *cmd =
- afmt
- ("do local s=\"\"; for i in pairs(%s) do s=s..i..\"\\n\" end return(s) end",
- table);
- if (!cmd) {
- perror("While tab-completing.");
- goto complete_members_exit;
- }
- size_t members_len;
- char *members = run_cmd(cmd, &members_len);
- free(cmd);
- if (!members) {
- perror("While communication with daemon");
- goto complete_members_exit;
- }
- //Split members by newline.
- char *members_tok = strdup(members);
- free(members);
- if (!members_tok) {
- goto complete_members_exit;
- }
- char *token = strtok(members_tok, "\n");
- int matches = 0;
- char *lastmatch = NULL;
- if (!dot || dot - str + 1 == strlen(str)) {
- //Prints all members.
- while (token) {
- char *member = afmt("%s.%s", table, token);
- const char *member_type = get_type_name(member);
- if (member && member_type) {
- printf("\n%s (%s)", member, member_type);
- free(member);
- free((void *)member_type);
- } else if (member) {
- printf("\n%s", member);
- free(member);
- }
- token = strtok(NULL, "\n");
- matches++;
- }
- } else {
- //Print members matching the current line.
- while (token) {
- if (starts_with(token, dot + 1)) {
- const char *member_type =
- get_type_name(afmt
- ("%s.%s", table,
- token));
- if (member_type) {
- printf("\n%s.%s (%s)", table,
- token, member_type);
- free((void *)member_type);
- } else {
- printf("\n%s.%s", table, token);
- }
- lastmatch = token;
- matches++;
- }
- token = strtok(NULL, "\n");
- }
-
- //Complete matching member.
- if (matches == 1) {
- el_deletestr(el, str_len);
- el_insertstr(el, table);
- el_insertstr(el, ".");
- el_insertstr(el, lastmatch);
- }
- }
- if (matches > 1) {
- printf("\n");
- }
- free(members_tok);
- }
-
-complete_members_exit:
- free(table);
- if(t_type) {
- free((void*)t_type);
- }
-}
-
-static void complete_globals(EditLine * el, const char *str, int str_len)
-{
- //Parse Lua globals.
- size_t globals_len;
- char *globals = run_cmd("_G.__orig_name_list", &globals_len);
- if (!globals) {
- perror("While tab-completing");
- return;
- }
- //Show possible globals.
- char *globals_tok = strdup(globals);
- free(globals);
- if (!globals_tok) {
- return;
- }
- char *token = strtok(globals_tok, "\n");
- int matches = 0;
- char *lastmatch = NULL;
- while (token) {
- if (str && starts_with(token, str)) {
- char *name = get_type_name(token);
- printf("\n%s (%s)", token, name);
- free(name);
- lastmatch = token;
- matches++;
- }
- token = strtok(NULL, "\n");
- }
- if (matches > 1) {
- printf("\n");
- }
- //Complete matching global.
- if (matches == 1) {
- el_deletestr(el, str_len);
- el_insertstr(el, lastmatch);
- }
- free(globals_tok);
-}
-
-static unsigned char complete(EditLine * el, int ch)
-{
- int argc, pos;
- const char **argv;
- const LineInfo *li = el_line(el);
- Tokenizer *tok = tok_init(NULL);
-
- //Tokenize current line.
- int ret = tok_line(tok, li, &argc, &argv, NULL, &pos);
-
- if (ret != 0) {
- perror("While tab-completing.");
- goto complete_exit;
- }
- //Show help.
- if (argc == 0) {
- size_t help_len;
- char *help = run_cmd("help()", &help_len);
- if (help) {
- printf("\n%s", help);
- free(help);
- } else {
- perror("While communication with daemon");
- }
- goto complete_exit;
- }
-
- if (argc > 1) {
- goto complete_exit;
- }
- //Get name of type of current line.
- const char *type = get_type_name(argv[0]);
-
- if (!type) {
- goto complete_exit;
- }
- //Get position of last dot in current line (useful for parsing table).
- char *dot = strrchr(argv[0], '.');
-
- if (strncmp(type, "table", 5) != 0 && !dot) {
- //Line is not a name of some table and there is no dot in it.
- complete_globals(el, argv[0], pos);
- } else if ((dot && strncmp(type, "nil", 3) == 0)
- || strncmp(type, "table", 5) == 0) {
- //Current line (or part of it) is a name of some table.
- complete_members(el, argv[0], type, pos, dot);
- } else if (strncmp(type, "function", 8) == 0) {
- //Current line is a function.
- complete_function(el);
- }
- if (type) {
- free((void *)type);
- }
-
-complete_exit:
- tok_reset(tok);
- tok_end(tok);
- return CC_REDISPLAY;
-}
-
-//! 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");
- close(fd);
- return 1;
- }
- memcpy(addr.sun_path, path, plen + 1);
- if (connect(fd, (const struct sockaddr *)&addr, sizeof(addr))) {
- perror("While connecting to daemon");
- close(fd);
- return 1;
- }
- g_tty = fdopen(fd, "r+");
- if (!g_tty) {
- perror("While opening TTY");
- close(fd);
- 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");
- fclose(g_tty);
- g_tty = NULL;
- return 1;
- }
-
- return 0;
-}
-
-//! Run a command on the daemon; return the answer or NULL on failure, puts answer length to out_len.
-static char *run_cmd(const char *cmd, size_t * out_len)
-{
- if (!g_tty || !cmd)
- 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;
- len = ntohl(len);
- if (!len)
- return NULL;
- char *msg = malloc(1 + (size_t) len);
- if (!msg)
- return NULL;
- if (len && !fread(msg, len, 1, g_tty)) {
- free(msg);
- return NULL;
- }
- msg[len] = '\0';
- *out_len = len;
- return msg;
-}
-
-static int interact()
-{
- EditLine *el;
- History *hist;
- int count;
- const char *line;
- HistEvent ev;
- el = el_init(PROGRAM_NAME, stdin, stdout, stderr);
- el_set(el, EL_PROMPT, prompt);
- el_set(el, EL_EDITOR, "emacs");
- el_set(el, EL_ADDFN, PROGRAM_NAME "-complete",
- "Perform " PROGRAM_NAME " completion.", complete);
- el_set(el, EL_BIND, "^I", PROGRAM_NAME "-complete", NULL);
-
- hist = history_init();
- if (hist == 0) {
- perror("While initializing command history");
- return 1;
- }
- history(hist, &ev, H_SETSIZE, 800);
- el_set(el, EL_HIST, history, hist);
-
- char *hist_file = NULL;
-
- char *data_home = getenv("XDG_DATA_HOME");
-
- //Check whether $XDG_DATA_HOME is set.
- if (!data_home || *data_home == '\0') {
- const char *home = getenv("HOME"); //This should be set on any POSIX compliant OS, even for nobody
-
- //Create necessary folders.
- char *dirs[3] =
- { afmt("%s/.local", home), afmt("%s/.local/share", home),
- afmt("%s/.local/share/knot-resolver/", home)
- };
- bool ok = true;
- for (int i = 0; i < 3; i++) {
- if (mkdir(dirs[i], 0755) && errno != EEXIST) {
- ok = false;
- break;
- }
- }
- if (ok) {
- hist_file =
- afmt("%s/.local/share/knot-resolver/" HISTORY_FILE, home);
- }
- } else {
- if (!mkdir(afmt("%s/knot-resolver/", data_home), 0755)
- || errno == EEXIST) {
- hist_file = afmt("%s/knot-resolver/" HISTORY_FILE, data_home);
- }
- }
-
- //Load history file
- if (hist_file) {
- history(hist, &ev, H_LOAD, hist_file);
- } else {
- perror("While opening history file");
- }
-
- while (1) {
- line = el_gets(el, &count);
- if (count > 0) {
- history(hist, &ev, H_ENTER, line);
- size_t msg_len;
- char *msg = run_cmd(line, &msg_len);
- if (!msg) {
- perror("While communication with daemon");
- history_end(hist);
- el_end(el);
- free(msg);
- return 1;
- }
- printf("%s", msg);
- if (msg_len > 0 && msg[msg_len - 1] != '\n') {
- printf("\n");
- }
- if (hist_file) {
- history(hist, &ev, H_SAVE, hist_file);
- }
- free(msg);
- }
- }
- history_end(hist);
- free(hist_file);
- el_end(el);
- if (feof(stdin))
- return 0;
- perror("While reading input");
- return 1;
-}
-
-int main(int argc, char **argv)
-{
- fprintf(stderr, "Warning! %s is highly experimental, use at own risk.\n", argv[0]);
- fprintf(stderr, "Please tell authors what features you expect from client utility.\n");
- 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;
-}
diff --git a/utils/client/meson.build b/utils/client/meson.build
deleted file mode 100644
index 761c2cdd..00000000
--- a/utils/client/meson.build
+++ /dev/null
@@ -1,37 +0,0 @@
-# client
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-kresc_src = files([
- 'kresc.c',
-])
-c_src_lint += kresc_src
-
-build_client = false
-if get_option('client') != 'disabled'
- message('--- client dependencies ---')
- libedit = dependency('libedit', required: false)
- if libedit.found()
- build_client = true
- else # darwin workaround: missing pkgconfig
- libedit = meson.get_compiler('c').find_library(
- 'edit', required: get_option('client') == 'enabled')
- if libedit.found()
- build_client = true
- endif
- endif
- message('---------------------------')
-endif
-
-
-if build_client
- kresc = executable(
- 'kresc',
- kresc_src,
- dependencies: [
- contrib_dep,
- libedit,
- ],
- install: true,
- install_dir: get_option('sbindir'),
- )
-endif
diff --git a/utils/meson.build b/utils/meson.build
index 931ef3c5..8bab5f2d 100644
--- a/utils/meson.build
+++ b/utils/meson.build
@@ -3,5 +3,4 @@
build_utils = get_option('utils') != 'disabled'
-subdir('client')
subdir('cache_gc')