From f449f278dd3c70e479a035f50a9bb817a9b433ba Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 17:24:08 +0200 Subject: Adding upstream version 3.2.6. Signed-off-by: Daniel Baumann --- src/knot/ctl/process.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/knot/ctl/process.c (limited to 'src/knot/ctl/process.c') diff --git a/src/knot/ctl/process.c b/src/knot/ctl/process.c new file mode 100644 index 0000000..50fde21 --- /dev/null +++ b/src/knot/ctl/process.c @@ -0,0 +1,128 @@ +/* Copyright (C) 2022 CZ.NIC, z.s.p.o. + + 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 . + */ + +#include "knot/common/log.h" +#include "knot/ctl/commands.h" +#include "knot/ctl/process.h" +#include "libknot/error.h" +#include "contrib/string.h" + +int ctl_process(knot_ctl_t *ctl, server_t *server) +{ + if (ctl == NULL || server == NULL) { + return KNOT_EINVAL; + } + + ctl_args_t args = { + .ctl = ctl, + .type = KNOT_CTL_TYPE_END, + .server = server + }; + + // Strip redundant/unprocessed data units in the current block. + bool strip = false; + + while (true) { + // Receive data unit. + int ret = knot_ctl_receive(args.ctl, &args.type, &args.data); + if (ret != KNOT_EOK) { + log_ctl_debug("control, failed to receive (%s)", + knot_strerror(ret)); + return ret; + } + + // Decide what to do. + switch (args.type) { + case KNOT_CTL_TYPE_DATA: + // Leading data unit with a command name. + if (!strip) { + // Set to strip unprocessed data unit. + strip = true; + break; + } + // FALLTHROUGH + case KNOT_CTL_TYPE_EXTRA: + // All non-first data units should be parsed in a callback. + // Ignore if probable previous error. + continue; + case KNOT_CTL_TYPE_BLOCK: + strip = false; + continue; + case KNOT_CTL_TYPE_END: + return KNOT_EOF; + default: + assert(0); + } + + strtolower((char *)args.data[KNOT_CTL_IDX_ZONE]); + + const char *cmd_name = args.data[KNOT_CTL_IDX_CMD]; + const char *zone_name = args.data[KNOT_CTL_IDX_ZONE]; + + ctl_cmd_t cmd = ctl_str_to_cmd(cmd_name); + if (cmd == CTL_CONF_LIST) { + log_ctl_debug("control, received command '%s'", cmd_name); + } else if (cmd != CTL_NONE) { + if (zone_name != NULL) { + log_ctl_zone_str_info(zone_name, + "control, received command '%s'", cmd_name); + } else { + log_ctl_info("control, received command '%s'", cmd_name); + } + } else if (cmd_name != NULL){ + log_ctl_debug("control, invalid command '%s'", cmd_name); + continue; + } else { + log_ctl_debug("control, empty command"); + continue; + } + + // Execute the command. + int cmd_ret = ctl_exec(cmd, &args); + switch (cmd_ret) { + case KNOT_EOK: + strip = false; + case KNOT_CTL_ESTOP: + case KNOT_CTL_EZONE: + // KNOT_CTL_EZONE - don't change strip, but don't be reported + // as a ctl/communication error either. + break; + default: + log_ctl_debug("control, command '%s' (%s)", cmd_name, + knot_strerror(cmd_ret)); + break; + } + + // Finalize the answer block. + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_BLOCK, NULL); + if (ret != KNOT_EOK) { + log_ctl_debug("control, failed to reply (%s)", + knot_strerror(ret)); + } + + // Stop if required. + if (cmd_ret == KNOT_CTL_ESTOP) { + // Finalize the answer message. + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_END, NULL); + if (ret != KNOT_EOK) { + log_ctl_debug("control, failed to reply (%s)", + knot_strerror(ret)); + } + + return cmd_ret; + } + } +} -- cgit v1.2.3