summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--src/vy_adapter.cpp262
-rw-r--r--src/vy_adapter.h33
3 files changed, 297 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 2170f95..6ef8d64 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -52,6 +52,7 @@ src_libvyatta_cfg_la_SOURCES += src/cnode/cnode-algorithm.cpp
src_libvyatta_cfg_la_SOURCES += src/cparse/cparse.cpp
src_libvyatta_cfg_la_SOURCES += src/cparse/cparse_lex.c
src_libvyatta_cfg_la_SOURCES += src/commit/commit-algorithm.cpp
+src_libvyatta_cfg_la_SOURCES += src/vy_adapter.cpp
CLEANFILES = src/cli_parse.c src/cli_parse.h src/cli_def.c src/cli_val.c
CLEANFILES += src/cparse/cparse.cpp src/cparse/cparse.h
CLEANFILES += src/cparse/cparse_lex.c
@@ -61,6 +62,7 @@ LDADD += $(GOBJECT_LIBS)
vincludedir = $(includedir)/vyatta-cfg
vinclude_HEADERS = src/cli_cstore.h
+vinclude_HEADERS += src/vy_adapter.h
vcincdir = $(vincludedir)/cstore
vcinc_HEADERS = src/cstore/cstore-c.h
diff --git a/src/vy_adapter.cpp b/src/vy_adapter.cpp
new file mode 100644
index 0000000..cf2f50e
--- /dev/null
+++ b/src/vy_adapter.cpp
@@ -0,0 +1,262 @@
+/* Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstring>
+#include <cstdlib>
+#include <vector>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <cstdint>
+#include <cassert>
+#include <algorithm>
+#include <list>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <cstore/cstore.hpp>
+#include <vy_adapter.h>
+
+using namespace cstore;
+
+enum PIPES { READ, WRITE };
+
+extern FILE *out_stream;
+
+class stdout_redirect {
+ public:
+ stdout_redirect(): old_stdout(0), redirecting(false) {
+ out_pipe[READ] = 0;
+ out_pipe[WRITE] = 0;
+ if (pipe(out_pipe) == -1) {
+ return;
+ }
+
+ old_stdout = dup(fileno(stdout));
+ setbuf(stdout, NULL);
+ dup2(out_pipe[WRITE], fileno(stdout));
+
+ redirecting = true;
+ }
+
+ std::string get_redirected_output() {
+ if (!redirecting) {
+ return "";
+ }
+
+ char buffer[1024];
+ ssize_t bytesRead = 0;
+ std::string redirected_output = "\n";
+ fcntl(out_pipe[READ], F_SETFL, O_NONBLOCK);
+ while ((bytesRead = read(out_pipe[READ], buffer, sizeof(buffer))) > 0) {
+ redirected_output.append(buffer, bytesRead);
+ }
+
+ return redirected_output;
+ }
+
+ ~stdout_redirect() {
+ if (!redirecting) {
+ return;
+ }
+
+ dup2(old_stdout, fileno(stdout));
+
+ if (old_stdout > 0) {
+ close(old_stdout);
+ }
+ if (out_pipe[READ] > 0) {
+ close(out_pipe[READ]);
+ }
+ if (out_pipe[WRITE] > 0) {
+ close(out_pipe[WRITE]);
+ }
+ }
+
+ private:
+ int out_pipe[2];
+ int old_stdout;
+ bool redirecting;
+};
+
+struct cstore_obj {
+ Cstore *cstore;
+ std::list<char *> output;
+};
+
+static struct cstore_obj* create_handle() {
+ struct cstore_obj *h = new cstore_obj;
+ h->cstore = Cstore::createCstore(false);
+ return h;
+};
+
+const char *out_data_copy(std::string msg, cstore_obj *o)
+{
+ size_t len = msg.length();
+ char *out_data = (char *) malloc(len + 1);
+ o->output.push_back(out_data);
+ msg.copy(out_data, len);
+ out_data[len] = '\0';
+ return out_data;
+}
+
+static uint64_t uint_of_voidptr(void* p)
+{
+ assert (((uintptr_t) p & 1) == 0);
+ return (uint64_t) p | 1;
+}
+
+static void *voidptr_of_uint(uint64_t v)
+{
+ return (void *)(uintptr_t)(v & ~1);
+}
+
+static cstore_obj *cstore_obj_of_handle(uint64_t handle)
+{
+ return (cstore_obj *) voidptr_of_uint(handle);
+}
+
+uint64_t
+vy_cstore_init(void)
+{
+ cstore_obj *handle = create_handle();
+ return uint_of_voidptr(handle);
+}
+
+void
+vy_cstore_free(uint64_t handle)
+{
+ cstore_obj *h = cstore_obj_of_handle(handle);
+ for (char * x: h->output) {
+ free(x);
+ }
+ delete h->cstore;
+ delete h;
+}
+
+int
+vy_in_session(uint64_t handle)
+{
+ Cstore *h = cstore_obj_of_handle(handle)->cstore;
+ return h->inSession() ? 1 : 0;
+}
+
+const char *
+vy_validate_path(uint64_t handle, const void** path_ptr, size_t len)
+{
+ cstore_obj *obj = cstore_obj_of_handle(handle);
+ Cstore *cstore = obj->cstore;
+ const char **path = (const char **) path_ptr;
+ Cpath path_comps = Cpath(path, len);
+ const char *out_data;
+ std::string out_str = "";
+ int res;
+
+ out_stream = stdout;
+ stdout_redirect redirect = stdout_redirect();
+
+ res = cstore->validateSetPath(path_comps);
+ if (!res) {
+ out_str = "\nInvalid set path: " + path_comps.to_string() + "\n";
+ out_str.append(redirect.get_redirected_output());
+ }
+
+ out_data = out_data_copy(out_str, obj);
+ out_stream = NULL;
+ return out_data;
+}
+
+const char *
+vy_set_path(uint64_t handle, const void** path_ptr, size_t len)
+{
+ cstore_obj *obj = cstore_obj_of_handle(handle);
+ Cstore *cstore = obj->cstore;
+ const char **path = (const char **) path_ptr;
+ Cpath path_comps = Cpath(path, len);
+ const char *out_data;
+ std::string out_str = "";
+ int res;
+
+ out_stream = stdout;
+ stdout_redirect redirect = stdout_redirect();
+
+ res = cstore->setCfgPath(path_comps);
+ if (!res) {
+ out_str = "\nSet config path failed: " + path_comps.to_string() + "\n";
+ out_str.append(redirect.get_redirected_output());
+ }
+
+ out_data = out_data_copy(out_str, obj);
+ out_stream = NULL;
+ return out_data;
+}
+
+const char *
+vy_legacy_set_path(uint64_t handle, const void** path_ptr, size_t len)
+{
+ cstore_obj *obj = cstore_obj_of_handle(handle);
+ Cstore *cstore = obj->cstore;
+ const char **path = (const char **) path_ptr;
+ Cpath path_comps = Cpath(path, len);
+ const char *out_data;
+ std::string out_str = "";
+ int res;
+
+ out_stream = stdout;
+ stdout_redirect redirect = stdout_redirect();
+
+ res = cstore->validateSetPath(path_comps);
+ if (!res) {
+ out_str = "\nInvalid set path: " + path_comps.to_string() + "\n";
+ out_str.append(redirect.get_redirected_output());
+ goto out;
+ }
+
+ res = cstore->setCfgPath(path_comps);
+ if (!res) {
+ out_str = "\nSet config path failed: " + path_comps.to_string() + "\n";
+ out_str.append(redirect.get_redirected_output());
+ }
+
+out:
+ out_data = out_data_copy(out_str, obj);
+ out_stream = NULL;
+ return out_data;
+}
+
+const char *
+vy_delete_path(uint64_t handle, const void** path_ptr, size_t len)
+{
+ cstore_obj *obj = cstore_obj_of_handle(handle);
+ Cstore *cstore = obj->cstore;
+ const char **path = (const char **) path_ptr;
+ Cpath path_comps = Cpath(path, len);
+ const char *out_data;
+ std::string out_str = "";
+ int res;
+
+ out_stream = stdout;
+ stdout_redirect redirect = stdout_redirect();
+
+ res = cstore->deleteCfgPath(path_comps);
+ if (!res) {
+ out_str = "\nDelete failed: " + path_comps.to_string() + "\n";
+ out_str.append(redirect.get_redirected_output());
+ }
+
+ out_data = out_data_copy(out_str, obj);
+ out_stream = NULL;
+ return out_data;
+}
diff --git a/src/vy_adapter.h b/src/vy_adapter.h
new file mode 100644
index 0000000..636c303
--- /dev/null
+++ b/src/vy_adapter.h
@@ -0,0 +1,33 @@
+/* Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _VY_ADAPTER_H_
+#define _VY_ADAPTER_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint64_t vy_cstore_init(void);
+void vy_cstore_free(uint64_t);
+int vy_in_session(uint64_t);
+const char *vy_validate_path(uint64_t, const void **, size_t);
+const char *vy_set_path(uint64_t, const void **, size_t);
+const char *vy_legacy_set_path(uint64_t, const void **, size_t);
+const char *vy_delete_path(uint64_t, const void **, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+#endif