From e970dd7fa06c2448f9ae376177485566bae27b4b Mon Sep 17 00:00:00 2001 From: Mateo Cindric Date: Sun, 21 Feb 2021 00:03:35 +0100 Subject: [PATCH] initial commit --- .clang-format | 17 +++++ .gitignore | 5 ++ CMakeLists.txt | 54 ++++++++++++++ CompileOptions.cmake | 20 ++++++ LogOptions.cmake | 30 ++++++++ cmake/Modules/FindLIBYANG.cmake | 80 +++++++++++++++++++++ cmake/Modules/FindSYSREPO.cmake | 26 +++++++ src/interfaces.c | 121 ++++++++++++++++++++++++++++++++ src/utils/memory.c | 79 +++++++++++++++++++++ src/utils/memory.h | 28 ++++++++ 10 files changed, 460 insertions(+) create mode 100644 .clang-format create mode 100755 .gitignore create mode 100644 CMakeLists.txt create mode 100644 CompileOptions.cmake create mode 100644 LogOptions.cmake create mode 100755 cmake/Modules/FindLIBYANG.cmake create mode 100755 cmake/Modules/FindSYSREPO.cmake create mode 100644 src/interfaces.c create mode 100755 src/utils/memory.c create mode 100755 src/utils/memory.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..e364fce6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,17 @@ +Language : Cpp +BasedOnStyle: LLVM +BreakBeforeBraces : Linux +IndentWidth: 4 +TabWidth : 4 +UseTab : Always +ColumnLimit : 0 + +SortIncludes: false +AllowShortIfStatementsOnASingleLine : false +AllowShortFunctionsOnASingleLine : Empty +AlwaysBreakAfterReturnType : None +AlignAfterOpenBracket : Align +AlignOperands : true +AlignTrailingComments : true +IndentCaseLabels : true +SpaceAfterCStyleCast : true \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100755 index 00000000..64992f08 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build/ +.vscode/ +.clangd/ +.test/ +compile_commands.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..5fc72a52 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 2.8) +project(sysrepo-plugin-interfaces C) + +include(CompileOptions.cmake) + +set(PLUGIN 0 CACHE BOOL "Build a plugin") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") + +include_directories( + ${CMAKE_SOURCE_DIR}/src/ +) + +set(SOURCES + src/interfaces.c + src/utils/memory.c +) + +# get sysrepo version +find_package(PkgConfig) +if (PKG_CONFIG_FOUND) + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} "--modversion" "sysrepo" OUTPUT_VARIABLE SYSREPO_VERSION) + if(SYSREPO_VERSION) + # strip new line from string + string(STRIP ${SYSREPO_VERSION} SYSREPO_VERSION) + if(${SYSREPO_VERSION} VERSION_LESS "1.0.0") + message(FATAL_ERROR "${PROJECT_NAME} requires at least libsysrepo verision 1.0.0") + endif() + endif() +endif() + +if(PLUGIN) + add_library(${CMAKE_PROJECT_NAME} MODULE ${SOURCES}) + install(TARGETS ${CMAKE_PROJECT_NAME} DESTINATION lib) +else() + add_executable(${CMAKE_PROJECT_NAME} ${SOURCES}) + install(TARGETS ${CMAKE_PROJECT_NAME} DESTINATION bin) +endif() + +set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES OUTPUT_NAME ${CMAKE_PROJECT_NAME} PREFIX "") + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules") +find_package(SYSREPO REQUIRED) +find_package(LIBYANG REQUIRED) + +target_link_libraries( + ${PROJECT_NAME} + ${SYSREPO_LIBRARIES} + ${LIBYANG_LIBRARIES} +) + +include_directories( + ${SYSREPO_INCLUDE_DIRS} + ${LIBYANG_INCLUDE_DIRS} +) \ No newline at end of file diff --git a/CompileOptions.cmake b/CompileOptions.cmake new file mode 100644 index 00000000..00bf1a93 --- /dev/null +++ b/CompileOptions.cmake @@ -0,0 +1,20 @@ +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wuninitialized") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2") +if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=incompatible-pointer-types") +endif () +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter") +if (CMAKE_C_COMPILER_ID MATCHES "Clang") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-newline-eof") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-gnu-zero-variadic-macro-arguments") +endif() diff --git a/LogOptions.cmake b/LogOptions.cmake new file mode 100644 index 00000000..da761851 --- /dev/null +++ b/LogOptions.cmake @@ -0,0 +1,30 @@ +option(ENABLE_LOG_LOG "Enable log messages" ON) +option(ENABLE_LOG_WARNING "Enable warning messages" ON) +option(ENABLE_LOG_ERROR "Enable error messages" ON) +option(ENABLE_LOG_DEBUG1 "Enable level 1 debug messages" ON) +option(ENABLE_LOG_DEBUG2 "Enable level 2 debug messages" OFF) +option(ENABLE_LOG_DEBUG3 "Enable level 3 debug messages" OFF) + +if(ENABLE_LOG_LOG) + add_definitions(-DLOG) +endif() + +if(ENABLE_LOG_WARNING) + add_definitions(-DWARNING) +endif() + +if(ENABLE_LOG_ERROR) + add_definitions(-DERROR) +endif() + +if(ENABLE_LOG_DEBUG1) + add_definitions(-DDEBUG1) +endif() + +if(ENABLE_LOG_DEBUG2) + add_definitions(-DDEBUG2) +endif() + +if(ENABLE_LOG_DEBUG3) + add_definitions(-DDEBUG3) +endif() \ No newline at end of file diff --git a/cmake/Modules/FindLIBYANG.cmake b/cmake/Modules/FindLIBYANG.cmake new file mode 100755 index 00000000..566f2521 --- /dev/null +++ b/cmake/Modules/FindLIBYANG.cmake @@ -0,0 +1,80 @@ +# - Try to find LibYANG +# Once done this will define +# +# LIBYANG_FOUND - system has LibYANG +# LIBYANG_INCLUDE_DIRS - the LibYANG include directory +# LIBYANG_LIBRARIES - Link these to use LibSSH +# +# Author Radek Krejci +# Copyright (c) 2015 CESNET, z.s.p.o. +# +# 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 copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 (LIBYANG_LIBRARIES AND LIBYANG_INCLUDE_DIRS) + # in cache already + set(LIBYANG_FOUND TRUE) +else (LIBYANG_LIBRARIES AND LIBYANG_INCLUDE_DIRS) + + find_path(LIBYANG_INCLUDE_DIR + NAMES + libyang/libyang.h + PATHS + /usr/include + /usr/local/include + /opt/local/include + /sw/include + ${CMAKE_INCLUDE_PATH} + ${CMAKE_INSTALL_PREFIX}/include + ) + + find_library(LIBYANG_LIBRARY + NAMES + yang + libyang + PATHS + /usr/lib + /usr/lib64 + /usr/local/lib + /usr/local/lib64 + /opt/local/lib + /sw/lib + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + ) + + if (LIBYANG_INCLUDE_DIR AND LIBYANG_LIBRARY) + set(LIBYANG_FOUND TRUE) + else (LIBYANG_INCLUDE_DIR AND LIBYANG_LIBRARY) + set(LIBYANG_FOUND FALSE) + endif (LIBYANG_INCLUDE_DIR AND LIBYANG_LIBRARY) + + set(LIBYANG_INCLUDE_DIRS ${LIBYANG_INCLUDE_DIR}) + set(LIBYANG_LIBRARIES ${LIBYANG_LIBRARY}) + + # show the LIBYANG_INCLUDE_DIRS and LIBYANG_LIBRARIES variables only in the advanced view + mark_as_advanced(LIBYANG_INCLUDE_DIRS LIBYANG_LIBRARIES) + +endif (LIBYANG_LIBRARIES AND LIBYANG_INCLUDE_DIRS) + diff --git a/cmake/Modules/FindSYSREPO.cmake b/cmake/Modules/FindSYSREPO.cmake new file mode 100755 index 00000000..3d6ece20 --- /dev/null +++ b/cmake/Modules/FindSYSREPO.cmake @@ -0,0 +1,26 @@ +# SYSREPO_FOUND - System has SYSREPO +# SYSREPO_INCLUDE_DIRS - The SYSREPO include directories +# SYSREPO_LIBRARIES - The libraries needed to use SYSREPO +# SYSREPO_DEFINITIONS - Compiler switches required for using SYSREPO + +find_package(PkgConfig) +pkg_check_modules(PC_SYSREPO QUIET sysrepo) +set(SYSREPO_DEFINITIONS ${PC_SYSREPO_CFLAGS_OTHER}) + +find_path(SYSREPO_INCLUDE_DIR sysrepo.h + HINTS ${PC_SYSREPO_INCLUDEDIR} ${PC_SYSREPO_INCLUDE_DIRS} + PATH_SUFFIXES sysrepo ) + +find_library(SYSREPO_LIBRARY NAMES sysrepo + HINTS ${PC_SYSREPO_LIBDIR} ${PC_SYSREPO_LIBRARY_DIRS} ) + +set(SYSREPO_LIBRARIES ${SYSREPO_LIBRARY} ) +set(SYSREPO_INCLUDE_DIRS ${SYSREPO_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set SYSREPO_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(sysrepo DEFAULT_MSG + SYSREPO_LIBRARY SYSREPO_INCLUDE_DIR) + +mark_as_advanced(SYSREPO_INCLUDE_DIR SYSREPO_LIBRARY ) diff --git a/src/interfaces.c b/src/interfaces.c new file mode 100644 index 00000000..c102c3e7 --- /dev/null +++ b/src/interfaces.c @@ -0,0 +1,121 @@ +#include + +static int system_module_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data); +static int system_state_data_cb(sr_session_ctx_t *session, const char *module_name, const char *path, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data); +static int system_rpc_cb(sr_session_ctx_t *session, const char *op_path, const sr_val_t *input, const size_t input_cnt, sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data); + +int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_data) +{ + int error = 0; + sr_conn_ctx_t *connection = NULL; + sr_session_ctx_t *startup_session = NULL; + sr_subscription_ctx_t *subscription = NULL; + + *private_data = NULL; + + SRP_LOG_INFMSG("start session to startup datastore"); + + connection = sr_session_get_connection(session); + error = sr_session_start(connection, SR_DS_STARTUP, &startup_session); + if (error) { + SRP_LOG_ERR("sr_session_start error (%d): %s", error, sr_strerror(error)); + goto error_out; + } + + *private_data = startup_session; + + SRP_LOG_INFMSG("plugin init done"); + + goto out; + +error_out: + sr_unsubscribe(subscription); + +out: + return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; +} + +void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_data) +{ + sr_session_ctx_t *startup_session = (sr_session_ctx_t *) private_data; + + if (startup_session) { + sr_session_stop(startup_session); + } + + SRP_LOG_INFMSG("plugin cleanup finished"); +} + +static int system_module_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data) +{ + int error = 0; + return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; +} + +static int system_state_data_cb(sr_session_ctx_t *session, const char *module_name, const char *path, const char *request_xpath, uint32_t request_id, struct lyd_node **parent, void *private_data) +{ + int error = SR_ERR_OK; + return error ? SR_ERR_CALLBACK_FAILED : SR_ERR_OK; +} + +static int system_rpc_cb(sr_session_ctx_t *session, const char *op_path, const sr_val_t *input, const size_t input_cnt, sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data) +{ + int error = SR_ERR_OK; + return error; +} + +#ifndef PLUGIN +#include +#include + +volatile int exit_application = 0; + +static void sigint_handler(__attribute__((unused)) int signum); + +int main(void) +{ + int error = SR_ERR_OK; + sr_conn_ctx_t *connection = NULL; + sr_session_ctx_t *session = NULL; + void *private_data = NULL; + + sr_log_stderr(SR_LL_DBG); + + error = sr_connect(SR_CONN_DEFAULT, &connection); + if (error) { + SRP_LOG_ERR("sr_connect error (%d): %s", error, sr_strerror(error)); + goto out; + } + + error = sr_session_start(connection, SR_DS_RUNNING, &session); + if (error) { + SRP_LOG_ERR("sr_session_start error (%d): %s", error, sr_strerror(error)); + goto out; + } + + error = sr_plugin_init_cb(session, &private_data); + if (error) { + SRP_LOG_ERRMSG("sr_plugin_init_cb error"); + goto out; + } + + signal(SIGINT, sigint_handler); + signal(SIGPIPE, SIG_IGN); + while (!exit_application) { + sleep(1); + } + +out: + sr_plugin_cleanup_cb(session, private_data); + sr_disconnect(connection); + + return error ? -1 : 0; +} + +static void sigint_handler(__attribute__((unused)) int signum) +{ + SRP_LOG_INFMSG("Sigint called, exiting..."); + exit_application = 1; +} + +#endif diff --git a/src/utils/memory.c b/src/utils/memory.c new file mode 100755 index 00000000..491955b6 --- /dev/null +++ b/src/utils/memory.c @@ -0,0 +1,79 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2019 Sartura Ltd. + * + * Author: Juraj Vijtiuk + * + * https://www.sartura.hr/ + */ + +#include +#include + +#include "memory.h" + +void *xmalloc(size_t size) +{ + void *res; + + res = malloc(size); + + if (res == NULL) { + abort(); + } + + return res; +} + +void *xrealloc(void *ptr, size_t size) +{ + void *res; + + res = realloc(ptr, size); + + if (res == NULL) { + abort(); + } + + return res; +} + +void *xcalloc(size_t nmemb, size_t size) +{ + void *res; + + res = calloc(nmemb, size); + + if (res == NULL) { + abort(); + } + + return res; +} + +char *xstrdup(const char *s) +{ + char *res; + + res = strdup(s); + + if (res == NULL) { + abort(); + } + + return res; +} + +char *xstrndup(const char *s, size_t size) +{ + char *res; + + res = strndup(s, size); + + if (res == NULL) { + abort(); + } + + return res; +} diff --git a/src/utils/memory.h b/src/utils/memory.h new file mode 100755 index 00000000..622bad87 --- /dev/null +++ b/src/utils/memory.h @@ -0,0 +1,28 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2019 Sartura Ltd. + * + * Author: Juraj Vijtiuk + * + * https://www.sartura.hr/ + */ + +#ifndef MEMORY_H_ONCE +#define MEMORY_H_ONCE + +#include + +#define FREE_SAFE(x) \ + do { \ + free(x); \ + (x) = NULL; \ + } while (0) + +void *xmalloc(size_t size); +void *xrealloc(void *ptr, size_t size); +void *xcalloc(size_t nmemb, size_t size); +char *xstrdup(const char *s); +char *xstrndup(const char *s, size_t size); + +#endif /* MEMORY_H_ONCE */