OCT 1. 初始化工程

This commit is contained in:
xajhuang 2024-12-09 16:28:32 +08:00
commit fbb857cff1
179 changed files with 316832 additions and 0 deletions

220
.clang-format Normal file
View File

@ -0,0 +1,220 @@
# ClangFormatConfigureSource: 'clang-format-file://D:/development/c/daemon_agent/.clang-format'
Language: Cpp
AccessModifierOffset: -4
InsertBraces: true
AlignArrayOfStructures: Left
AlignAfterOpenBracket: Align
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: false
AcrossComments: true
PadOperators: true
AlignCompound: true
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations:
Enabled: true
AcrossEmptyLines: false
AcrossComments: true
PadOperators: true
AlignCompound: true
AlignEscapedNewlines: Left
AlignOperands: DontAlign
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortEnumsOnASingleLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
- __unused
BinPackArguments: true
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: true
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
StatementAttributeLikeMacros:
- Q_EMIT
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequiresClause: false
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 1000
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 140
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PenaltyIndentedWhitespace: 0
PointerAlignment: Right
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: ''
BasedOnStyle: google
ReflowComments: false
SortIncludes: Never
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 4
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Auto
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
SeparateDefinitionBlocks: Always
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
TypenameMacros:
- CONFIG_ITEM
- PCONFIG_ITEM

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/.idea/
*/__init__.py
/cmake-build-*/
/dhcp_server/

116
CMakeLists.txt Normal file
View File

@ -0,0 +1,116 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR)
INCLUDE(CMakeDependentOption)
OPTION(USED_DHCPSERVER "DHCP server for agent" OFF)
OPTION(USED_JSON_VALIDATE "Support json protocol field validate" OFF)
OPTION(BUILD_TESTING "Enable tests" ON)
#
OPTION(USED_REDIS "Add redis database support for agent" OFF)
OPTION(USED_MYSQL "Add mysql database support for agent" OFF)
OPTION(USED_SQLITE_CRYPTO "Sqlite3 database support crypto" OFF)
CMAKE_DEPENDENT_OPTION(USED_HTTP_SVR "Build-in http(s) server support" OFF "USED_DHCPSERVER" OFF)
CMAKE_DEPENDENT_OPTION(USED_SQLITE "Add sqlite3 database support for agent" OFF "USED_SQLITE_CRYPTO" OFF)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/depend)
IF (BUILD_TESTING)
INCLUDE(doctest_framework)
ENDIF ()
INCLUDE(system_libs)
SET(AGENT_VERSION "0.1.0")
PROJECT(agent VERSION "${AGENT_VERSION}")
SET(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig")
SET(URI_HOME "${CMAKE_SOURCE_DIR}/libs")
SET(VERSION_GIT_TAG "")
SET(VERSION_GIT_HASH "")
SET(VERSION_GIT_HASH_SHORT "")
SET(VERSION_GIT_BRANCH "")
FIND_PACKAGE(Git QUIET)
IF (GIT_FOUND)
EXECUTE_PROCESS(
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
OUTPUT_VARIABLE VERSION_GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
EXECUTE_PROCESS(
COMMAND ${GIT_EXECUTABLE} rev-parse --short=8 HEAD
OUTPUT_VARIABLE VERSION_GIT_HASH_SHORT
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
EXECUTE_PROCESS(
COMMAND ${GIT_EXECUTABLE} symbolic-ref --short -q HEAD
OUTPUT_VARIABLE VERSION_GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
EXECUTE_PROCESS(
COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty=-dev
OUTPUT_VARIABLE VERSION_GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
ENDIF ()
IF ("${VERSION_GIT_TAG}" STREQUAL "")
STRING(TIMESTAMP COMPILE_TIME %Y-%m-%d_%H:%M:%S)
SET(VERSION_GIT_TAG ${COMPILE_TIME})
ELSE ()
SET(VERSION_GIT_TAG ${VERSION_GIT_TAG})
ENDIF ()
CONFIGURE_FILE(prj_config.h.in prj_config.h)
MESSAGE("Git Tag: " ${VERSION_GIT_TAG})
#
FIND_PACKAGE(PkgConfig)
SET(COMMON_LIBS "")
INCLUDE(./depend/third_libs.cmake)
IF (USED_JSON_VALIDATE)
LIST(APPEND COMMON_DEFINE "-DJSON_SCHEMA_ON")
ENDIF ()
IF (USED_HTTP_SVR)
LIST(APPEND COMMON_DEFINE "-DHTTPSERVER_ON")
MESSAGE("Select Option USED_HTTP_SVR")
ENDIF ()
IF (USED_SQLITE)
MESSAGE("Select Option USED_SQLITE")
LIST(APPEND COMMON_DEFINE "-DSQLITE_ON")
ENDIF ()
IF (USED_MYSQL)
MESSAGE("Select Option USED_MYSQL")
LIST(APPEND COMMON_DEFINE "-DUSED_MYSQL")
ENDIF ()
IF (USED_REDIS)
MESSAGE("Select Option USED_REDIS")
LIST(APPEND COMMON_DEFINE "-DUSED_REDIS")
ENDIF ()
IF (USED_SQLITE_CRYPTO)
LIST(APPEND COMMON_DEFINE "-DSQLITE_CRYPTO_ON")
MESSAGE("Select Option USED_SQLITE_CRYPTO")
ENDIF ()
ADD_SUBDIRECTORY(srcs)
ADD_SUBDIRECTORY(srcs/libs)
IF (BUILD_TESTING)
ADD_SUBDIRECTORY(unit_test)
ENDIF ()

58
config/agent.cfg Normal file
View File

@ -0,0 +1,58 @@
# daemon agent application configuration file
application:
{
# 系统配置项
system:
{
config_file_path = "."; # 配置文件默认存放目录
show_banner = true; # 是否打印 Banner 信息
ssl_ca_file_path = "/etc/ssl/certs/ca-certificates.crt"; # HTTPS 访问客户端证书存放路径
system_info_watch = true; # 是否启用硬件信息监控
system_info_refresh = 10; # 硬件信息监控刷新频率(秒)
};
# 硬件监控相关配置内容
watch_params:
{
cpu = true; # 是否开启CPU监控
memory = true; # 是否开启内存监控
disk = true; # 是否开启磁盘空间占用监控
sensor = true; # 是否开启传感器状态监控
};
# 数据库相关配置
database:
{
# Redis 服务器相关配置
redis_server = "10.88.76.100"; # redis 服务器IP
redis_port = 6379; # redis 服务器端口
redis_passwd = ""; # redis 数据库密码
mysql_server = "10.88.76.100"; # mysql 服务器IP
mysql_port = 3306; # mysql 服务器端口
mysql_user = "root"; # mysql 用户名
mysql_passwd = "AES@5/BQyUIfVxgV9BZAz/D3Rg=="; # mysql 数据库密码
mysql_database = "test"; # mysql 数据库名称
sqlite_dbname = "./agent.db"; # sqlite3 数据库文件名
sqlite_passwd = ""; # sqlite3 数据库密码
};
# http server config
http_svr:
{
uri = "http://0.0.0.0:8000";
};
protocol:
{
# 0无编码格式普通字符串
# 1base64编码格式
# 2采用AES128加密后的base64编码格式
# 3采用3DES加密后的base64编码格式
# 4采用AES256加密后的base64编码格式
crypto_type = 0;
crypto_key = "AES@rX2qZWVwGVlYTJLf/6X22w==";
};
}

18
config/agent.service Normal file
View File

@ -0,0 +1,18 @@
# sudo cp agent.service /lib/systemd/system/
# sudo ln -s /lib/systemd/system/agent.service /etc/systemd/system/multi-user.target.wants/agent.service
# sudo systemctl daemon-reload
# sudo systemctl enable agent
[Unit]
Description=agent Service
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=5
User=root
WorkingDirectory=/home/jw/agent/srcs
ExecStart=/usr/bin/env /home/jw/agent/srcs/agent_main dhcpd -m -n vxlan0 -d ./config/ -k pqwAQ81rxg70aoy3v+Jjrw==
[Install]
WantedBy=multi-user.target

18
config/agent@.service Normal file
View File

@ -0,0 +1,18 @@
# sudo cp agent@.service /lib/systemd/system/
# sudo ln -s /lib/systemd/system/agent@.service /etc/systemd/system/multi-user.target.wants/agent@.service
# sudo systemctl daemon-reload
# sudo systemctl enable agent@<vni id>
[Unit]
Description=agent service with user %I
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=5
User=root
WorkingDirectory=/home/jw/agent/srcs
ExecStart=/usr/bin/env /home/jw/agent/srcs/agent_main dhcpd -v %I -m -n vxlan0 -c ./config/agent.cfg -d ./config/ -k pqwAQ81rxg70aoy3v+Jjrw==
[Install]
WantedBy=multi-user.target

12
config/banner.txt Normal file
View File

@ -0,0 +1,12 @@
__ __ _
\ \ / ___| | ___ ___ _ __ ___ ___
\ \ /\ / / _ | |/ __/ _ \| '_ ` _ \ / _ \
\ V V | __| | (_| (_) | | | | | | __/
\_/\_/ \___|_|\___\___/|_| |_| |_|\___|
██╗ ██╗██╗██████╗ ████████╗██╗ ██╗ █████╗ ██╗ ██████╗██████╗ ███████╗
██║ ██║██║██╔══██╗╚══██╔══╝██║ ██║██╔══██╗██║ ██╔════╝██╔══██╗██╔════╝
██║ ██║██║██████╔╝ ██║ ██║ ██║███████║██║ ██║ ██████╔╝█████╗
╚██╗ ██╔╝██║██╔══██╗ ██║ ██║ ██║██╔══██║██║ ██║ ██╔═══╝ ██╔══╝
╚████╔╝ ██║██║ ██║ ██║ ╚██████╔╝██║ ██║███████╗ ╚██████╗██║ ███████╗
╚═══╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚══════╝

29
config/zlog.conf Normal file
View File

@ -0,0 +1,29 @@
[global]
strict init = true
reload conf period = 10M
buffer min = 1024
buffer max = 2MB
#rotate lock file = /tmp/zlog.lock
rotate lock file = self
default format = "%d(%F %T.%l) %-6V (%c:%f:%L) %m%n"
file perms = 644
fsync period = 1K
[levels]
TRACE = 10
CRIT = 130, LOG_CRIT
[formats]
simple = "%m"
normal = "[%d(%F %T).%ms][%-6V][%c][%f:%L] %m"
[rules]
*.* >stdout; normal
*.INFO "/var/log/agent/%M(vni)_agent.log", \
1MB * 12 ~ "/var/log/agent/%M(vni)_agent_.%D(%F) #2r #3s.log"; \
normal

Binary file not shown.

BIN
depend/doctest-2.4.9.tar.gz Normal file

Binary file not shown.

View File

@ -0,0 +1,18 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.14 FATAL_ERROR)
INCLUDE(FetchContent)
IF (BUILD_TESTING)
FETCHCONTENT_DECLARE(doctest_framework
URL file://${CMAKE_SOURCE_DIR}/depend/doctest-2.4.11.tar.gz
URL_MD5 a457ba0e8c8f670bfd4aafaa3d9f5e4d)
FETCHCONTENT_MAKEAVAILABLE(doctest_framework)
FETCHCONTENT_GETPROPERTIES(doctest_framework)
IF (NOT doctest_framework_POPULATED)
FETCHCONTENT_POPULATE(doctest_framework)
ADD_SUBDIRECTORY(${doctest_framework_SOURCE_DIR})
ENDIF ()
INCLUDE_DIRECTORIES(${doctest_framework_SOURCE_DIR}/doctest)
LIST(APPEND CMAKE_MODULE_PATH ${doctest_framework_SOURCE_DIR}/scripts/cmake)
ENDIF ()

BIN
depend/json-c-0.16.tar.gz Normal file

Binary file not shown.

Binary file not shown.

BIN
depend/libuv-1.49.2.tar.gz Normal file

Binary file not shown.

29
depend/system_libs.cmake Normal file
View File

@ -0,0 +1,29 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR)
FUNCTION(LINUX_INSTALL_SYSTEM_PACKAGE)
SET(OS_RELEASE_FILE "/etc/os-release")
SET(OS_DISTRIB_NAME "")
IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND EXISTS ${OS_RELEASE_FILE})
FILE(STRINGS ${OS_RELEASE_FILE} OS_RELEASE_NAME LIMIT_COUNT 1)
STRING(FIND ${OS_RELEASE_NAME} "CentOS" SUB_OUT)
IF (${SUB_OUT} MATCHES "6")
SET(OS_DISTRIB_NAME "CentOS")
ELSE ()
STRING(FIND ${OS_RELEASE_NAME} "Ubuntu" SUB_OUT)
IF (${SUB_OUT} MATCHES "6")
SET(OS_DISTRIB_NAME "Ubuntu")
ENDIF ()
ENDIF ()
MESSAGE("Run this command to install system(${OS_DISTRIB_NAME}) dependencies libraries:")
IF (${OS_DISTRIB_NAME} MATCHES "CentOS")
MESSAGE(FATAL_ERROR "$sudo yum -y install libcurl-devel czmq-devel openssl-devel libjson-c-devel")
ELSEIF (${OS_DISTRIB_NAME} MATCHES "Ubuntu")
MESSAGE(FATAL_ERROR "$sudo apt -y install libcurl4-openssl-dev libczmq-dev libssl-dev libjson-c-dev")
ENDIF ()
ELSE ()
MESSAGE(FATAL_ERROR "Run command to install system dependencies libraries [libcurl,libssl,libcrypto,libzmq] by yourself")
ENDIF ()
ENDFUNCTION(LINUX_INSTALL_SYSTEM_PACKAGE)

132
depend/third_libs.cmake Normal file
View File

@ -0,0 +1,132 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.14 FATAL_ERROR)
INCLUDE(FetchContent)
PKG_SEARCH_MODULE(LIBCURL REQUIRED libcurl)
PKG_SEARCH_MODULE(LIBSSL REQUIRED libssl)
PKG_SEARCH_MODULE(LIBCRYPTO REQUIRED libcrypto)
IF (USED_SQLITE AND (NOT USED_SQLITE_CRYPTO))
PKG_SEARCH_MODULE(LIBSQLITE3 REQUIRED sqlite3)
ENDIF ()
IF ((NOT LIBCRYPTO_FOUND) OR (NOT LIBSSL_FOUND) OR (NOT LIBCURL_FOUND))
LINUX_INSTALL_SYSTEM_PACKAGE()
ENDIF ()
LIST(APPEND COMMON_LIBS "${LIBCURL_LDFLAGS} ${LIBSSL_LDFLAGS} ${LIBCRYPTO_LDFLAGS}")
IF (USED_SQLITE AND LIBSQLITE3_FOUND)
LIST(APPEND COMMON_LIBS "${LIBSQLITE3_LDFLAGS}")
ENDIF()
LIST(APPEND COMMON_LIBS "-lm -lpthread")
PKG_SEARCH_MODULE(LIBUV QUIET libuv)
PKG_SEARCH_MODULE(LIBCONFIG QUIET libconfig)
FIND_LIBRARY(LIBZLOG zlog PATHS "/usr/local/lib")
IF (USED_JSON_VALIDATE)
PKG_CHECK_MODULES(LIBJSON-C QUIET json-c>=0.13)
IF (NOT LIBJSON-C_FOUND)
FETCHCONTENT_DECLARE(libjson-c
URL file://${CMAKE_SOURCE_DIR}/depend/json-c-0.16.tar.gz
URL_MD5 a549a833f886d427148fb5710c3e613e
)
ENDIF ()
ENDIF ()
IF (NOT LIBUV_FOUND)
FETCHCONTENT_DECLARE(libuv
URL file://${CMAKE_SOURCE_DIR}/depend/libuv-1.49.2.tar.gz
URL_MD5 b6aa4c4d5a8be9822a50ee9b6cfd00d2)
ENDIF ()
IF (NOT LIBCONFIG_FOUND)
FETCHCONTENT_DECLARE(libconfig
URL file://${CMAKE_SOURCE_DIR}/depend/libconfig-1.7.3.tar.gz
URL_MD5 8f96910eee26118258ac8d4cd128a0b2)
ENDIF ()
IF (LIBZLOG STREQUAL "LIBZLOG-NOTFOUND")
FETCHCONTENT_DECLARE(zlog
URL file://${CMAKE_SOURCE_DIR}/depend/zlog-1.2.18.tar.gz
URL_MD5 5f99a30e61af3b62db4986e277f69cf9)
ENDIF ()
IF (NOT LIBUV_FOUND)
FETCHCONTENT_MAKEAVAILABLE(libuv)
ENDIF ()
IF (NOT LIBCONFIG_FOUND)
FETCHCONTENT_MAKEAVAILABLE(libconfig)
ENDIF ()
IF (LIBZLOG STREQUAL "LIBZLOG-NOTFOUND")
FETCHCONTENT_MAKEAVAILABLE(zlog)
ENDIF ()
IF (USED_JSON_VALIDATE)
IF (NOT LIBJSON-C_FOUND)
FETCHCONTENT_MAKEAVAILABLE(libjson-c)
ENDIF ()
ENDIF ()
IF (NOT LIBUV_FOUND)
MESSAGE(STATUS "libuv not found, will be used source code to build it ...")
FETCHCONTENT_GETPROPERTIES(libuv)
IF (NOT libuv_POPULATED)
FETCHCONTENT_POPULATE(libuv)
ADD_SUBDIRECTORY(${libuv_SOURCE_DIR} ${libuv_BINARY_DIR})
ENDIF ()
INCLUDE_DIRECTORIES(${libuv_SOURCE_DIR}/include)
LIST(APPEND COMMON_LIBS "uv_a")
ELSE ()
MESSAGE(STATUS "libuv found ${LIBUV_VERSION} at ${LIBUV_LIBRARY_DIRS}")
LIST(APPEND COMMON_LIBS "${LIBUV_LDFLAGS}")
ENDIF ()
IF (NOT LIBCONFIG_FOUND)
MESSAGE(STATUS "libconfig not found, will be used source code to build it ...")
FETCHCONTENT_GETPROPERTIES(libconfig)
IF (NOT libconfig_POPULATED)
FETCHCONTENT_POPULATE(libconfig)
ADD_SUBDIRECTORY(${libconfig_SOURCE_DIR} ${libconfig_BINARY_DIR})
ENDIF ()
INCLUDE_DIRECTORIES(${libconfig_SOURCE_DIR}/lib)
LIST(APPEND COMMON_LIBS "config")
ELSE ()
MESSAGE(STATUS "libconfig found ${LIBCONFIG_VERSION} at ${LIBCONFIG_LIBRARY_DIRS}")
LIST(APPEND COMMON_LIBS "${LIBCONFIG_LDFLAGS}")
ENDIF ()
IF (LIBZLOG STREQUAL "LIBZLOG-NOTFOUND")
MESSAGE(STATUS "zlog not found, will be used source code to build it ...")
FETCHCONTENT_GETPROPERTIES(zlog)
IF (NOT zlog_POPULATED)
FETCHCONTENT_POPULATE(zlog)
ADD_SUBDIRECTORY(${zlog_SOURCE_DIR} ${zlog_BINARY_DIR})
ENDIF ()
INCLUDE_DIRECTORIES(${zlog_SOURCE_DIR}/src)
LIST(APPEND COMMON_LIBS "zlog")
ELSE ()
MESSAGE(STATUS "zlog found of ${LIBZLOG}")
LIST(APPEND COMMON_LIBS "${LIBZLOG}")
ENDIF ()
IF (USED_JSON_VALIDATE)
IF (NOT LIBJSON-C_FOUND)
MESSAGE(STATUS "json-c not found, will be used source code to build it ...")
FETCHCONTENT_GETPROPERTIES(libjson-c)
IF (NOT libjson-c_POPULATED)
FETCHCONTENT_POPULATE(libjson-c)
ADD_SUBDIRECTORY(${libjson-c_SOURCE_DIR} ${libjson-c_BINARY_DIR})
ENDIF ()
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory "json-c"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${libjson-c_BINARY_DIR}/json.h" "./json-c/"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${libjson-c_BINARY_DIR}/json_config.h" "."
WORKING_DIRECTORY ${libjson-c_SOURCE_DIR})
INCLUDE_DIRECTORIES(${libjson-c_SOURCE_DIR})
LIST(APPEND COMMON_LIBS "json-c")
ELSE ()
MESSAGE(STATUS "json-c found ${LIBJSON-C_VERSION} at ${LIBJSON-C_LIBRARY_DIRS}")
LIST(APPEND COMMON_LIBS "${LIBJSON-C_LDFLAGS}")
ENDIF ()
ENDIF ()

BIN
depend/zlog-1.2.18.tar.gz Normal file

Binary file not shown.

18
prj_config.h.in Normal file
View File

@ -0,0 +1,18 @@
//
// Created by xajhuang on 2022/12/14.
//
#ifndef PROJECT_PRG_CONFIG_H_IN
#define PROJECT_PRG_CONFIG_H_IN
#define PROJECT_GIT_VERSION "@VERSION_GIT_TAG@"
#define PROJECT_GIT_HASH "@VERSION_GIT_HASH@"
#define PROJECT_GIT_HASH_SHORT "@VERSION_GIT_HASH_SHORT@"
#define PROJECT_GIT_BRANCH "@VERSION_GIT_BRANCH@"
#define PROJECT_PROJECT_NAME "@PROJECT_NAME@"
#define PROJECT_PROJECT_VER "@PROJECT_VERSION@"
#define PROJECT_PROJECT_VER_MAJOR "@PROJECT_VERSION_MAJOR@"
#define PROJECT_PROJECT_VER_MINOR "@PROJECT_VERSION_MINOR@"
#define PROJECT_PTOJECT_VER_PATCH "@PROJECT_VERSION_PATCH@"
#endif //PROJECT_PRG_CONFIG_H_IN

43
srcs/CMakeLists.txt Normal file
View File

@ -0,0 +1,43 @@
SET(PROJECT_TARGET middleware_agent)
PROJECT(${PROJECT_TARGET} LANGUAGES C)
ADD_DEFINITIONS(${COMMON_DEFINE})
INCLUDE_DIRECTORIES(include ./ ./include ./libs/include ${COMMON_INCLUDE})
SET(CMAKE_C_STANDARD 99)
FILE(GLOB AGENT_HEADS include/*.h include/uthash/*.h include/s2j/*.h)
ADD_EXECUTABLE(${PROJECT_TARGET} ${AGENT_HEADS} middleware_agent.c)
TARGET_LINK_LIBRARIES(${PROJECT_TARGET} common)
TARGET_LINK_LIBRARIES(${PROJECT_TARGET} ${COMMON_LIBS})
TARGET_INCLUDE_DIRECTORIES(${PROJECT_TARGET} PUBLIC ${PROJECT_BINARY_DIR}/../)
#
ADD_CUSTOM_COMMAND(TARGET ${PROJECT_TARGET}
POST_BUILD
COMMENT "!!!!!! Notice: Automatic upgreade configuration files after build project."
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/config/"
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/log/"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/config/zlog.conf" "${CMAKE_CURRENT_BINARY_DIR}/config/"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/config/agent.cfg" "${CMAKE_CURRENT_BINARY_DIR}/config/"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/config/banner.txt" "${CMAKE_CURRENT_BINARY_DIR}/config/")
SET(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install/")
INSTALL(FILES ../config/agent.cfg ../config/agent@.service ../config/banner.txt ../config/zlog.conf
DESTINATION config)
INSTALL(TARGETS ${PROJECT_TARGET} RUNTIME DESTINATION ./)
INSTALL(DIRECTORY DESTINATION ./log)
SET(CPACK_GENERATOR "TGZ")
IF ("${VERSION_GIT_HASH_SHORT}" STREQUAL "")
STRING(REGEX REPLACE "[_:-]" "" VER_STR "${VERSION_GIT_TAG}")
SET(CPACK_PACKAGE_FILE_NAME "agent-${AGENT_VERSION}-linux-amd64_${VER_STR}")
ELSE ()
SET(CPACK_PACKAGE_FILE_NAME "agent-${AGENT_VERSION}-linux-amd64_${VERSION_GIT_HASH_SHORT}")
ENDIF ()
INCLUDE(CPack)

76
srcs/libs/CMakeLists.txt Normal file
View File

@ -0,0 +1,76 @@
SET(LIB_PROJECT_TARGET common)
PROJECT(${LIB_PROJECT_TARGET} LANGUAGES C VERSION 1.1.0)
STRING(REPLACE ";" ", " BUILD_CONFIG_INFO "${COMMON_DEFINE}")
CONFIGURE_FILE(lib_config.h.in lib_config.h)
IF (USED_SQLITE_CRYPTO)
INCLUDE_DIRECTORIES(include/sqlite3)
ENDIF ()
INCLUDE_DIRECTORIES(include ./ ./include ../lwip/src/arch_linux/include ../include mongoose)
FILE(GLOB C_HEADS ./include/network/*.h include/*.h include/uthash/*.h include/s2j/*.h vector/*.h ${CMAKE_BINARY_DIR}/*.h ${PROJECT_BINARY_DIR}/*.h)
AUX_SOURCE_DIRECTORY(json C_SRC)
AUX_SOURCE_DIRECTORY(args C_SRC)
AUX_SOURCE_DIRECTORY(init C_SRC)
AUX_SOURCE_DIRECTORY(misc C_SRC)
AUX_SOURCE_DIRECTORY(bitset C_SRC)
AUX_SOURCE_DIRECTORY(banner C_SRC)
AUX_SOURCE_DIRECTORY(configure C_SRC)
AUX_SOURCE_DIRECTORY(network C_SRC)
AUX_SOURCE_DIRECTORY(task C_SRC)
AUX_SOURCE_DIRECTORY(ipaddr C_SRC)
AUX_SOURCE_DIRECTORY(cmdline C_SRC)
AUX_SOURCE_DIRECTORY(crypto_cipher C_SRC)
AUX_SOURCE_DIRECTORY(hardware C_SRC)
AUX_SOURCE_DIRECTORY(protocol C_SRC)
AUX_SOURCE_DIRECTORY(fs_watch C_SRC)
AUX_SOURCE_DIRECTORY(zlog_module C_SRC)
IF (USED_JSON_VALIDATE)
ADD_SUBDIRECTORY(./json/json_schema)
ENDIF ()
IF (USED_HTTP_SVR)
AUX_SOURCE_DIRECTORY(mongoose C_SRC)
ENDIF ()
IF (USED_SQLITE)
LIST(APPEND C_SRC database/database.c)
IF (SQLITE_CRYPTO_ON)
AUX_SOURCE_DIRECTORY(database/sqlite3 C_SRC)
ENDIF ()
ENDIF ()
SET(CMAKE_C_STANDARD 99)
SET_SOURCE_FILES_PROPERTIES(misc/zvector.c PROPERTIES COMPILE_FLAGS "-Wall -Wextra -flto")
SET_SOURCE_FILES_PROPERTIES(mongoose/mongoose.c PROPERTIES COMPILE_FLAGS "-Wall -Wextra -w")
IF (USED_SQLITE_CRYPTO)
SET_SOURCE_FILES_PROPERTIES(database/sqlite3/sqlite3.c PROPERTIES
COMPILE_FLAGS "-DSQLITE_HAS_CODEC \
-DSQLCIPHER_CRYPTO_OPENSSL -DSQLITE_OS_UNIX=1 \
-D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite -DNDEBUG -DSQLITE_THREADSAFE=1 \
-DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT \
-DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT \
-DSQLITE_HAVE_ZLIB=1 -DSQLITE_TEMP_STORE=2")
ENDIF ()
ADD_DEFINITIONS(${COMMON_DEFINE})
IF (USED_HTTP_SVR)
ADD_DEFINITIONS(-DMG_ARCH=MG_ARCH_UNIX -DMG_ENABLE_OPENSSL=1)
ENDIF ()
ADD_LIBRARY(${LIB_PROJECT_TARGET} ${C_SRC} ${C_HEADS})
TARGET_LINK_LIBRARIES(${LIB_PROJECT_TARGET} ${COMMON_LIBS})
IF (USED_JSON_VALIDATE)
TARGET_LINK_LIBRARIES(${LIB_PROJECT_TARGET} jsoncdac)
ENDIF ()
TARGET_INCLUDE_DIRECTORIES(${LIB_PROJECT_TARGET} PUBLIC ${PROJECT_BINARY_DIR}/ ${CMAKE_BINARY_DIR}/)

6403
srcs/libs/args/argtable3.c Normal file

File diff suppressed because it is too large Load Diff

371
srcs/libs/args/argtable3.h Normal file
View File

@ -0,0 +1,371 @@
/*******************************************************************************
* argtable3: Declares the main interfaces of the library
*
* This file is part of the argtable3 library.
*
* Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
* <sheitmann@users.sourceforge.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of STEWART HEITMANN nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 STEWART HEITMANN 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.
******************************************************************************/
#ifndef ARGTABLE3
#define ARGTABLE3
#include <stdio.h> /* FILE */
#include <time.h> /* struct tm */
#ifdef __cplusplus
extern "C" {
#endif
#define ARG_REX_ICASE 1
#define ARG_DSTR_SIZE 200
#define ARG_CMD_NAME_LEN 100
#define ARG_CMD_DESCRIPTION_LEN 256
#ifndef ARG_REPLACE_GETOPT
#define ARG_REPLACE_GETOPT 1 /* use the embedded getopt as the system getopt(3) */
#endif /* ARG_REPLACE_GETOPT */
/* bit masks for arg_hdr.flag */
enum {
ARG_TERMINATOR = 0x1,
ARG_HASVALUE = 0x2,
ARG_HASOPTVALUE = 0x4
};
#if defined(_WIN32)
#if defined(argtable3_EXPORTS)
#define ARG_EXTERN __declspec(dllexport)
#elif defined(argtable3_IMPORTS)
#define ARG_EXTERN __declspec(dllimport)
#else
#define ARG_EXTERN
#endif
#else
#define ARG_EXTERN
#endif
typedef struct _internal_arg_dstr *arg_dstr_t;
typedef void *arg_cmd_itr_t;
typedef void(arg_resetfn)(void *parent);
typedef int(arg_scanfn)(void *parent, const char *argval);
typedef int(arg_checkfn)(void *parent);
typedef void(arg_errorfn)(void *parent, arg_dstr_t ds, int error, const char *argval, const char *progname);
typedef void(arg_dstr_freefn)(char *buf);
typedef int(arg_cmdfn)(int argc, char *argv[], arg_dstr_t res);
typedef int(arg_comparefn)(const void *k1, const void *k2);
/*
* The arg_hdr struct defines properties that are common to all arg_xxx structs.
* The argtable library requires each arg_xxx struct to have an arg_hdr
* struct as its first data member.
* The argtable library functions then use this data to identify the
* properties of the command line option, such as its option tags,
* datatype string, and glossary strings, and so on.
* Moreover, the arg_hdr struct contains pointers to custom functions that
* are provided by each arg_xxx struct which perform the tasks of parsing
* that particular arg_xxx arguments, performing post-parse checks, and
* reporting errors.
* These functions are private to the individual arg_xxx source code
* and are the pointer to them are initiliased by that arg_xxx struct's
* constructor function. The user could alter them after construction
* if desired, but the original intention is for them to be set by the
* constructor and left unaltered.
*/
typedef struct arg_hdr {
char flag; /* Modifier flags: ARG_TERMINATOR, ARG_HASVALUE. */
const char *shortopts; /* String defining the short options */
const char *longopts; /* String defiing the long options */
const char *datatype; /* Description of the argument data type */
const char *glossary; /* Description of the option as shown by
arg_print_glossary function */
int mincount; /* Minimum number of occurences of this option accepted */
int maxcount; /* Maximum number of occurences if this option accepted */
void *parent; /* Pointer to parent arg_xxx struct */
arg_resetfn *resetfn; /* Pointer to parent arg_xxx reset function */
arg_scanfn *scanfn; /* Pointer to parent arg_xxx scan function */
arg_checkfn *checkfn; /* Pointer to parent arg_xxx check function */
arg_errorfn *errorfn; /* Pointer to parent arg_xxx error function */
void *priv; /* Pointer to private header data for use by arg_xxx functions */
} arg_hdr_t;
typedef struct arg_rem {
struct arg_hdr hdr; /* The mandatory argtable header struct */
} arg_rem_t;
typedef struct arg_lit {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
} arg_lit_t;
typedef struct arg_int {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
int *ival; /* Array of parsed argument values */
} arg_int_t;
typedef struct arg_dbl {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
double *dval; /* Array of parsed argument values */
} arg_dbl_t;
typedef struct arg_str {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
const char **sval; /* Array of parsed argument values */
} arg_str_t;
typedef struct arg_rex {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
const char **sval; /* Array of parsed argument values */
} arg_rex_t;
typedef struct arg_file {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args*/
const char **filename; /* Array of parsed filenames (eg: /home/foo.bar) */
const char **basename; /* Array of parsed basenames (eg: foo.bar) */
const char **extension; /* Array of parsed extensions (eg: .bar) */
} arg_file_t;
typedef struct arg_date {
struct arg_hdr hdr; /* The mandatory argtable header struct */
const char *format; /* strptime format string used to parse the date */
int count; /* Number of matching command line args */
struct tm *tmval; /* Array of parsed time values */
} arg_date_t;
enum {
ARG_ELIMIT = 1,
ARG_EMALLOC,
ARG_ENOMATCH,
ARG_ELONGOPT,
ARG_EMISSARG
};
typedef struct arg_end {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of errors encountered */
int *error; /* Array of error codes */
void **parent; /* Array of pointers to offending arg_xxx struct */
const char **argval; /* Array of pointers to offending argv[] string */
} arg_end_t;
typedef struct arg_cmd_info {
char name[ARG_CMD_NAME_LEN];
char description[ARG_CMD_DESCRIPTION_LEN];
arg_cmdfn *proc;
} arg_cmd_info_t;
/**** arg_xxx constructor functions *********************************/
ARG_EXTERN struct arg_rem *arg_rem(const char *datatype, const char *glossary);
ARG_EXTERN struct arg_lit *arg_lit0(const char *shortopts, const char *longopts, const char *glossary);
ARG_EXTERN struct arg_lit *arg_lit1(const char *shortopts, const char *longopts, const char *glossary);
ARG_EXTERN struct arg_lit *arg_litn(const char *shortopts,
const char *longopts,
int mincount,
int maxcount,
const char *glossary);
ARG_EXTERN struct arg_int *arg_int0(const char *shortopts,
const char *longopts,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_int *arg_int1(const char *shortopts,
const char *longopts,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_int *arg_intn(const char *shortopts,
const char *longopts,
const char *datatype,
int mincount,
int maxcount,
const char *glossary);
ARG_EXTERN struct arg_dbl *arg_dbl0(const char *shortopts,
const char *longopts,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_dbl *arg_dbl1(const char *shortopts,
const char *longopts,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_dbl *arg_dbln(const char *shortopts,
const char *longopts,
const char *datatype,
int mincount,
int maxcount,
const char *glossary);
ARG_EXTERN struct arg_str *arg_str0(const char *shortopts,
const char *longopts,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_str *arg_str1(const char *shortopts,
const char *longopts,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_str *arg_strn(const char *shortopts,
const char *longopts,
const char *datatype,
int mincount,
int maxcount,
const char *glossary);
ARG_EXTERN struct arg_rex *arg_rex0(const char *shortopts,
const char *longopts,
const char *pattern,
const char *datatype,
int flags,
const char *glossary);
ARG_EXTERN struct arg_rex *arg_rex1(const char *shortopts,
const char *longopts,
const char *pattern,
const char *datatype,
int flags,
const char *glossary);
ARG_EXTERN struct arg_rex *arg_rexn(const char *shortopts,
const char *longopts,
const char *pattern,
const char *datatype,
int mincount,
int maxcount,
int flags,
const char *glossary);
ARG_EXTERN struct arg_file *arg_file0(const char *shortopts,
const char *longopts,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_file *arg_file1(const char *shortopts,
const char *longopts,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_file *arg_filen(const char *shortopts,
const char *longopts,
const char *datatype,
int mincount,
int maxcount,
const char *glossary);
ARG_EXTERN struct arg_date *arg_date0(const char *shortopts,
const char *longopts,
const char *format,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_date *arg_date1(const char *shortopts,
const char *longopts,
const char *format,
const char *datatype,
const char *glossary);
ARG_EXTERN struct arg_date *arg_daten(const char *shortopts,
const char *longopts,
const char *format,
const char *datatype,
int mincount,
int maxcount,
const char *glossary);
ARG_EXTERN struct arg_end *arg_end(int maxcount);
#define ARG_DSTR_STATIC ((arg_dstr_freefn *)0)
#define ARG_DSTR_VOLATILE ((arg_dstr_freefn *)1)
#define ARG_DSTR_DYNAMIC ((arg_dstr_freefn *)3)
/**** other functions *******************************************/
ARG_EXTERN int arg_nullcheck(void **argtable);
ARG_EXTERN int arg_parse(int argc, char **argv, void **argtable);
ARG_EXTERN void arg_print_option(FILE *fp,
const char *shortopts,
const char *longopts,
const char *datatype,
const char *suffix);
ARG_EXTERN void arg_print_syntax(FILE *fp, void **argtable, const char *suffix);
ARG_EXTERN void arg_print_syntaxv(FILE *fp, void **argtable, const char *suffix);
ARG_EXTERN void arg_print_glossary(FILE *fp, void **argtable, const char *format);
ARG_EXTERN void arg_print_glossary_gnu(FILE *fp, void **argtable);
ARG_EXTERN void arg_print_errors(FILE *fp, struct arg_end *end, const char *progname);
ARG_EXTERN void arg_print_option_ds(arg_dstr_t ds,
const char *shortopts,
const char *longopts,
const char *datatype,
const char *suffix);
ARG_EXTERN void arg_print_syntax_ds(arg_dstr_t ds, void **argtable, const char *suffix);
ARG_EXTERN void arg_print_syntaxv_ds(arg_dstr_t ds, void **argtable, const char *suffix);
ARG_EXTERN void arg_print_glossary_ds(arg_dstr_t ds, void **argtable, const char *format);
ARG_EXTERN void arg_print_glossary_gnu_ds(arg_dstr_t ds, void **argtable);
ARG_EXTERN void arg_print_errors_ds(arg_dstr_t ds, struct arg_end *end, const char *progname);
ARG_EXTERN void arg_freetable(void **argtable, size_t n);
ARG_EXTERN arg_dstr_t arg_dstr_create(void);
ARG_EXTERN void arg_dstr_destroy(arg_dstr_t ds);
ARG_EXTERN void arg_dstr_reset(arg_dstr_t ds);
ARG_EXTERN void arg_dstr_free(arg_dstr_t ds);
ARG_EXTERN void arg_dstr_set(arg_dstr_t ds, char *str, arg_dstr_freefn *free_proc);
ARG_EXTERN void arg_dstr_cat(arg_dstr_t ds, const char *str);
ARG_EXTERN void arg_dstr_catc(arg_dstr_t ds, char c);
ARG_EXTERN void arg_dstr_catf(arg_dstr_t ds, const char *fmt, ...);
ARG_EXTERN char *arg_dstr_cstr(arg_dstr_t ds);
ARG_EXTERN void arg_cmd_init(void);
ARG_EXTERN void arg_cmd_uninit(void);
ARG_EXTERN void arg_cmd_register(const char *name, arg_cmdfn *proc, const char *description);
ARG_EXTERN void arg_cmd_unregister(const char *name);
ARG_EXTERN int arg_cmd_dispatch(const char *name, int argc, char *argv[], arg_dstr_t res);
ARG_EXTERN unsigned int arg_cmd_count(void);
ARG_EXTERN arg_cmd_info_t *arg_cmd_info(const char *name);
ARG_EXTERN arg_cmd_itr_t arg_cmd_itr_create(void);
ARG_EXTERN void arg_cmd_itr_destroy(arg_cmd_itr_t itr);
ARG_EXTERN int arg_cmd_itr_advance(arg_cmd_itr_t itr);
ARG_EXTERN char *arg_cmd_itr_key(arg_cmd_itr_t itr);
ARG_EXTERN arg_cmd_info_t *arg_cmd_itr_value(arg_cmd_itr_t itr);
ARG_EXTERN int arg_cmd_itr_search(arg_cmd_itr_t itr, void *k);
ARG_EXTERN void arg_mgsort(void *data, int size, int esize, int i, int k, arg_comparefn *comparefn);
ARG_EXTERN void arg_make_get_help_msg(arg_dstr_t res);
ARG_EXTERN void arg_make_help_msg(arg_dstr_t ds, char *cmd_name, void **argtable);
ARG_EXTERN void arg_make_syntax_err_msg(arg_dstr_t ds, void **argtable, struct arg_end *end);
ARG_EXTERN int arg_make_syntax_err_help_msg(arg_dstr_t ds,
char *name,
int help,
int nerrors,
void **argtable,
struct arg_end *end,
int *exitcode);
ARG_EXTERN void arg_set_module_name(const char *name);
ARG_EXTERN void arg_set_module_version(int major, int minor, int patch, const char *tag);
/**** deprecated functions, for back-compatibility only ********/
ARG_EXTERN void arg_free(void **argtable);
#ifdef __cplusplus
}
#endif
#endif

42
srcs/libs/banner/banner.c Normal file
View File

@ -0,0 +1,42 @@
//
// Created by xajhu on 2021/6/29 0029.
//
#include "uthash/utstring.h"
#include "banner.h"
#include "config.h"
#include "zlog_module.h"
void banner_show() {
FILE *fp;
UT_string *pPath;
char rdBuf[1024];
utstring_new(pPath);
utstring_printf(pPath, "%s/%s", cfg_get_config_directory(), BANNER_FILE);
// 读取文件
if ((fp = fopen(utstring_body(pPath), "r")) != NULL) {
UT_string *pBannerText;
utstring_new(pBannerText);
while (!feof(fp)) {
memset(rdBuf, 0, 1024);
fgets(rdBuf, 1024, fp);
// 保存读取的banner信息
utstring_bincpy(pBannerText, rdBuf, strlen(rdBuf));
}
fclose(fp);
LOG_MOD(info,
ZLOG_MOD_MAIN,
"================== Banner Used ===================\n%s\n",
utstring_body(pBannerText));
utstring_free(pBannerText);
} else {
LOG_MOD(error, ZLOG_MOD_MAIN, "Banner file does not exists: %s\n", utstring_body(pPath));
}
utstring_free(pPath);
}

382
srcs/libs/bitset/bitset.c Normal file
View File

@ -0,0 +1,382 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "bitset/bitset.h"
/* Create a new bitset. Return NULL in case of failure. */
bitset_t *bitset_create() {
bitset_t *bitset = NULL;
/* Allocate the bitset itself. */
if ((bitset = (bitset_t *)malloc(sizeof(bitset_t))) == NULL) {
return NULL;
}
bitset->array = NULL;
bitset->arraysize = 0;
bitset->capacity = 0;
return bitset;
}
/* Create a new bitset able to contain size bits. Return NULL in case of failure. */
bitset_t *bitset_create_with_capacity(size_t size) {
bitset_t *bitset = NULL;
/* Allocate the bitset itself. */
if ((bitset = (bitset_t *)malloc(sizeof(bitset_t))) == NULL) {
return NULL;
}
bitset->arraysize = (size + sizeof(uint64_t) * 8 - 1) / (sizeof(uint64_t) * 8);
bitset->capacity = bitset->arraysize;
if ((bitset->array = (uint64_t *)calloc(bitset->arraysize, sizeof(uint64_t))) == NULL) {
free(bitset);
return NULL;
}
return bitset;
}
/* Create a copy */
bitset_t *bitset_copy(const bitset_t *bitset) {
bitset_t *copy = NULL;
/* Allocate the bitset itself. */
if ((copy = (bitset_t *)malloc(sizeof(bitset_t))) == NULL) {
return NULL;
}
memcpy(copy, bitset, sizeof(bitset_t));
copy->capacity = copy->arraysize;
if ((copy->array = (uint64_t *)malloc(sizeof(uint64_t) * bitset->arraysize)) == NULL) {
free(copy);
return NULL;
}
memcpy(copy->array, bitset->array, sizeof(uint64_t) * bitset->arraysize);
return copy;
}
void bitset_clear(bitset_t *bitset) {
memset(bitset->array, 0, sizeof(uint64_t) * bitset->arraysize);
}
void bitset_shift_left(bitset_t *bitset, size_t s) {
size_t extra_words = s / 64;
int inword_shift = (int)(s % 64);
size_t as = bitset->arraysize;
if (inword_shift == 0) {
bitset_resize(bitset, as + extra_words, FALSE);
// could be done with a memmove
for (size_t i = as + extra_words; i > extra_words; i--) {
bitset->array[i - 1] = bitset->array[i - 1 - extra_words];
}
} else {
bitset_resize(bitset, as + extra_words + 1, TRUE);
bitset->array[as + extra_words] = bitset->array[as - 1] >> (64 - inword_shift);
for (size_t i = as + extra_words; i >= extra_words + 2; i--) {
bitset->array[i - 1] = (bitset->array[i - 1 - extra_words] << inword_shift) |
(bitset->array[i - 2 - extra_words] >> (64 - inword_shift));
}
bitset->array[extra_words] = bitset->array[0] << inword_shift;
}
for (size_t i = 0; i < extra_words; i++) {
bitset->array[i] = 0;
}
}
void bitset_shift_right(bitset_t *bitset, size_t s) {
size_t extra_words = s / 64;
int inword_shift = (int)(s % 64);
size_t as = bitset->arraysize;
if (inword_shift == 0) {
// could be done with a memmove
for (size_t i = 0; i < as - extra_words; i++) {
bitset->array[i] = bitset->array[i + extra_words];
}
bitset_resize(bitset, as - extra_words, FALSE);
} else {
for (size_t i = 0; i + extra_words + 1 < as; i++) {
bitset->array[i] = (bitset->array[i + extra_words] >> inword_shift) |
(bitset->array[i + extra_words + 1] << (64 - inword_shift));
}
bitset->array[as - extra_words - 1] = (bitset->array[as - 1] >> inword_shift);
bitset_resize(bitset, as - extra_words, FALSE);
}
}
/* Free memory. */
void bitset_free(bitset_t *bitset) {
free(bitset->array);
free(bitset);
}
/* Resize the bitset so that it can support newarraysize * 64 bits. Return TRUE in case of success, FALSE for failure. */
int bitset_resize(bitset_t *bitset, size_t newarraysize, int padwithzeroes) {
size_t smallest = newarraysize < bitset->arraysize ? newarraysize : bitset->arraysize;
if (bitset->capacity < newarraysize) {
uint64_t *newarray;
bitset->capacity = newarraysize * 2;
if ((newarray = (uint64_t *)realloc(bitset->array, sizeof(uint64_t) * bitset->capacity)) == NULL) {
free(bitset->array);
return FALSE;
}
bitset->array = newarray;
}
if (padwithzeroes && (newarraysize > smallest)) {
memset(bitset->array + smallest, 0, sizeof(uint64_t) * (newarraysize - smallest));
}
bitset->arraysize = newarraysize;
return TRUE; // success!
}
size_t bitset_count(const bitset_t *bitset) {
size_t card = 0;
size_t k = 0;
// assumes that long long is 8 bytes
for (; k + 7 < bitset->arraysize; k += 8) {
card += __builtin_popcountll(bitset->array[k]);
card += __builtin_popcountll(bitset->array[k + 1]);
card += __builtin_popcountll(bitset->array[k + 2]);
card += __builtin_popcountll(bitset->array[k + 3]);
card += __builtin_popcountll(bitset->array[k + 4]);
card += __builtin_popcountll(bitset->array[k + 5]);
card += __builtin_popcountll(bitset->array[k + 6]);
card += __builtin_popcountll(bitset->array[k + 7]);
}
for (; k + 3 < bitset->arraysize; k += 4) {
card += __builtin_popcountll(bitset->array[k]);
card += __builtin_popcountll(bitset->array[k + 1]);
card += __builtin_popcountll(bitset->array[k + 2]);
card += __builtin_popcountll(bitset->array[k + 3]);
}
for (; k < bitset->arraysize; k++) {
card += __builtin_popcountll(bitset->array[k]);
}
return card;
}
int bitset_inplace_union(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
for (size_t k = 0; k < minlength; ++k) {
b1->array[k] |= b2->array[k];
}
if (b2->arraysize > b1->arraysize) {
size_t oldsize = b1->arraysize;
if (!bitset_resize(b1, b2->arraysize, FALSE)) {
return FALSE;
}
memcpy(b1->array + oldsize, b2->array + oldsize, (b2->arraysize - oldsize) * sizeof(uint64_t));
}
return TRUE;
}
size_t bitset_minimum(const bitset_t *bitset) {
for (size_t k = 0; k < bitset->arraysize; k++) {
uint64_t w = bitset->array[k];
if (w != 0) {
return __builtin_ctzll(w) + k * 64;
}
}
return 0;
}
size_t bitset_maximum(const bitset_t *bitset) {
for (size_t k = bitset->arraysize; k > 0; k--) {
uint64_t w = bitset->array[k - 1];
if (w != 0) {
return 63 - __builtin_clzll(w) + (k - 1) * 64;
}
}
return 0;
}
/* Returns TRUE if bitsets share no common elements, FALSE otherwise.
*
* Performs early-out if common element found. */
int bitsets_disjoint(const bitset_t *b1, const bitset_t *b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
for (size_t k = 0; k < minlength; k++) {
if ((b1->array[k] & b2->array[k]) != 0) {
return FALSE;
}
}
return TRUE;
}
/* Returns TRUE if bitsets contain at least 1 common element, FALSE if they are
* disjoint.
*
* Performs early-out if common element found. */
int bitsets_intersect(const bitset_t *b1, const bitset_t *b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
for (size_t k = 0; k < minlength; k++) {
if ((b1->array[k] & b2->array[k]) != 0) {
return TRUE;
}
}
return FALSE;
}
/* Returns TRUE if b has any bits set in or after b->array[starting_loc]. */
static int any_bits_set(const bitset_t *b, size_t starting_loc) {
if (starting_loc >= b->arraysize) {
return FALSE;
}
for (size_t k = starting_loc; k < b->arraysize; k++) {
if (b->array[k] != 0) {
return TRUE;
}
}
return FALSE;
}
/* Returns TRUE if b1 has all of b2's bits set.
*
* Performs early out if a bit is found in b2 that is not found in b1. */
int bitset_contains_all(const bitset_t *b1, const bitset_t *b2) {
for (size_t k = 0; k < b1->arraysize; k++) {
if ((b1->array[k] & b2->array[k]) != b2->array[k]) {
return FALSE;
}
}
if (b2->arraysize > b1->arraysize) {
/* Need to check if b2 has any bits set beyond b1's array */
return !any_bits_set(b2, b1->arraysize);
}
return TRUE;
}
size_t bitset_union_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t answer = 0;
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
for (; k + 3 < minlength; k += 4) {
answer += __builtin_popcountll(b1->array[k] | b2->array[k]);
answer += __builtin_popcountll(b1->array[k + 1] | b2->array[k + 1]);
answer += __builtin_popcountll(b1->array[k + 2] | b2->array[k + 2]);
answer += __builtin_popcountll(b1->array[k + 3] | b2->array[k + 3]);
}
for (; k < minlength; ++k) {
answer += __builtin_popcountll(b1->array[k] | b2->array[k]);
}
if (b2->arraysize > b1->arraysize) {
//k = b1->arraysize;
for (; k + 3 < b2->arraysize; k += 4) {
answer += __builtin_popcountll(b2->array[k]);
answer += __builtin_popcountll(b2->array[k + 1]);
answer += __builtin_popcountll(b2->array[k + 2]);
answer += __builtin_popcountll(b2->array[k + 3]);
}
for (; k < b2->arraysize; ++k) {
answer += __builtin_popcountll(b2->array[k]);
}
} else {
//k = b2->arraysize;
for (; k + 3 < b1->arraysize; k += 4) {
answer += __builtin_popcountll(b1->array[k]);
answer += __builtin_popcountll(b1->array[k + 1]);
answer += __builtin_popcountll(b1->array[k + 2]);
answer += __builtin_popcountll(b1->array[k + 3]);
}
for (; k < b1->arraysize; ++k) {
answer += __builtin_popcountll(b1->array[k]);
}
}
return answer;
}
void bitset_inplace_intersection(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
for (; k < minlength; ++k) {
b1->array[k] &= b2->array[k];
}
for (; k < b1->arraysize; ++k) {
b1->array[k] = 0; // memset could, maybe, be a tiny bit faster
}
}
size_t bitset_intersection_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t answer = 0;
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
for (size_t k = 0; k < minlength; ++k) {
answer += __builtin_popcountll(b1->array[k] & b2->array[k]);
}
return answer;
}
void bitset_inplace_difference(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
for (; k < minlength; ++k) {
b1->array[k] &= ~(b2->array[k]);
}
}
size_t bitset_difference_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
size_t answer = 0;
for (; k < minlength; ++k) {
answer += __builtin_popcountll(b1->array[k] & ~(b2->array[k]));
}
for (; k < b1->arraysize; ++k) {
answer += __builtin_popcountll(b1->array[k]);
}
return answer;
}
int bitset_inplace_symmetric_difference(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
for (; k < minlength; ++k) {
b1->array[k] ^= b2->array[k];
}
if (b2->arraysize > b1->arraysize) {
size_t oldsize = b1->arraysize;
if (!bitset_resize(b1, b2->arraysize, FALSE)) {
return FALSE;
}
memcpy(b1->array + oldsize, b2->array + oldsize, (b2->arraysize - oldsize) * sizeof(uint64_t));
}
return TRUE;
}
size_t bitset_symmetric_difference_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2) {
size_t minlength = b1->arraysize < b2->arraysize ? b1->arraysize : b2->arraysize;
size_t k = 0;
size_t answer = 0;
for (; k < minlength; ++k) {
answer += __builtin_popcountll(b1->array[k] ^ b2->array[k]);
}
if (b2->arraysize > b1->arraysize) {
for (; k < b2->arraysize; ++k) {
answer += __builtin_popcountll(b2->array[k]);
}
} else {
for (; k < b1->arraysize; ++k) {
answer += __builtin_popcountll(b1->array[k]);
}
}
return answer;
}
int bitset_trim(bitset_t *bitset) {
size_t newsize = bitset->arraysize;
while (newsize > 0) {
if (bitset->array[newsize - 1] == 0) {
newsize -= 1;
} else {
break;
}
}
if (bitset->capacity == newsize) {
return TRUE; // nothing to do
}
bitset->capacity = newsize;
bitset->arraysize = newsize;
uint64_t *newarray;
if ((newarray = (uint64_t *)realloc(bitset->array, sizeof(uint64_t) * bitset->capacity)) == NULL) {
free(bitset->array);
return FALSE;
}
bitset->array = newarray;
return TRUE;
}

View File

@ -0,0 +1,712 @@
//
// Created by xajhu on 2021/8/3 0003.
//
#include <string.h>
#include <stdlib.h>
#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
#include <openssl/crypto.h>
#else
#include <openssl/opensslv.h>
#endif
#include "args/argtable3.h"
#include "cmdline.h"
#include "user_errno.h"
#include "task_manager.h"
#include "init.h"
#include "crypto.h"
#include "misc.h"
#include "config.h"
#include "s2j/s2j.h"
#include "msg_queue.h"
#include "prj_config.h"
#define REG_ICASE (ARG_REX_ICASE)
typedef void (*HelpCmdCb)(void *, const char *, void *);
typedef int (*ProcessCmdCb)(void **, const char *, void *);
typedef struct {
void *argTbl;
int nArgItem;
int *pErrCode;
ProcessCmdCb pCmd;
HelpCmdCb pHelp;
const char *pDesc;
} ARG_TBL_INFO, *PARG_TBL_INFO;
static PARG_TBL_INFO g_pArgTbl = NULL;
static unsigned int g_nArgTbl = 0;
static const char *g_toolsKey[][2] = {
{"cfg_all", "get all configuration information" },
{"mem_info", "show the memory alloc information" },
{"sys_info", "show the system and hardware information"},
};
static int get_reg_cmd(void *pTbl[]) {
return ((arg_rex_t *)pTbl[0])->count;
}
static void *get_arg_err(void *pTbl[], PARG_TBL_INFO pInfo) {
return pTbl[pInfo->nArgItem - 1];
}
static arg_lit_t *get_help_cmd(void *pTbl[], PARG_TBL_INFO pInfo) {
return pTbl[pInfo->nArgItem - 2];
}
static void show_help(const char *pAppName) {
int i;
for (i = 0; i < g_nArgTbl; i++) {
if (i == 0) {
printf("Usage: \033[1;33m%s", pAppName);
} else {
printf(" \033[1;33m%s", pAppName);
}
arg_print_syntax(stdout, g_pArgTbl[i].argTbl, "\n");
}
printf("\033[0m\nThe Intrusion Detection Systems agent application\n");
printf("\nMandatory arguments to long options are mandatory for short options too.\n");
arg_print_glossary(stdout, g_pArgTbl[i - 1].argTbl, " \033[1;32m%-30s %s\033[0m\n");
printf("\nSupport subcommand: \n");
for (i = 0; i < g_nArgTbl - 1; i++) {
if (g_pArgTbl[i].pDesc) {
printf("%s", g_pArgTbl[i].pDesc);
arg_print_glossary(stdout, g_pArgTbl[i].argTbl, " %-30s %s\n");
}
}
printf("\n\nTry '\033[1;31m%s --help\033[0m' for more information.\n", pAppName);
}
static void cmdn_help(void *pTbl, const char *pName, void *pErr) {
if (pErr != NULL) {
printf("\033[1;31m");
arg_print_errors(stdout, pErr, "");
printf("\033[0m\n");
}
printf("usage : %s", pName);
arg_print_syntax(stdout, pTbl, "\n");
printf("\nMandatory arguments to long options are mandatory for short options too.\n");
arg_print_glossary(stdout, pTbl, "%-30s %s\n");
}
static void cmd2_help(void *pTbl, const char *pName, void *pErr) {
int i;
cmdn_help(pTbl, pName, pErr);
printf("\n\nSupport keys:\n");
printf(" \033[1;4;35mConfiguration\033[0m:\n");
for (i = 0; i < ARRAY_SIZE(g_toolsKey); i++) {
printf(" \033[4m%s\033[0m:\t %s\n", g_toolsKey[i][0], g_toolsKey[i][1]);
}
}
static int on_cmd1(void *pTbl[], const char *pName, void *pInfo) {
int ret;
PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo;
const char *pCfgFile = ((arg_file_t *)pTbl[1])->filename[0];
const char *pCfgDir = ((arg_file_t *)pTbl[2])->filename[0];
const char *pKey = ((arg_str_t *)pTbl[3])->sval[0];
int help = get_help_cmd(pTbl, pArg)->count;
if (pArg->pHelp && help > 0) {
pArg->pHelp(pArg->argTbl, pName, NULL);
return ERR_MENU_EXIT;
}
if ((ret = user_init(pCfgFile, pCfgDir, pKey, 0)) != ERR_SUCCESS) {
printf("System init error: %d\n", ret);
return ret;
}
return ret;
}
static cJSON *s2j_mq_msg(void *pObj) {
PMQ_CMD_MSG pMsg = (PMQ_CMD_MSG)pObj;
s2j_create_json_obj(pJsonObj);
s2j_json_set_basic_element(pJsonObj, pMsg, string, cmd);
s2j_json_set_basic_element(pJsonObj, pMsg, string, key);
s2j_json_set_basic_element(pJsonObj, pMsg, string, value);
return pJsonObj;
}
static int on_cmd2(void *pTbl[], const char *pName, void *pInfo) {
int ret, i;
PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo;
MQ_CMD_MSG msg;
cJSON *pJsonObj;
const char *pJsonStr;
const char *pSvr = ((arg_str_t *)pTbl[1])->sval[0];
int help = get_help_cmd(pTbl, pArg)->count;
if (pArg->pHelp && help > 0) {
pArg->pHelp(pArg->argTbl, pName, NULL);
return ERR_MENU_EXIT;
}
memset(&msg, 0, sizeof(MQ_CMD_MSG));
strncpy(msg.cmd, ((arg_str_t *)pTbl[2])->sval[0], MAX_PATH - 1);
strncpy(msg.key, ((arg_str_t *)pTbl[3])->sval[0], MAX_PATH - 1);
strncpy(msg.value, ((arg_str_t *)pTbl[4])->sval[0], MAX_PATH - 1);
if (strcmp(msg.cmd, "get") != 0 && strcmp(msg.cmd, "set") != 0) {
printf("Error command: %s\n", msg.cmd);
return -ERR_INPUT_PARAMS;
}
ret = FALSE;
for (i = 0; i < ARRAY_SIZE(g_toolsKey); i++) {
if (strcmp(g_toolsKey[i][0], msg.key) == 0) {
ret = TRUE;
break;
}
}
if (ret == FALSE) {
printf("Error key: %s\n", msg.key);
return -ERR_INPUT_PARAMS;
}
pJsonObj = s2j_mq_msg(&msg);
if (pJsonObj == NULL) {
return -ERR_JSON_CREAT_OBJ;
}
pJsonStr = cJSON_PrintUnformatted(pJsonObj);
#ifdef ZEROMQ_ON
ret = mq_cmd_run(pSvr, pJsonStr);
#else
ret = ERR_SUCCESS;
#endif
cJSON_Delete(pJsonObj);
free((void *)pJsonStr);
return (ret == ERR_SUCCESS) ? ERR_MENU_EXIT : ret;
}
static int on_cmd3(void *pTbl[], const char *pName, void *pInfo) {
const char *pRet;
PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo;
int type = ((arg_lit_t *)pTbl[1])->count;
const char *pValue = ((arg_str_t *)pTbl[2])->sval[0];
int help = get_help_cmd(pTbl, pArg)->count;
if (pArg->pHelp && help > 0) {
pArg->pHelp(pArg->argTbl, pName, NULL);
return ERR_MENU_EXIT;
}
if (type == 0) {
pRet = base64_encode((unsigned char *)pValue, strlen(pValue));
} else {
pRet = (const char *)base64_decode(pValue, NULL);
}
if (pRet == NULL) {
return type == 0 ? -ERR_EVP_ENCRYPTION : -ERR_EVP_DECRYPTION;
}
printf("Base64 %s: {%s} --> [%s]\n", type == 0 ? "encode" : "decode", pValue, pRet);
free((void *)pRet);
return ERR_MENU_EXIT;
}
static int on_cmd4(void *pTbl[], const char *pName, void *pInfo) {
char *pHashValue = NULL;
PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo;
const char *type = ((arg_str_t *)pTbl[1])->sval[0];
const char *pFile = ((arg_file_t *)pTbl[2])->filename[0];
int help = get_help_cmd(pTbl, pArg)->count;
if (pArg->pHelp && help > 0) {
pArg->pHelp(pArg->argTbl, pName, NULL);
return ERR_MENU_EXIT;
}
if (strcmp(type, "sha256") == 0) {
hash_digest_file(HASH_TYPE_SHA256, pFile, &pHashValue);
} else if (strcmp(type, "sha1") == 0) {
hash_digest_file(HASH_TYPE_SHA1, pFile, &pHashValue);
} else if (strcmp(type, "md5") == 0) {
hash_digest_file(HASH_TYPE_MD5, pFile, &pHashValue);
} else {
printf("Unsupported type: %s\n", type);
return -ERR_UNSUP_EVP_TYPE;
}
printf("%s %s hash value: [%s]\n", type, pFile, pHashValue);
free(pHashValue);
return ERR_MENU_EXIT;
}
static int on_cmd5(void *pTbl[], const char *pName, void *pInfo) {
int algType;
const char *strRet;
unsigned char *buf;
int outSize = 0;
PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo;
int encrypt = ((arg_lit_t *)pTbl[1])->count;
const char *alg = ((arg_str_t *)pTbl[2])->sval[0];
const char *key = ((arg_str_t *)pTbl[3])->sval[0];
const char *data = ((arg_str_t *)pTbl[4])->sval[0];
int help = get_help_cmd(pTbl, pArg)->count;
if (pArg->pHelp && help > 0) {
pArg->pHelp(pArg->argTbl, pName, NULL);
return ERR_MENU_EXIT;
}
if (strcmp(alg, "3des_ecb") == 0) {
algType = DES3_ECB_PKCS7PADDING;
} else if (strcmp(alg, "3des_cbc") == 0) {
algType = DES3_CBC_PKCS7PADDING;
} else if (strcmp(alg, "3des_ofb") == 0) {
algType = DES3_OFB_PKCS7PADDING;
} else if (strcmp(alg, "aes128_ecb") == 0) {
algType = AES128_ECB_PKCS7PADDING;
} else if (strcmp(alg, "aes128_ecb_sha1") == 0) {
algType = AES128_ECB_PKCS7PADDING_SHA1PRNG;
} else if (strcmp(alg, "aes128_cbc") == 0) {
algType = AES128_CBC_PKCS7PADDING;
} else if (strcmp(alg, "aes128_ofb") == 0) {
algType = AES128_OFB_PKCS7PADDING;
} else if (strcmp(alg, "aes192_ecb") == 0) {
algType = AES192_ECB_PKCS7PADDING;
} else if (strcmp(alg, "aes192_cbc") == 0) {
algType = AES192_CBC_PKCS7PADDING;
} else if (strcmp(alg, "aes192_ofb") == 0) {
algType = AES192_OFB_PKCS7PADDING;
} else if (strcmp(alg, "aes256_ecb") == 0) {
algType = AES256_ECB_PKCS7PADDING;
} else if (strcmp(alg, "aes256_cbc") == 0) {
algType = AES256_CBC_PKCS7PADDING;
} else if (strcmp(alg, "aes256_ofb") == 0) {
algType = AES256_OFB_PKCS7PADDING;
} else {
printf("Unsupported cipher algorithms: %s\n", alg);
return -ERR_UNSUP_EVP_TYPE;
}
if (encrypt > 0) {
if (symmetric_encrypto(algType, (unsigned char *)data, strlen(data), &buf, &outSize, key) != ERR_SUCCESS) {
printf("Unsupported aes algorithms: %s\n", alg);
return -ERR_EVP_ENCRYPTION;
} else {
strRet = base64_encode((unsigned char *)buf, outSize);
}
} else {
unsigned char *pBase64 = (unsigned char *)base64_decode(data, (unsigned int *)&outSize);
if (pBase64 == NULL) {
printf("Base64 decode error: %s\n", data);
return -ERR_EVP_DECRYPTION;
}
if (symmetric_decrypto(algType, pBase64, outSize, &buf, &outSize, key) != ERR_SUCCESS) {
printf("Unsupported aes algorithms: %s\n", alg);
free((void *)pBase64);
return -ERR_EVP_DECRYPTION;
} else {
buf[outSize] = 0;
strRet = strdup((const char *)buf);
}
}
printf("AES %s: {%s} --> [%s]\n", encrypt > 0 ? "encryption" : "decryption", data, strRet);
free(buf);
free((void *)strRet);
return ERR_MENU_EXIT;
}
static int on_cmd6(void *pTbl[], const char *pName, void *pInfo) {
unsigned char *buf;
int outSize = 0;
PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo;
const char *pKeygen = get_config_keygen();
const char *pKey = ((arg_str_t *)pTbl[1])->sval[0];
int help = get_help_cmd(pTbl, pArg)->count;
if (pArg->pHelp && help > 0) {
pArg->pHelp(pArg->argTbl, pName, NULL);
return ERR_MENU_EXIT;
}
if (symmetric_encrypto(DES3_CBC_PKCS7PADDING, (unsigned char *)pKey, strlen(pKey), &buf, &outSize, pKeygen) !=
ERR_SUCCESS) {
free((void *)pKeygen);
return -ERR_EVP_ENCRYPTION;
} else {
const char *strRet = base64_encode((unsigned char *)buf, outSize);
printf("Key: [%s]\n", strRet);
printf("Keygen: {%s} --> [%s]\n", pKey, strRet);
free((void *)strRet);
}
free(buf);
free((void *)pKeygen);
return ERR_MENU_EXIT;
}
#ifdef DHCPD_ON
static int on_cmd8(void *pTbl[], const char *pName, void *pInfo) {
int ret;
PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo;
const char *pCfgFile = ((arg_file_t *)pTbl[1])->filename[0];
const char *pCfgDir = ((arg_file_t *)pTbl[2])->filename[0];
const char *pIfName = ((arg_str_t *)pTbl[3])->sval[0];
const char *pKey = ((arg_str_t *)pTbl[4])->sval[0];
int help = get_help_cmd(pTbl, pArg)->count;
if (pArg->pHelp && help > 0) {
pArg->pHelp(pArg->argTbl, pName, pTbl);
return ERR_MENU_EXIT;
}
if ((ret = user_init(pCfgFile, pCfgDir, pKey, 0)) != ERR_SUCCESS) {
printf("System init error: %d\n", ret);
return ret;
}
dhcpd_init(MODE_DHCP_SERVER, pIfName);
return ERR_SUCCESS;
}
#endif
#ifdef OPENDHCPD_ON
typedef struct {
int mode;
const char *pIni;
const char *pStatus;
const char *pIfName;
} DHCPD_SETUP, *PDHCPD_SETUP;
static void dhcpd_task(void *pArg) {
PDHCPD_SETUP p = (PDHCPD_SETUP)pArg;
if (p) {
//dhcpd_init(MODE_DHCP_SERVER, p->pIfName);
//dhcpd_main(p->mode, p->pIni, p->pStatus, p->pIfName);
if (p->pIni) {
free((void *)p->pIni);
}
if (p->pStatus) {
free((void *)p->pStatus);
}
if (p->pIfName) {
free((void *)p->pIfName);
}
free(p);
}
}
static int on_cmd7(void *pTbl[], const char *pName, void *pInfo) {
int ret;
// PDHCPD_SETUP p;
static uv_thread_t uvThread;
PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo;
int mode = ((arg_lit_t *)pTbl[1])->count;
const char *pCfgFile = ((arg_file_t *)pTbl[2])->filename[0];
const char *pCfgDir = ((arg_file_t *)pTbl[3])->filename[0];
const char *piniFile = ((arg_file_t *)pTbl[4])->filename[0];
const char *pstatFile = ((arg_file_t *)pTbl[5])->filename[0];
const char *pIfName = ((arg_str_t *)pTbl[6])->sval[0];
#ifdef USERVNI_ON
int *pVni = ((arg_int_t *)pTbl[7])->ival;
const char *pKey = ((arg_str_t *)pTbl[8])->sval[0];
#else
const char *pKey = ((arg_str_t *)pTbl[7])->sval[0];
#endif
int help = get_help_cmd(pTbl, pArg)->count;
if (pArg->pHelp && help > 0) {
pArg->pHelp(pArg->argTbl, pName, pTbl);
return ERR_MENU_EXIT;
}
#ifdef USERVNI_ON
if (pVni && *pVni > 0) {
cfg_set_user_vni_id(*pVni);
} else {
cfg_set_user_vni_id(0);
}
#endif
if ((ret = user_init(pCfgFile, pCfgDir, pKey, 0)) != ERR_SUCCESS) {
printf("System init error: %d\n", ret);
return ret;
}
dhcpd_init(MODE_DHCP_SERVER, pIfName);
#if 0
p = (PDHCPD_SETUP)malloc(sizeof(DHCPD_SETUP));
if (p) {
p->mode = mode;
p->pIni = piniFile ? strdup(piniFile) : NULL;
p->pStatus = pstatFile ? strdup(pstatFile) : NULL;
p->pIfName = pIfName ? strdup(pIfName) : NULL;
uv_thread_create(&uvThread, dhcpd_task, p);
}
#endif
return ERR_SUCCESS;
}
#endif
static int on_cmd_(void *pTbl[], const char *pName, void *pInfo) {
PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo;
int help = get_help_cmd(pTbl, pArg)->count;
//int version = ((arg_lit_t *)pTbl[0])->count;
if (help > 0) {
show_help(pName);
} else {
printf("Application information: %s (Build: %s %s GCC Ver:%s) With %lu(bits) OS\n", PROJECT_GIT_VERSION, __DATE__,
__TIME__, __VERSION__, sizeof(int *) * 8);
#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
printf("OpenSSL information: %s (%s, %s)\n", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_BUILT_ON),
SSLeay_version(SSLEAY_PLATFORM));
#else
printf("OpenSSL information: %s (%s, %s)\n", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_BUILT_ON),
OpenSSL_version(OPENSSL_PLATFORM));
#endif
}
return ERR_MENU_EXIT;
}
int menu_run(int argc, char **argv) {
int ret = ERR_MENU_EXIT;
int i, flag = FALSE;
const char *pAppName = basename_v2(argv[0]);
/*****************************************************************
*
******************************************************************/
// clang-format off
arg_rex_t *cmd1 = arg_rex1(NULL, NULL, "start", NULL, REG_ICASE, NULL);
arg_file_t *cfgfile = arg_filen("c", "config", "[file]", 0, 1,
"\tSpecify the current application configuration file path");
arg_file_t *cfgdir = arg_file1("d", "directory", "<dir>", "\tSpecify the configuration directory path");
arg_str_t *key1 = arg_str0("k", "key", "Key", "\tSpecify the configuration file cryptographic key.");
arg_lit_t *helpCmd1 = arg_lit0("h", "help", NULL);
arg_end_t *end1 = arg_end(20);
void *pArgTbl1[] = {cmd1, cfgfile, cfgdir, key1, helpCmd1, end1};
int errCode1 = 0;
arg_rex_t *cmd2 = arg_rex1(NULL, NULL, "if", NULL, REG_ICASE, NULL);
arg_str_t *server = arg_str1("s", "server", "<svr>", "\tMessage queue server address.");
arg_str_t *type = arg_str1("t", "command", "<get/set>", "\tMessage queue command.");
arg_str_t *key2 = arg_str1("k", "key", "<key>", "\tSystem predefine command \033[1;7mKEY\033[0m value.");
arg_str_t *value2 = arg_str0("v", "value", "value", "\tValue of key when command is need");
arg_lit_t *helpCmd2 = arg_lit0("h", "help", NULL);
arg_end_t *end2 = arg_end(20);
void *pArgTbl2[] = {cmd2, server, type, key2, value2, helpCmd2, end2};
int errCode2 = 0;
arg_rex_t *cmd3 = arg_rex1(NULL, NULL, "base64", NULL, REG_ICASE, NULL);
arg_lit_t *operate3 = arg_litn("o", "operate", 0, 1, "\tBase64 decode, otherwise mean base64 encode");
arg_str_t *value3 = arg_str0(NULL, NULL, "<base64 string>", NULL);
arg_lit_t *helpCmd3 = arg_lit0("h", "help", NULL);
arg_end_t *end3 = arg_end(20);
void *pArgTbl3[] = {cmd3, operate3, value3, helpCmd3, end3};
int errCode3 = 0;
arg_rex_t *cmd4 = arg_rex1(NULL, NULL, "hash", NULL, REG_ICASE, NULL);
arg_file_t *file4 = arg_file0(NULL, NULL, "<file>", NULL);
arg_str_t *alg4 = arg_str0("a", "algorithms", "algorithms", "\tChose \033[1;7mHASH\033[0m algorithms.");
arg_lit_t *helpCmd4 = arg_lit0("h", "help", NULL);
arg_end_t *end4 = arg_end(20);
void *pArgTbl4[] = {cmd4,
alg4,
file4,
arg_rem(NULL, "\tSupport algorithms:"),
arg_rem(NULL, "\t \033[4mmd5\033[0m: file md5 value"),
arg_rem(NULL, "\t \033[4msha1\033[0m: file sha1 value"),
arg_rem(NULL, "\t \033[4msha256\033[0m: file sha256 value"),
helpCmd4,
end4};
int errCode4 = 0;
arg_rex_t *cmd5 = arg_rex1(NULL, NULL, "cipher", NULL, REG_ICASE, NULL);
arg_lit_t *operate5 = arg_litn("e", "encrypt", 0, 1, "\tEncryption, Ignore means decryption.");
arg_str_t *alg5 = arg_str0("a", "algorithms", "algorithms", "\tChose \033[1;7mCryptography\033[0m algorithms.");
arg_str_t *key5 = arg_str0("k", "key", "Key", "\tCryptographic key");
arg_str_t *value5 = arg_str0(NULL, NULL, "<AES string>", NULL);
arg_lit_t *helpCmd5 = arg_lit0("h", "help", NULL);
arg_end_t *end5 = arg_end(20);
void *pArgTbl5[] = {cmd5,
operate5,
alg5,
key5,
value5,
arg_rem(NULL, "\tSupport algorithms:"),
arg_rem(NULL, "\t \033[4m3des_ecb\033[0m: 3DES ECB with PKCS7 padding"),
arg_rem(NULL, "\t \033[4m3des_cbc\033[0m: 3DES CBC with PKCS7 padding"),
arg_rem(NULL, "\t \033[4m3des_ofb\033[0m: 3DES OFB with PKCS7 padding"),
arg_rem(NULL, "\t \033[4maes128_ecb\033[0m: 128 bit AES ECB with PKCS7 padding"),
arg_rem(NULL,
"\t \033[4maes128_ecb_sha1\033[0m: 128 bit AES ECB and used SHA1 key with PKCS7 padding"),
arg_rem(NULL, "\t \033[4maes128_cbc\033[0m: 128 bit AES CBC with PKCS7 padding"),
arg_rem(NULL, "\t \033[4maes128_ofb\033[0m: 128 bit AES OFB with PKCS7 padding"),
arg_rem(NULL, "\t \033[4maes192_ecb\033[0m: 192 bit AES ECB with PKCS7 padding"),
arg_rem(NULL, "\t \033[4maes192_cbc\033[0m: 192 bit AES CBC with PKCS7 padding"),
arg_rem(NULL, "\t \033[4maes192_ofb\033[0m: 192 bit AES OFB with PKCS7 padding"),
arg_rem(NULL, "\t \033[4maes256_ecb\033[0m: 256 bit AES ECB with PKCS7 padding"),
arg_rem(NULL, "\t \033[4maes256_cbc\033[0m: 256 bit AES CBC with PKCS7 padding"),
arg_rem(NULL, "\t \033[4maes256_ofb\033[0m: 256 bit AES OFB with PKCS7 padding"),
helpCmd5,
end5};
int errCode5 = 0;
arg_rex_t *cmd6 = arg_rex1(NULL, NULL, "config", NULL, REG_ICASE, NULL);
arg_str_t *keyGen = arg_str0("k", "keygen", "<Key>", "\tCreate configuration file cryptographic key.");
arg_lit_t *helpCmd6 = arg_lit0("h", "help", NULL);
arg_end_t *end6 = arg_end(20);
void *pArgTbl6[] = {cmd6, keyGen, helpCmd6, end6};
int errCode6 = 0;
#ifdef DHCPD_ON
arg_rex_t *cmd8 = arg_rex1(NULL, NULL, "dhcpd", NULL, REG_ICASE, NULL);
arg_file_t *cfgfile8 = arg_filen("c", "config", "[file]", 0, 1, "\tSpecify the current application configuration file path");
arg_file_t *cfgdir8 = arg_file1("d", "directory", "<dir>", "\tSpecify the configuration directory path");
arg_str_t *ifname = arg_str1("n", "nic", "<ifname>", "\tSpecify the dhcpd service network interface name.");
arg_str_t *key8 = arg_str0("k", "key", "Key", "\tSpecify the configuration file cryptographic key.");
arg_lit_t *helpCmd8 = arg_lit0("h", "help", NULL);
arg_end_t *end8 = arg_end(20);
void *pArgTbl8[] = {cmd8, cfgfile8, cfgdir8,ifname, key8, helpCmd8, end8};
int errCode8 = 0;
#endif
#ifdef OPENDHCPD_ON
arg_rex_t *cmd7 = arg_rex1(NULL, NULL, "dhcpd", NULL, REG_ICASE, NULL);
arg_lit_t *operate7 = arg_lit0("m", "mode", "\tService works on verbatim mode.");
arg_file_t *cfgfile7 = arg_filen("c", "config", "[file]", 0, 1, "\tSpecify the current application configuration file path");
arg_file_t *cfgdir7 = arg_file1("d", "directory", "<dir>", "\tSpecify the configuration directory path");
arg_str_t *key7 = arg_str0("k", "key", "Key", "\tSpecify the configuration file cryptographic key.");
arg_file_t *inifile = arg_filen("i", "ini", "<file>", 0, 1, "\tSpecify the dhcpd service configuration file path");
arg_file_t *statfile = arg_filen("s", "state", "<file>", 0, 1, "\tSpecify the dhcpd service state cache file path");
arg_str_t *ifname = arg_str1("n", "nic", "<ifname>", "\tSpecify the dhcpd service network interface name.");
arg_int_t *vni = arg_intn("v", "vni", "<vni id>", 0, 1, "\tSpecify user vxlan vni id.");
arg_lit_t *helpCmd7 = arg_lit0("h", "help", NULL);
arg_end_t *end7 = arg_end(20);
void *pArgTbl7[] = {cmd7, operate7, cfgfile7, cfgdir7, inifile, statfile, ifname, vni, key7, helpCmd7, end7};
int errCode7 = 0;
#endif
/*****************************************************************
*
******************************************************************/
arg_lit_t *help_ = arg_lit0("h", "help", "\tDisplay this help and exit");
arg_lit_t *version_ = arg_lit0("v", "version", "\tDisplay application version information and exit");
arg_end_t *end_ = arg_end(20);
void *pArgTbl_[] = {version_, help_, end_};
int errCode_ = 0;
ARG_TBL_INFO argTblInfo[] = {
{pArgTbl1, ARRAY_SIZE(pArgTbl1), &errCode1, on_cmd1, cmdn_help,
"\r \033[1;4;36mstart\033[0m: \033[1mRun agent service normally.\033[0m\n"},
#ifdef OPENDHCPD_ON
{pArgTbl7, ARRAY_SIZE(pArgTbl7), &errCode7, on_cmd7, cmdn_help, "\n \033[1;4;36mdhcpd\033[0m: \033[1mRun DHCP service normally.\033[0m\n"},
#endif
#ifdef DHCPD_ON
{pArgTbl8, ARRAY_SIZE(pArgTbl8), &errCode8, on_cmd8, cmdn_help,
"\n \033[1;4;36mdhcpd\033[0m: \033[1mRun DHCP service normally.\033[0m\n"},
#endif
{pArgTbl2, ARRAY_SIZE(pArgTbl2), &errCode2, on_cmd2, cmd2_help,
"\n \033[1;4;36mif\033[0m: \033[1mRun agent interface tools.\033[0m\n"},
{pArgTbl3, ARRAY_SIZE(pArgTbl3), &errCode3, on_cmd3, cmdn_help,
"\n \033[1;4;36mbase64\033[0m: \033[1mString base64 encode/decode.\033[0m\n"},
{pArgTbl4, ARRAY_SIZE(pArgTbl4), &errCode4, on_cmd4, cmdn_help,
"\n \033[1;4;36mhash\033[0m: \033[1mCalculate file's hash value.\033[0m\n"},
{pArgTbl5, ARRAY_SIZE(pArgTbl5), &errCode5, on_cmd5, cmdn_help,
"\n \033[1;4;36mcipher\033[0m: \033[1mSymmetric cryptography for string.\033[0m\n"},
{pArgTbl6, ARRAY_SIZE(pArgTbl6), &errCode6, on_cmd6, cmdn_help,
"\n \033[1;4;36mconfig\033[0m: \033[1mConfiguration file tools.\033[0m\n"},
{pArgTbl_, ARRAY_SIZE(pArgTbl_), &errCode_, on_cmd_, NULL, NULL},
};
// clang-format on
g_pArgTbl = argTblInfo;
g_nArgTbl = ARRAY_SIZE(argTblInfo);
for (i = 0; i < g_nArgTbl; i++) {
if (arg_nullcheck(argTblInfo[i].argTbl) != 0) {
printf("%s insufficient memory\n", pAppName);
return -ERR_SYS_INIT;
}
}
cfgfile->filename[0] = "-";
for (i = 0; i < g_nArgTbl; i++) {
*argTblInfo[i].pErrCode = arg_parse(argc, argv, argTblInfo[i].argTbl);
}
for (i = 0; i < g_nArgTbl; i++) {
PARG_TBL_INFO pArg = &argTblInfo[i];
if (*pArg->pErrCode == 0 && pArg->pCmd) {
ret = pArg->pCmd(pArg->argTbl, pAppName, pArg);
if (ret != ERR_SUCCESS && ret != ERR_MENU_EXIT) {
if (pArg->pHelp) {
pArg->pHelp(pArg->argTbl, pAppName, NULL);
}
} else {
flag = TRUE;
}
}
}
if (flag == FALSE) {
for (i = 0; i < g_nArgTbl - 1; i++) {
PARG_TBL_INFO pArg = &argTblInfo[i];
if (*pArg->pErrCode != 0) {
if (get_reg_cmd(pArg->argTbl) > 0 && pArg->pHelp) {
int help = get_help_cmd(pArg->argTbl, pArg)->count;
pArg->pHelp(pArg->argTbl, pAppName, help > 0 ? NULL : get_arg_err(pArg->argTbl, pArg));
flag = TRUE;
break;
}
}
}
if (flag == FALSE) {
show_help(pAppName);
}
}
for (i = 0; i < g_nArgTbl; i++) {
arg_freetable(argTblInfo[i].argTbl, argTblInfo[i].nArgItem);
}
return ret;
}

View File

@ -0,0 +1,786 @@
//
// Created by xajhu on 2021/7/30 0030.
//
#include <libconfig.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#include <sds/sds.h>
#include "uthash/uthash.h"
#include "config.h"
#include "misc.h"
#include "user_errno.h"
#include "crypto.h"
#include "hardware.h"
#include "zlog_module.h"
#include "common.h"
typedef struct {
CONFIG_ITEM_ID cfgId;
const char *cfgPath;
CONFIG_VALUE_TYPE valType;
const char *defValue;
const char *readme;
const char *pStrId;
} CFG_ITEM, *PCFG_ITEM;
#define CFG_INT_VALUE(p) (p->value.longValue)
#define CFG_BOOL_VALUE(p) (p->value.longValue == FALSE ? FALSE : TRUE)
#define CFG_FLOAT_VALUE(p) (p->value.floatValue)
#define CFG_STRING_VALUE(p) (p->value.strValue)
#define ENC_HEAD ("AES@")
typedef union {
long long longValue;
char *strValue;
long double floatValue;
c_vector array;
} CFG_VALUE, *PCFG_VALUE;
typedef struct {
CONFIG_ITEM_ID cfgId;
const char *pcfgKey;
CONFIG_VALUE_TYPE valType;
const char *defaultValue;
int isChanged;
const char *pMessage;
const char *pStrId;
CFG_VALUE value;
UT_hash_handle hh;
} CONFIG_ITEM, *PCONFIG_ITEM;
static config_t g_cfgContent;
static const char *g_cfgFilePath;
static const char *g_pCfgKey = NULL;
PCONFIG_ITEM g_pConfigItem = NULL;
#define DEF_CFG_ITEM(id, key, type, defVal, desc) \
{ .cfgId = (id), .cfgPath = (key), .valType = (type), .defValue = (defVal), .readme = (desc), .pStrId = (#id) }
// clang-format off
static CFG_ITEM g_cfgItem[] = {
DEF_CFG_ITEM(CFG_DIRECTORY, "system.config_file_path", VAL_STR, ".", "Configuration files location path"),
DEF_CFG_ITEM(CFG_CURL_CA_PATH, "system.ssl_ca_file_path", VAL_STR, "~/.ssh/ca.crt", "Libcurl access HTTPS CA File"),
DEF_CFG_ITEM(CFG_BANNER_SHOW, "system.show_banner", VAL_BOOL, "1", "Enable/Disable show banner"),
DEF_CFG_ITEM(CFG_HARDWARE_WATCH, "system.system_info_watch", VAL_BOOL, "1", "Monitor cpu, memory, disk, fan, temperature ..."),
DEF_CFG_ITEM(CFG_HARDWARE_REFRESH, "system.system_info_refresh", VAL_INT, "10", "Monitor hardware information upgrade frequency"),
// Agent 配置
DEF_CFG_ITEM(CFG_AGENT_IPTV_POST_URL, "agent.iptv_report_url", VAL_STR, "", "IPTV report URL"),
DEF_CFG_ITEM(CFG_AGENT_MONITER_URL, "agent.moniter_rep_url", VAL_STR, "", "vCPE moniter report URL"),
/* 系统监控设备相配置 */
DEF_CFG_ITEM(CFG_WATCH_CPU, "watch_params.cpu", VAL_BOOL, "1", "Monitor cpu information"),
DEF_CFG_ITEM(CFG_WATCH_MEMORY, "watch_params.memory", VAL_BOOL, "1", "Monitor memory information"),
DEF_CFG_ITEM(CFG_WATCH_DISK, "watch_params.disk", VAL_BOOL, "1", "Monitor disk partition information"),
DEF_CFG_ITEM(CFG_WATCH_SENSOR, "watch_params.sensor", VAL_BOOL, "1", "Sensor information refresh frequency"),
/* 数据库相配置 */
/* Redis配置 */
#ifdef USED_REDIS
DEF_CFG_ITEM(CFG_DB_REDIS_SERVER, "database.redis_server", VAL_STR, "127.0.0.1", "Redis database server ip address"),
DEF_CFG_ITEM(CFG_DB_REDIS_PORT, "database.redis_port", VAL_INT, "6379", "Redis database server port"),
DEF_CFG_ITEM(CFG_DB_REDIS_PASSWD, "database.redis_passwd", VAL_STR, "", "Redis database server password"),
#endif
/* MySQL配置 */
#ifdef USED_MYSQL
DEF_CFG_ITEM(CFG_DB_MYSQL_SERVER, "database.mysql_server", VAL_STR, "127.0.0.1", "MySQL database server ip address"),
DEF_CFG_ITEM(CFG_DB_MYSQL_PORT, "database.mysql_port", VAL_INT, "3306", "MySQL database server port"),
DEF_CFG_ITEM(CFG_DB_MYSQL_USER, "database.mysql_user", VAL_STR, "", "MySQL database user name"),
DEF_CFG_ITEM(CFG_DB_MYSQL_PASSWD, "database.mysql_passwd", VAL_STR, "", "MySQL database server password"),
DEF_CFG_ITEM(CFG_DB_MYSQL_DB_NAME, "database.mysql_database", VAL_STR, ".main", "MySQL database used"),
#endif
/* SQLite3配置 */
#ifdef SQLITE_ON
DEF_CFG_ITEM(CFG_DB_SQLITE_DB_NAME, "database.sqlite_dbname", VAL_STR, "", "SQLite3 database file name"),
#ifdef SQLITE_CRYPTO_ON
DEF_CFG_ITEM(CFG_DB_SQLITE_PASSWD, "database.sqlite_passwd", VAL_STR, "", "SQLite3 database password"),
#endif
#endif
#ifdef ZEROMQ_ON
/* 消息队列相配置 */
/* ZeroMq配置 */
DEF_CFG_ITEM(CFG_MQ_SVR_PORT, "zero_mq.svr_port", VAL_INT, "6278", "ZeroMQ server port"),
DEF_CFG_ITEM(CFG_MQ_DATA_PATH, "zero_mq.agent_addr", VAL_STR, "ipc:///tmp/msg_fifo0", "ZeroMQ Agent data path"),
#endif
/* vxLan 隧道配置 */
DEF_CFG_ITEM(CFG_VXLAN_NIC_NAME, "vxlan_wan.nic", VAL_STR, "", "Network card name to send data"),
DEF_CFG_ITEM(CFG_VXLAN_SUPPORT, "vxlan_wan.enable", VAL_BOOL, "1", "Is support vxLan tune"),
DEF_CFG_ITEM(CFG_VXLAN_PEER_IP, "vxlan_wan.peer_ip", VAL_STR, "", "vxLan peer ip address"),
DEF_CFG_ITEM(CFG_VXLAN_PEER_MAC, "vxlan_wan.peer_mac", VAL_STR, "", "vxLan peer mac address"),
DEF_CFG_ITEM(CFG_VXLAN_PKG_FILTER, "vxlan_wan.pkg_filter", VAL_STR, "", "vxLan package filter"),
/*HTTP Server 配置*/
#ifdef HTTPSERVER_ON
DEF_CFG_ITEM(CFG_HTTP_SVR_URI, "http_svr.uri", VAL_STR, "http://0.0.0.0:6789", "Network address to listen on"),
#endif
DEF_CFG_ITEM(CFG_PROTO_CRYPTO, "protocol.crypto_type", VAL_INT, "0", "Protocol crypto_cipher algorithm"),
DEF_CFG_ITEM(CFG_PROTO_CRYPTO_KEY, "protocol.crypto_key", VAL_STR, "", "Protocol crypto_cipher keys"),
#ifdef DHCPD_ON
// 配置DHCP服务器
DEF_CFG_ITEM(CFG_DHCP_LEASE_TIME, "dhcp_server.lease_time", VAL_INT, "36000", "DHCP server lease time"),
DEF_CFG_ITEM(CFG_DHCP_LISTEN_ON, "dhcp_server.listen_on", VAL_ARRAY_STR, "", "DHCP listen interface"),
DEF_CFG_ITEM(CFG_DHCP_REPLICATION_SVR, "dhcp_server.replication", VAL_ARRAY_STR, "", "DHCP replication server configure"),
DEF_CFG_ITEM(CFG_DHCP_RANGE_SET, "dhcp_server.range_set", VAL_ARRAY_OBJ, "", "DHCP IP pool"),
DEF_CFG_ITEM(CFG_DHCP_NET_FILTER, "dhcp_server.net_filter", VAL_STR, "", "DHCP packet filter"),
DEF_CFG_ITEM(CFG_DHCP_MAC_FILTER, "dhcp_server.mac_filter", VAL_ARRAY_STR, "", "DHCP client MAC address black list"),
DEF_CFG_ITEM(CFG_DHCP_NIC_NAME, "dhcp_server.nic", VAL_STR, "ens192", "DHCP server network interface name"),
#endif
}; // clang-format on
static int cfg_is_upgrade(PCONFIG_ITEM pItem) {
if (pItem->isChanged) {
pItem->isChanged = FALSE;
return TRUE;
}
return FALSE;
}
static const char *load_string_value(const char *pKeyName) {
const char *pCfgVal;
if (config_lookup_string(&g_cfgContent, pKeyName, &pCfgVal) != CONFIG_TRUE) {
LOG_MOD(error, ZLOG_MOD_CONFIG, "No {%s} setting in configuration file.\n", pKeyName);
return NULL;
}
if (strncmp(ENC_HEAD, pCfgVal, strlen(ENC_HEAD)) == 0) {
if (g_pCfgKey == NULL || strlen(g_pCfgKey) == 0) {
return NULL;
} else {
const char *pKey = get_config_key(g_pCfgKey);
int bufSize, outSize;
unsigned char *buf;
unsigned char *pBuf = base64_decode(&pCfgVal[strlen(ENC_HEAD)], (unsigned int *)&bufSize);
if (pBuf == NULL || bufSize <= 0) {
LOG_MOD(error, ZLOG_MOD_CONFIG, "{%s} setting [%s] maybe a encryption message, base64 decode error.\n",
pKeyName, pCfgVal);
return NULL;
}
if (symmetric_decrypto(AES128_ECB_PKCS7PADDING_SHA1PRNG, pBuf, bufSize, &buf, &outSize, pKey) !=
ERR_SUCCESS) {
free((void *)pKey);
free(pBuf);
return NULL;
}
free(pBuf);
free((void *)pKey);
buf[outSize] = 0;
return (const char *)buf;
}
} else {
return strdup(pCfgVal);
}
}
static int load_boolean_value(const char *pKeyName) {
int val;
if (config_lookup_bool(&g_cfgContent, pKeyName, &val) != CONFIG_TRUE) {
LOG_MOD(error, ZLOG_MOD_CONFIG, "No {%s} setting in configuration file.\n", pKeyName);
return DEFAULT_INTEGRAL_ERR_VALUE;
}
return val;
}
static long long int load_integral_value(const char *pKeyName) {
long long val;
if (config_lookup_int64(&g_cfgContent, pKeyName, &val) != CONFIG_TRUE) {
LOG_MOD(error, ZLOG_MOD_CONFIG, "No {%s} setting in configuration file.\n", pKeyName);
return DEFAULT_INTEGRAL_ERR_VALUE;
}
return val;
}
static double load_float_value(const char *pKeyName) {
double val;
if (config_lookup_float(&g_cfgContent, pKeyName, &val) != CONFIG_TRUE) {
LOG_MOD(error, ZLOG_MOD_CONFIG, "No {%s} setting in configuration file.\n", pKeyName);
return DEFAULT_INTEGRAL_ERR_VALUE;
}
return val;
}
static int cmp_str(const void *a, const void *b) {
return strcmp((const char *)a, (const char *)b);
}
static int load_array_str(const char *pKeyName, PCONFIG_ITEM pValue) {
int i;
config_setting_t *pItem = config_lookup(&g_cfgContent, pKeyName);
if (pItem) {
for (i = 0; i < config_setting_length(pItem); i++) {
const char *pVal = config_setting_get_string_elem(pItem, i);
if (pVal) {
zvect_index idx = 0;
if (!vect_bsearch(pValue->value.array, pVal, cmp_str, &idx)) {
vect_push(pValue->value.array, pVal);
pValue->isChanged = TRUE;
}
}
}
vect_shrink(pValue->value.array);
return ERR_SUCCESS;
}
return -ERR_ITEM_UNEXISTS;
}
static int cmp_dhcp_obj(const void *a, const void *b) {
POBJ_DHCP_RNG pV1 = (POBJ_DHCP_RNG)a;
POBJ_DHCP_RNG pV2 = (POBJ_DHCP_RNG)b;
if (strcmp(pV1->rangAddr, pV2->rangAddr) == 0 && strcmp(pV1->subnet, pV2->subnet) == 0 &&
strcmp(pV1->dnsSvr, pV2->dnsSvr) == 0 && strcmp(pV1->gateway, pV2->gateway) == 0 && pV1->lease == pV2->lease) {
return 0;
}
return -1;
}
static int load_array_obj(const char *pKeyName, PCONFIG_ITEM pValue) {
int i;
config_setting_t *pItem = config_lookup(&g_cfgContent, pKeyName);
if (!pItem) {
return -ERR_ITEM_UNEXISTS;
}
for (i = 0; i < config_setting_length(pItem); i++) {
OBJ_DHCP_RNG v, k;
config_setting_t *pObj = config_setting_get_elem(pItem, i);
switch (pValue->cfgId) {
#if DHCPD_ON
case CFG_DHCP_RANGE_SET: {
zvect_index idx = -1;
const char *rangAddr, *subnet, *dnsSvr, *gateway;
memset(&v, 0, sizeof(OBJ_DHCP_RNG));
if (config_setting_lookup_string(pObj, "dhcp_range", &rangAddr)) {
strcpy(v.rangAddr, rangAddr);
}
if (config_setting_lookup_string(pObj, "subnet_mask", &subnet)) {
strcpy(v.subnet, subnet);
}
if (config_setting_lookup_string(pObj, "domain_server", &dnsSvr)) {
strcpy(v.dnsSvr, dnsSvr);
}
if (config_setting_lookup_string(pObj, "gateway", &gateway)) {
strcpy(v.gateway, gateway);
}
if (!config_setting_lookup_int(pObj, "lease_time", (int *)&v.lease)) {
v.lease = 0xFFFFFFFF;
}
if (!config_setting_lookup_int(pObj, "vni", (int *)&v.vni)) {
v.vni = 0;
}
if (!config_setting_lookup_int(pObj, "gid", (int *)&v.gid)) {
v.gid = 0;
}
if (!vect_bsearch(pValue->value.array, &v, cmp_dhcp_obj, &idx)) {
memcpy(&k, &v, sizeof(OBJ_DHCP_RNG));
vect_push(pValue->value.array, &k);
pValue->isChanged = TRUE;
}
} break;
#endif
default:
break;
}
}
return ERR_SUCCESS;
}
static int setConfigItemValue(PCONFIG_ITEM pItem, const char *pValue) {
errno = 0;
if (pItem->valType == VAL_STR) {
if (pItem->value.strValue != NULL) {
free(pItem->value.strValue);
}
pItem->value.strValue = strdup(pValue);
} else if (pItem->valType == VAL_INT || pItem->valType == VAL_BOOL) {
char *pOver;
long long val = strtoll(pValue, &pOver, 10);
if ((pOver != NULL && strlen(pOver)) || errno != 0) {
return -ERR_STRING_TO_NUMBER;
}
pItem->value.longValue = val;
} else if (pItem->valType == VAL_FLOAT) {
char *pOver;
long double val = strtold(pValue, &pOver);
if ((pOver != NULL && strlen(pOver)) || errno != 0) {
return -ERR_STRING_TO_NUMBER;
}
pItem->value.floatValue = val;
} else if (pItem->valType == VAL_ARRAY_STR) {
pItem->value.array = vect_create(128, 512, ZV_SEC_WIPE);
} else if (pItem->valType == VAL_ARRAY_OBJ) {
pItem->value.array = vect_create(128, sizeof(OBJ_DHCP_RNG), ZV_SEC_WIPE);
} else {
return -ERR_UN_SUPPORT;
}
return ERR_SUCCESS;
}
static int add_new_cfg_item(CONFIG_ITEM_ID id,
const char *pKey,
CONFIG_VALUE_TYPE valType,
const char *pDefVal,
const char *pStrId,
const char *pDesc) {
PCONFIG_ITEM pItem;
int ret;
HASH_FIND_INT(g_pConfigItem, &id, pItem);
if (pItem != NULL) {
return -ERR_ITEM_EXISTS;
}
pItem = (PCONFIG_ITEM)malloc(sizeof(CONFIG_ITEM));
if (pItem == NULL) {
return -ERR_MALLOC_MEMORY;
}
memset(pItem, 0, sizeof(CONFIG_ITEM));
pItem->cfgId = id;
pItem->pcfgKey = pKey;
pItem->valType = valType;
pItem->defaultValue = pDefVal;
pItem->pMessage = pDesc;
pItem->pStrId = pStrId;
ret = setConfigItemValue(pItem, pItem->defaultValue);
if (ret != ERR_SUCCESS) {
free(pItem);
return ret;
}
HASH_ADD_INT(g_pConfigItem, cfgId, pItem);
return ERR_SUCCESS;
}
static PCFG_VALUE cfg_get_value(CONFIG_ITEM_ID id) {
PCONFIG_ITEM pItem;
HASH_FIND_INT(g_pConfigItem, &id, pItem);
if (pItem != NULL) {
return &pItem->value;
}
return NULL;
}
static void refreshCfgFileCb() {
PCONFIG_ITEM pItem, pTmp;
int cfgUpgrade = FALSE;
if (!config_read_file(&g_cfgContent, g_cfgFilePath)) {
LOG_MOD(error, ZLOG_MOD_CONFIG, "%s:%d - %s\n", config_error_file(&g_cfgContent),
config_error_line(&g_cfgContent), config_error_text(&g_cfgContent));
return;
}
HASH_ITER(hh, g_pConfigItem, pItem, pTmp) {
char *pStr;
long long iVal;
double fVal;
sds realKey = sdsnew("application.");
realKey = sdscat(realKey, pItem->pcfgKey);
switch (pItem->valType) {
case VAL_STR:
pStr = (char *)load_string_value(realKey);
if (pStr) {
if (strcmp(pItem->value.strValue, pStr) != 0) {
if (pItem->value.strValue != NULL) {
free(pItem->value.strValue);
}
pItem->value.strValue = strdup(pStr);
pItem->isChanged = TRUE;
}
free(pStr);
}
break;
case VAL_BOOL:
iVal = load_boolean_value(realKey);
if (iVal != DEFAULT_INTEGRAL_ERR_VALUE) {
if (pItem->value.longValue != iVal) {
pItem->value.longValue = iVal;
pItem->isChanged = TRUE;
}
}
break;
case VAL_INT:
iVal = load_integral_value(realKey);
if (iVal != DEFAULT_INTEGRAL_ERR_VALUE) {
if (pItem->value.longValue != iVal) {
pItem->value.longValue = iVal;
pItem->isChanged = TRUE;
}
}
break;
case VAL_FLOAT:
fVal = load_float_value(realKey);
if (fVal != DEFAULT_INTEGRAL_ERR_VALUE) {
if (pItem->value.floatValue != fVal) {
pItem->value.floatValue = fVal;
pItem->isChanged = TRUE;
}
}
break;
case VAL_ARRAY_STR:
load_array_str(realKey, pItem);
break;
case VAL_ARRAY_OBJ:
load_array_obj(realKey, pItem);
break;
default:
break;
}
if (pItem->isChanged) {
cfgUpgrade = TRUE;
}
sdsfree(realKey);
}
if (cfgUpgrade) {
config_item_dump("Configuration upgrade");
}
}
const char *config_item_dump_fmt(const char *titleMessage) {
int i;
const char *pResp;
PCONFIG_ITEM pItem, pTmp;
char tmp2[256];
sds tmp;
sds s = sdsempty();
if (titleMessage && strlen(titleMessage) > 0) {
s = sdscatprintf(s, "%s:\n", titleMessage);
}
s = sdscat(s,
"--------------------------------------------------------------------------------"
"-----------------------------------------------------------------------\n");
s = sdscat(s,
"| id | Key Name | Configuration file key |"
" value |\n");
s = sdscat(s,
"--------------------------------------------------------------------------------"
"-----------------------------------------------------------------------\n");
HASH_ITER(hh, g_pConfigItem, pItem, pTmp) {
memset(tmp2, 0, 256);
sprintf(tmp2, "%s%s", cfg_is_upgrade(pItem) ? "*" : " ", pItem->pStrId);
switch (pItem->valType) {
case VAL_BOOL:
s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, pItem->pcfgKey,
CFG_BOOL_VALUE(pItem) ? "True" : "False");
break;
case VAL_INT:
s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64lld |\n", pItem->cfgId, tmp2, pItem->pcfgKey,
CFG_INT_VALUE(pItem));
break;
case VAL_FLOAT:
s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64Lf |\n", pItem->cfgId, tmp2, pItem->pcfgKey,
CFG_FLOAT_VALUE(pItem));
break;
case VAL_STR:
tmp = sdsempty();
tmp = sdscatprintf(tmp, "\"%s\"", CFG_STRING_VALUE(pItem));
if (sdslen(tmp) > 63) {
sdsrange(tmp, 0, 59);
tmp = sdscat(tmp, "...\"");
}
s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, pItem->pcfgKey, tmp);
sdsfree(tmp);
break;
case VAL_ARRAY_STR:
tmp = sdsempty();
tmp = sdscat(tmp, "[");
for (i = 0; i < vect_size(pItem->value.array); i++) {
const char *p = (const char *)vect_get_at(pItem->value.array, i);
if (p) {
tmp = sdscatfmt(tmp, "\"%s\",", p);
}
}
sdsrange(tmp, 0, -2);
tmp = sdscat(tmp, "]");
//tmp = sdscatprintf(tmp, "\"%s\"", CFG_STRING_VALUE(pItem));
if (sdslen(tmp) > 63) {
sdsrange(tmp, 0, 58);
tmp = sdscat(tmp, "...\"]");
}
s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, pItem->pcfgKey, tmp);
sdsfree(tmp);
break;
case VAL_ARRAY_OBJ:
for (i = 0; i < vect_size(pItem->value.array); i++) {
POBJ_DHCP_RNG p = (POBJ_DHCP_RNG)vect_get_at(pItem->value.array, i);
if (!p) {
continue;
}
sds title = sdsempty();
sds keyRang = sdsempty();
sds keySubnet = sdsempty();
sds keyDns = sdsempty();
sds keyGateway = sdsempty();
title = sdscatprintf(title, "%s[%d]", pItem->pcfgKey, i);
keyRang = sdscatprintf(keyRang, "\"%s\"", p->rangAddr);
keySubnet = sdscatprintf(keySubnet, "\"%s\"", p->subnet);
keyDns = sdscatprintf(keyDns, "\"%s\"", p->dnsSvr);
keyGateway = sdscatprintf(keyGateway, "\"%s\"", p->gateway);
s = sdscatprintf(s, "|%4d | %-25s | %-45s | %-64s |\n", pItem->cfgId, tmp2, title, "");
s = sdscatprintf(s, "| | %-25s | %-45s | %-64u |\n", "", " .vni", p->vni);
s = sdscatprintf(s, "| | %-25s | %-45s | %-64s |\n", "", " .dhcp_range", keyRang);
s = sdscatprintf(s, "| | %-25s | %-45s | %-64s |\n", "", " .subnet_mask", keySubnet);
s = sdscatprintf(s, "| | %-25s | %-45s | %-64s |\n", "", " .domain_server", keyDns);
s = sdscatprintf(s, "| | %-25s | %-45s | %-64s |\n", "", " .gateway", keyGateway);
s = sdscatprintf(s, "| | %-25s | %-45s | %-64u |\n", "", " .lease_time", p->lease);
sdsfree(title);
sdsfree(keyRang);
sdsfree(keySubnet);
sdsfree(keyDns);
sdsfree(keyGateway);
}
break;
default:
break;
}
}
s = sdscat(s,
"--------------------------------------------------------------------------------"
"-----------------------------------------------------------------------\n");
pResp = strdup(s);
sdsfree(s);
return pResp;
}
void config_item_dump(const char *titleMessage) {
const char *pMsg = config_item_dump_fmt(titleMessage);
LOG_MOD(info, ZLOG_MOD_CONFIG, "%s", pMsg);
free((char *)pMsg);
#if 0
PCONFIG_ITEM pItem, pTmp;
//int i, k = ARRAY_SIZE(g_sysConfigMap);
LOG_MOD(info, ZLOG_MOD_CONFIG, "================== %s ===================\n", titleMessage == NULL ? "" : titleMessage);
HASH_ITER(hh, g_pConfigItem, pItem, pTmp) {
switch (pItem->valType) {
case VAL_BOOL:
LOG_MOD(info, ZLOG_MOD_CONFIG, "%s%-25s: [%-45s] = %s\n",
cfg_is_upgrade(pItem) ? "*" : " ",
pItem->pStrId,
pItem->pcfgKey,
CFG_BOOL_VALUE(pItem) ? "True" : "False");
break;
case VAL_INT:
LOG_MOD(info, ZLOG_MOD_CONFIG, "%s%-25s: [%-45s] = %lld\n",
cfg_is_upgrade(pItem) ? "*" : " ",
pItem->pStrId,
pItem->pcfgKey,
CFG_INT_VALUE(pItem));
break;
case VAL_FLOAT:
LOG_MOD(info, ZLOG_MOD_CONFIG, "%s%-25s: [%-45s] = %Lf\n",
cfg_is_upgrade(pItem) ? "*" : " ",
pItem->pStrId,
pItem->pcfgKey,
CFG_FLOAT_VALUE(pItem));
break;
case VAL_STR:
LOG_MOD(info, ZLOG_MOD_CONFIG, "%s%-25s: [%-45s] = \"%s\"\n",
cfg_is_upgrade(pItem) ? "*" : " ",
pItem->pStrId,
pItem->pcfgKey,
CFG_STRING_VALUE(pItem));
break;
default:
break;
}
}
#endif
}
long double cfg_get_float_value(CONFIG_ITEM_ID id) {
PCFG_VALUE pVal = cfg_get_value(id);
if (pVal) {
return pVal->floatValue;
} else {
return DEFAULT_INTEGRAL_ERR_VALUE;
}
}
long long cfg_get_integral_value(CONFIG_ITEM_ID id) {
PCFG_VALUE pVal = cfg_get_value(id);
if (pVal) {
return pVal->longValue;
} else {
return DEFAULT_INTEGRAL_ERR_VALUE;
}
}
int cfg_get_bool_value(CONFIG_ITEM_ID id) {
PCFG_VALUE pVal = cfg_get_value(id);
if (pVal) {
return pVal->longValue == FALSE ? FALSE : TRUE;
} else {
return DEFAULT_INTEGRAL_ERR_VALUE;
}
}
const char *cfg_get_string_value(CONFIG_ITEM_ID id) {
PCFG_VALUE pVal = cfg_get_value(id);
if (pVal) {
return pVal->strValue;
} else {
return NULL;
}
}
c_vector cfg_get_vector(CONFIG_ITEM_ID id) {
PCFG_VALUE pVal = cfg_get_value(id);
if (pVal) {
return pVal->array;
} else {
return NULL;
}
}
int init_config_system(const char *pCfgFile, const char *pKey) {
int i;
if (!file_exists(pCfgFile)) {
LOG_MOD(error, ZLOG_MOD_CONFIG, "Configuration file [%s] not exists\n", pCfgFile);
return -ERR_FILE_NOT_EXISTS;
}
g_pCfgKey = strdup(pKey == NULL ? "" : pKey);
g_cfgFilePath = strdup(pCfgFile);
config_init(&g_cfgContent);
for (i = 0; i < ARRAY_SIZE(g_cfgItem); i++) {
add_new_cfg_item(g_cfgItem[i].cfgId, g_cfgItem[i].cfgPath, g_cfgItem[i].valType, g_cfgItem[i].defValue,
g_cfgItem[i].pStrId, g_cfgItem[i].readme);
}
// clang-format on
refreshCfgFileCb();
return ERR_SUCCESS;
}
void uninit_config_system() {
PCONFIG_ITEM pItem, pTmp;
HASH_ITER(hh, g_pConfigItem, pItem, pTmp) {
switch (pItem->valType) {
case VAL_ARRAY_STR:
case VAL_ARRAY_OBJ:
vect_destroy(pItem->value.array);
break;
default:
break;
}
}
config_destroy(&g_cfgContent);
}
const char *get_config_keygen() {
char buf[MAX_PATH];
CPU_INFO cpuInfo;
get_cpu_info(&cpuInfo);
memset(buf, 0, MAX_PATH);
sprintf(buf, "%d#%s", cpuInfo.nLogicCores, cpuInfo.cpuCoreDesc.cpuName);
return strdup(buf);
}
const char *get_config_key(const char *pKeygen) {
int outSize;
unsigned char *buf = NULL;
const char *strRet;
const char *pKey = get_config_keygen();
unsigned char *pBase64 = (unsigned char *)base64_decode(pKeygen, (unsigned int *)&outSize);
if (pBase64 == NULL) {
LOG_MOD(error, ZLOG_MOD_CONFIG, "Base64 decode error: %s\n", pKeygen);
return NULL;
}
if (symmetric_decrypto(DES3_CBC_PKCS7PADDING, pBase64, outSize, &buf, &outSize, pKey) != ERR_SUCCESS) {
free((void *)pKey);
free((void *)pBase64);
if (buf) {
free(buf);
}
return NULL;
} else {
buf[outSize] = 0;
strRet = strdup((const char *)buf);
}
free(buf);
free((void *)pKey);
free((void *)pBase64);
return strRet;
}

View File

@ -0,0 +1,188 @@
//
// Created by xajhu on 2021/7/7 0007.
//
#include "config.h"
#ifdef USERVNI_ON
static int g_user_vni_id = -1;
void cfg_set_user_vni_id(int vni) {
if (g_user_vni_id != vni) {
g_user_vni_id = vni;
}
}
int cfg_get_user_vni_id() {
if (g_user_vni_id > 0xFFFFFF) {
return 0;
}
return g_user_vni_id;
}
#endif
unsigned int config_get_proto_crypto_type() {
return cfg_get_integral_value(CFG_PROTO_CRYPTO);
}
const char *config_get_proto_crypto_key() {
return cfg_get_string_value(CFG_PROTO_CRYPTO_KEY);
}
#if DHCPD_ON
unsigned int config_get_dhcp_server_lease_time() {
return cfg_get_integral_value(CFG_DHCP_LEASE_TIME);
}
c_vector config_get_dhcp_server_range_set() {
return cfg_get_vector(CFG_DHCP_RANGE_SET);
}
c_vector config_get_dhcp_listen_on() {
return cfg_get_vector(CFG_DHCP_LISTEN_ON);
}
c_vector config_get_dhcp_replication_svr() {
return cfg_get_vector(CFG_DHCP_REPLICATION_SVR);
}
const char *config_get_dhcp_net_filter() {
return cfg_get_string_value(CFG_DHCP_NET_FILTER);
}
c_vector config_get_dhcp_mac_filter() {
return cfg_get_vector(CFG_DHCP_MAC_FILTER);
}
const char *config_get_dhcp_nic_name() {
return cfg_get_string_value(CFG_DHCP_NIC_NAME);
}
#endif
const char *config_get_agent_iptv_report_url() {
return cfg_get_string_value(CFG_AGENT_IPTV_POST_URL);
}
const char *config_get_agent_moniter_report_url() {
return cfg_get_string_value(CFG_AGENT_MONITER_URL);
}
#ifdef HTTPSERVER_ON
const char *config_get_http_server_addr() {
return cfg_get_string_value(CFG_HTTP_SVR_URI);
}
#endif
#ifdef LWIP_ON
const char *config_get_vxlan_nic_name() {
return cfg_get_string_value(CFG_VXLAN_NIC_NAME);
}
const char *config_get_vxlan_peer_ip() {
return cfg_get_string_value(CFG_VXLAN_PEER_IP);
}
const char *config_get_vxlan_peer_mac() {
return cfg_get_string_value(CFG_VXLAN_PEER_MAC);
}
const char *config_get_vxlan_pkg_filter() {
return cfg_get_string_value(CFG_VXLAN_PKG_FILTER);
}
int cfg_get_support_vxlan() {
return cfg_get_bool_value(CFG_VXLAN_SUPPORT);
}
#endif
const char *config_get_ssl_ca_path() {
return cfg_get_string_value(CFG_CURL_CA_PATH);
}
const char *cfg_get_config_directory() {
return cfg_get_string_value(CFG_DIRECTORY);
}
int cfg_get_banner_enable() {
return cfg_get_bool_value(CFG_BANNER_SHOW);
}
int cfg_get_hardware_watch_enable() {
return cfg_get_bool_value(CFG_HARDWARE_WATCH);
}
unsigned int cfg_get_hardware_refresh_period() {
return cfg_get_integral_value(CFG_HARDWARE_REFRESH);
}
int cfg_get_watch_cpu() {
return cfg_get_bool_value(CFG_WATCH_CPU);
}
int cfg_get_watch_memory() {
return cfg_get_bool_value(CFG_WATCH_MEMORY);
}
int cfg_get_watch_disk() {
return cfg_get_bool_value(CFG_WATCH_DISK);
}
int cfg_get_watch_sensor() {
return cfg_get_bool_value(CFG_WATCH_SENSOR);
}
#ifdef SQLITE_ON
const char *cfg_get_sqlite_db_name() {
return cfg_get_string_value(CFG_DB_SQLITE_DB_NAME);
}
#ifdef SQLITE_CRYPTO_ON
const char *cfg_get_sqlite_passwd() {
return cfg_get_string_value(CFG_DB_SQLITE_PASSWD);
}
#endif
#endif
#ifdef USED_REDIS
const char *cfg_get_redis_server() {
return cfg_get_string_value(CFG_DB_REDIS_SERVER);
}
int cfg_get_redis_port() {
return (unsigned short)cfg_get_integral_value(CFG_DB_REDIS_PORT);
}
const char *cfg_get_redis_passwd() {
return cfg_get_string_value(CFG_DB_REDIS_PASSWD);
}
#endif
#ifdef USED_MYSQL
const char *cfg_get_mysql_server() {
return cfg_get_string_value(CFG_DB_MYSQL_SERVER);
}
int cfg_get_mysql_port() {
return (unsigned short)cfg_get_integral_value(CFG_DB_MYSQL_PORT);
}
const char *cfg_get_mysql_user() {
return cfg_get_string_value(CFG_DB_MYSQL_USER);
}
const char *cfg_get_mysql_passwd() {
return cfg_get_string_value(CFG_DB_MYSQL_PASSWD);
}
const char *cfg_get_mysql_database() {
return cfg_get_string_value(CFG_DB_MYSQL_DB_NAME);
}
#endif
#ifdef ZEROMQ_ON
int cfg_get_zero_mq_port() {
return (unsigned short)cfg_get_integral_value(CFG_MQ_SVR_PORT);
}
const char *cfg_get_zero_mq_data_path() {
return cfg_get_string_value(CFG_MQ_DATA_PATH);
}
#endif

View File

@ -0,0 +1,154 @@
//
// Created by xajhu on 2021/7/2 0002.
//
#include <string.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include "crypto.h"
#include "zlog_module.h"
#if 0
/**
* Base64 Base64编码字符串使用换行对齐方式
* @param pSrc
* @return
*/
const char *base64_encode(unsigned char *pSrc, unsigned int sLen) {
int enSize = 0;
size_t size;
char *pEncode = NULL;
EVP_ENCODE_CTX *pCtx = EVP_ENCODE_CTX_new();
if (pCtx == NULL || pSrc == NULL || sLen == 0) {
return (NULL);
}
size = ((sLen / 3) * 4) + 4 + (sLen / 64) + sLen % 64;
pEncode = (char *)malloc(size);
memset(pEncode, 0, size);
EVP_EncodeInit(pCtx);
EVP_EncodeUpdate(pCtx, (unsigned char *)pEncode, &enSize, (const unsigned char *)pSrc, (int)strlen(pSrc));
EVP_EncodeFinal(pCtx, (unsigned char *)(pEncode + enSize), &enSize);
// fprintf(stdout, "Src: \n[%s]\n", pSrc);
// fprintf(stdout, "Base64(%d --> %d | %d) Bytes: \n[%s]\n", sLen, size, strlen(pEncode), pEncode);
EVP_ENCODE_CTX_free(pCtx);
return pEncode;
}
/**
* Base64 Base64编码字符串使用换行对齐方式
* @param pBase64
* @return
*/
unsigned char *base64_decode(const char *pBase64) {
int enSize = 0;
size_t size = 0;
unsigned char *pDecode = NULL;
EVP_ENCODE_CTX *pCtx = EVP_ENCODE_CTX_new();
if (pCtx == NULL || pBase64 == NULL || strlen(pBase64) == 0) {
return (NULL);
}
size = strlen(pBase64);
pDecode = (unsigned char *)malloc(size);
memset(pDecode, 0, size);
EVP_DecodeInit(pCtx);
EVP_DecodeUpdate(pCtx, (unsigned char *)pDecode, &enSize, (const unsigned char *)pBase64, (int)strlen(pBase64));
EVP_DecodeFinal(pCtx, (unsigned char *)(pDecode + enSize), &enSize);
// fprintf(stdout, "Decode(%d --> %d) Bytes: \n[%s]\n", size, strlen(pDecode), pDecode);
EVP_ENCODE_CTX_free(pCtx);
return pDecode;
}
#endif
/**
* Base64 Base64编码字符串未使用换行对齐方式
* @param pSrc
* @param sLen
* @return
*/
const char *base64_encode(unsigned char *pSrc, unsigned int sLen) {
int size;
char *pEncode = NULL;
if (pSrc == NULL || sLen <= 0) {
return (NULL);
}
size = (int)(((sLen / 3) * 4) + 4 + (sLen / 64) + sLen % 64);
pEncode = (char *)malloc(size);
memset(pEncode, 0, size);
EVP_EncodeBlock((unsigned char *)pEncode, (const unsigned char *)pSrc, (int)sLen);
// fprintf(stdout, "Src: \n[%s]\n", pSrc);
// fprintf(stdout, "Base64(%d --> %d | %d) Bytes: \n[%s]\n", sLen, size, strlen(pEncode), pEncode);
return pEncode;
}
/**
* Base64 Base64编码字符串未使用换行对齐方式
* @param pBase64
* @param pOutSize
* @return
*/
unsigned char *base64_decode(const char *pBase64, unsigned int *pOutSize) {
#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_ENCODE_CTX ctx;
#else
EVP_ENCODE_CTX *pCtx = EVP_ENCODE_CTX_new();
#endif
int enSize = 0;
int size;
unsigned char *pDecode = NULL;
if (pBase64 == NULL || strlen(pBase64) == 0) {
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
EVP_ENCODE_CTX_free(pCtx);
#endif
return (NULL);
}
size = (int)strlen(pBase64);
pDecode = (unsigned char *)malloc(size);
memset(pDecode, 0, size);
#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_DecodeInit(&ctx);
EVP_DecodeUpdate(&ctx, pDecode, &enSize, (const unsigned char *)pBase64, strlen(pBase64));
#else
EVP_DecodeInit(pCtx);
if (EVP_DecodeUpdate(pCtx, pDecode, &enSize, (const unsigned char *)pBase64, size) == -1) {
LOG_MOD(error, ZLOG_MOD_CRYPTO, "Decode [%s] error\n", pBase64);
free(pDecode);
return NULL;
}
#endif
if (pOutSize) {
*pOutSize = enSize;
}
#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_DecodeFinal(&ctx, pDecode + enSize, &size);
#else
if (EVP_DecodeFinal(pCtx, pDecode, &enSize) == -1) {
LOG_MOD(error, ZLOG_MOD_CRYPTO, "Finish decode [%s] error\n", pBase64);
free(pDecode);
return NULL;
}
EVP_ENCODE_CTX_free(pCtx);
#endif
return pDecode;
}

View File

@ -0,0 +1,177 @@
//
// Created by xajhu on 2021/7/2 0002.
//
#include <string.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include "task_manager.h"
#include "user_errno.h"
#include "crypto.h"
#include "common.h"
static uv_mutex_t *pEvpMutex = NULL;
typedef struct {
CRYPTO_TYPE type;
unsigned char *pInData;
int iInSize;
unsigned char *pOutData;
unsigned char pKey[EVP_MAX_KEY_LENGTH + 1];
on_evp_crypto onEvpEventCb;
} CRYPT_TASK_PARAMS, *PCRYPT_TASK_PARAMS;
static void freeEVPWorkCb(uv_work_t *pWork, int UNUSED(status)) {
PCRYPT_TASK_PARAMS pTask = (PCRYPT_TASK_PARAMS)pWork->data;
free(pTask->pInData);
free(pTask);
free(pWork);
}
static void onEVPWorkCb(uv_work_t *pWork) {
PCRYPT_TASK_PARAMS pTask = (PCRYPT_TASK_PARAMS)pWork->data;
unsigned int uOutSize = 0;
int iError = 0;
switch (pTask->type) {
#if 0
case CRYPTO_AES_ENCRYPT:
iError = EvpAESEncrypto(pTask->pInData,
pTask->iInSize,
pTask->pOutData,
&uOutSize,
pTask->pKey);
break;
case CRYPTO_AES_DECRYPT:
iError = EvpAESDecrypto(pTask->pInData,
pTask->iInSize,
pTask->pOutData,
&uOutSize,
pTask->pKey);
break;
#endif
case CRYPTO_BASE64_ENCODE:
pTask->pOutData = (unsigned char *)base64_encode((unsigned char *)pTask->pInData, pTask->iInSize);
uOutSize = strlen((char *)pTask->pOutData);
break;
case CRYPTO_BASE64_DECODE:
pTask->pOutData = (unsigned char *)base64_decode((const char *)pTask->pInData, &uOutSize);
//uOutSize = strlen((char *)pTask->pOutData);
break;
#if 0
case CRYPTO_MD5_FILE:
pTask->pOutData = (unsigned char *)EvpMD5HashFile((const char *)pTask->pInData);
uOutSize = strlen((char *)pTask->pOutData);
break;
#endif
default:
iError = -ERR_UNSUP_EVP_TYPE;
}
if (iError != 0) {
pTask->onEvpEventCb(pTask->type, pTask->pOutData, 0, pTask->pInData, iError);
} else {
pTask->onEvpEventCb(pTask->type, pTask->pOutData, uOutSize, pTask->pInData, 0);
}
}
int evp_add_crypto_task(CRYPTO_TYPE type,
unsigned char *pInBuf,
unsigned int iSize,
unsigned char *pOutBuf,
char *pKey,
on_evp_crypto onEvpCryptCb) {
uv_work_t *puvWork = NULL;
PCRYPT_TASK_PARAMS pTask = NULL;
if (!onEvpCryptCb) {
return -ERR_INPUT_PARAMS;
}
if (type == CRYPTO_AES_ENCRYPT || type == CRYPTO_AES_DECRYPT) {
if (pKey == NULL || pOutBuf == NULL) {
return -ERR_INPUT_PARAMS;
}
switch (strlen(pKey) * 8) {
case 128:
case 192:
case 256:
break;
default:
return -ERR_EVP_KEY_SIZE;
}
} else if (type == CRYPTO_MD5_FILE) {
uv_fs_t uvFs;
if (uv_fs_access(get_task_manager(), &uvFs, (const char *)pInBuf, F_OK, NULL) != 0) {
return -ERR_FILE_NOT_EXISTS;
}
}
pTask = (PCRYPT_TASK_PARAMS)malloc(sizeof(CRYPT_TASK_PARAMS));
puvWork = (uv_work_t *)malloc(sizeof(uv_work_t));
puvWork->data = (void *)pTask;
pTask->type = type;
pTask->pInData = (unsigned char *)malloc(iSize + 1);
pTask->iInSize = (int)iSize;
pTask->pOutData = pOutBuf;
pTask->onEvpEventCb = onEvpCryptCb;
memset(pTask->pInData, 0, iSize + 1);
memset(pTask->pKey, 0, EVP_MAX_KEY_LENGTH + 1);
if (pKey) {
strncpy((char *)pTask->pKey, pKey, EVP_MAX_KEY_LENGTH);
}
memcpy(pTask->pInData, pInBuf, iSize);
uv_queue_work(get_task_manager(), puvWork, onEVPWorkCb, freeEVPWorkCb);
return 0;
}
static void evpLockCb(int mode, int n, const char *UNUSED(pFile), int UNUSED(line)) {
if (n >= CRYPTO_num_locks()) {
return;
}
if (mode & CRYPTO_LOCK) {
uv_mutex_lock(&pEvpMutex[n]);
} else {
uv_mutex_unlock(&pEvpMutex[n]);
}
}
#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0
void evpIdCb(CRYPTO_THREADID *tid) {
CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self());
}
#else
static unsigned long evpIdCb(void) {
return ((unsigned long)uv_thread_self());
}
#endif
void evp_system_init(void) {
int i;
pEvpMutex = (uv_mutex_t *)malloc(CRYPTO_num_locks() * sizeof(uv_mutex_t));
for (i = 0; i < CRYPTO_num_locks(); i++) {
uv_mutex_init(&pEvpMutex[i]);
}
#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0
CRYPTO_THREADID_set_callback(evpIdCb);
#else
CRYPTO_set_id_callback(evpIdCb);
#endif
CRYPTO_set_locking_callback(evpLockCb);
}

View File

@ -0,0 +1,143 @@
//
// Created by xajhu on 2021/7/2 0002.
//
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include "crypto.h"
#include "misc.h"
#include "user_errno.h"
#include "zlog_module.h"
/**
* MD5值
* @param pFileName
* @param md5
* @return
*/
int hash_digest_file(HASH_TYPE hashType, const char *pFileName, char **pHashValue) {
unsigned int rdSize = 0;
int fd;
uint8_t hashValue[EVP_MAX_MD_SIZE];
uint8_t buf[1024];
EVP_MD_CTX *pCtx;
if (pHashValue == NULL) {
return (-ERR_INPUT_PARAMS);
}
memset(hashValue, 0, EVP_MAX_MD_SIZE);
pCtx = EVP_MD_CTX_create();
if (!pCtx) {
return -ERR_EVP_CREATE_CTX;
}
EVP_MD_CTX_init(pCtx);
switch (hashType) {
case HASH_TYPE_MD5:
EVP_DigestInit_ex(pCtx, EVP_md5(), NULL);
break;
case HASH_TYPE_SHA1:
EVP_DigestInit_ex(pCtx, EVP_sha1(), NULL);
break;
case HASH_TYPE_SHA256:
EVP_DigestInit_ex(pCtx, EVP_sha256(), NULL);
break;
default:
EVP_MD_CTX_destroy(pCtx);
return (-ERR_INPUT_PARAMS);
}
fd = open(pFileName, O_RDONLY);
if (fd == -1) {
LOG_MOD(error, ZLOG_MOD_CRYPTO, "Open File %s error\n", pFileName);
EVP_MD_CTX_destroy(pCtx);
return (-ERR_OPEN_FILE);
}
do {
rdSize = read(fd, buf, 1024);
EVP_DigestUpdate(pCtx, buf, rdSize);
} while (rdSize > 0);
close(fd);
EVP_DigestFinal_ex(pCtx, hashValue, &rdSize);
EVP_MD_CTX_destroy(pCtx);
*pHashValue = (char *)malloc(EVP_MAX_MD_SIZE * 2 + 1);
if (*pHashValue == NULL) {
return (-ERR_MALLOC_MEMORY);
}
memset(*pHashValue, 0, EVP_MAX_MD_SIZE * 2 + 1);
bin2hex(*pHashValue, hashValue, rdSize);
return ERR_SUCCESS;
}
/**
* Hash
* @param pBuf
* @param iBufLen
* @param pHashValue
* @return
*/
int hash_digest_mem(HASH_TYPE hashType,
const unsigned char *pBuf,
unsigned int iBufLen,
unsigned char **pHashValue,
unsigned int *pOutSize) {
EVP_MD_CTX *pCtx;
if (pHashValue == NULL || pBuf == NULL || pOutSize == NULL) {
return (-ERR_INPUT_PARAMS);
}
*pHashValue = (unsigned char *)malloc(EVP_MAX_MD_SIZE);
if (*pHashValue == NULL) {
*pOutSize = 0;
return -ERR_MALLOC_MEMORY;
}
memset(*pHashValue, 0, EVP_MAX_MD_SIZE);
pCtx = EVP_MD_CTX_create();
if (!pCtx) {
*pOutSize = 0;
return -ERR_EVP_CREATE_CTX;
}
EVP_MD_CTX_init(pCtx);
switch (hashType) {
case HASH_TYPE_MD5:
EVP_DigestInit_ex(pCtx, EVP_md5(), NULL);
break;
case HASH_TYPE_SHA1:
EVP_DigestInit_ex(pCtx, EVP_sha1(), NULL);
break;
case HASH_TYPE_SHA256:
EVP_DigestInit_ex(pCtx, EVP_sha256(), NULL);
break;
default:
EVP_MD_CTX_destroy(pCtx);
return (-ERR_INPUT_PARAMS);
}
EVP_DigestUpdate(pCtx, pBuf, iBufLen);
EVP_DigestFinal_ex(pCtx, *pHashValue, pOutSize);
EVP_MD_CTX_destroy(pCtx);
return ERR_SUCCESS;
}

View File

@ -0,0 +1,259 @@
//
// Created by xajhu on 2021/7/13 0013.
//
#include <string.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include "crypto.h"
#include "user_errno.h"
static int sha1prng_for_aes_key(const char *pKey, unsigned char *pShaPrng16) {
unsigned int outSize = EVP_MAX_MD_SIZE;
unsigned char data[SHA_DIGEST_LENGTH] = {0};
unsigned char *pHashValue = NULL;
int ret = hash_digest_mem(HASH_TYPE_SHA1, (const unsigned char *)pKey, strlen(pKey), &pHashValue, &outSize);
if (ret != ERR_SUCCESS) {
if (pHashValue) {
free(pHashValue);
}
return ret;
}
memcpy(data, pHashValue, SHA_DIGEST_LENGTH);
free(pHashValue);
ret = hash_digest_mem(HASH_TYPE_SHA1, data, SHA_DIGEST_LENGTH, &pHashValue, &outSize);
if (ret != ERR_SUCCESS) {
if (pHashValue) {
free(pHashValue);
}
return ret;
}
memcpy(pShaPrng16, pHashValue, 16);
free(pHashValue);
return ERR_SUCCESS;
}
#define EVP_ENV_INIT(algorithmType, pCipher, keyBuf, pKey) \
do { \
switch (algorithmType) { \
case DES3_ECB_PKCS7PADDING: \
pCipher = EVP_des_ede3(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case DES3_CBC_PKCS7PADDING: \
pCipher = EVP_des_ede3_cbc(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case DES3_OFB_PKCS7PADDING: \
pCipher = EVP_des_ede3_ofb(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case AES128_ECB_PKCS7PADDING: \
pCipher = EVP_aes_128_ecb(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case AES128_ECB_PKCS7PADDING_SHA1PRNG: \
if (sha1prng_for_aes_key(pKey, keyBuf) != ERR_SUCCESS) { \
EVP_CIPHER_CTX_cleanup(pCtx); \
return -ERR_AES_KEYGEN; \
} \
pCipher = EVP_aes_128_ecb(); \
break; \
case AES128_CBC_PKCS7PADDING: \
pCipher = EVP_aes_128_cbc(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case AES128_OFB_PKCS7PADDING: \
pCipher = EVP_aes_128_ofb(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case AES192_ECB_PKCS7PADDING: \
pCipher = EVP_aes_192_ecb(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case AES192_CBC_PKCS7PADDING: \
pCipher = EVP_aes_192_cbc(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case AES192_OFB_PKCS7PADDING: \
pCipher = EVP_aes_192_ofb(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case AES256_ECB_PKCS7PADDING: \
pCipher = EVP_aes_256_ecb(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case AES256_CBC_PKCS7PADDING: \
pCipher = EVP_aes_256_cbc(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
case AES256_OFB_PKCS7PADDING: \
pCipher = EVP_aes_256_ofb(); \
strncpy((char *)keyBuf, pKey, EVP_CIPHER_key_length(pCipher)); \
break; \
default: \
EVP_CIPHER_CTX_cleanup(pCtx); \
return -ERR_UNSUP_EVP_TYPE; \
} \
} while (0)
int symmetric_decrypto(AES_TYPE algorithmType,
unsigned char *pInBuf,
unsigned int inSize,
unsigned char **pOutBuf,
int *pOutSize,
const char *pKey) {
int enBytes = 0;
EVP_CIPHER_CTX *pCtx;
unsigned char *pAesBuf;
unsigned char keyBuf[EVP_MAX_KEY_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
const EVP_CIPHER *pCipher;
if (!pInBuf || !pOutSize || !pKey || inSize == 0) {
return -ERR_INPUT_PARAMS;
}
*pOutSize = 0;
pCtx = EVP_CIPHER_CTX_new();
if (!pCtx) {
return -ERR_EVP_CREATE_CTX;
}
memset(keyBuf, 0, EVP_MAX_KEY_LENGTH);
memset(iv, '0', EVP_MAX_IV_LENGTH);
EVP_ENV_INIT(algorithmType, pCipher, keyBuf, pKey);
EVP_CIPHER_CTX_init(pCtx);
if (EVP_DecryptInit_ex(pCtx, pCipher, NULL, (const unsigned char *)keyBuf, iv) == 0) {
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return -ERR_EVP_INIT_KEY;
}
pAesBuf = malloc(inSize + EVP_MAX_BLOCK_LENGTH);
if (pAesBuf == NULL) {
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return -ERR_MALLOC_MEMORY;
}
memset(pAesBuf, 0, inSize + EVP_MAX_BLOCK_LENGTH);
if (EVP_DecryptUpdate(pCtx, pAesBuf, &enBytes, pInBuf, (int)inSize) == 0) {
free(pAesBuf);
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return -ERR_EVP_UPDATE;
}
*pOutBuf = pAesBuf;
pAesBuf += enBytes;
*pOutSize += enBytes;
if (EVP_DecryptFinal_ex(pCtx, pAesBuf, &enBytes) == 0) {
//free(pOutBuf); // Maybe exception
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return -ERR_EVP_FINALE;
}
*pOutSize += enBytes;
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return ERR_SUCCESS;
}
int symmetric_encrypto(AES_TYPE algorithmType,
unsigned char *pInBuf,
unsigned int inSize,
unsigned char **pOutBuf,
int *pOutSize,
const char *pKey) {
int enBytes = 0;
unsigned char *pAesBuf;
EVP_CIPHER_CTX *pCtx;
unsigned char keyBuf[EVP_MAX_KEY_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
const EVP_CIPHER *pCipher;
if (!pInBuf || !pOutSize || !pKey || inSize == 0) {
return -ERR_INPUT_PARAMS;
}
*pOutSize = 0;
pCtx = EVP_CIPHER_CTX_new();
if (!pCtx) {
return -ERR_EVP_CREATE_CTX;
}
memset(keyBuf, 0, EVP_MAX_KEY_LENGTH);
memset(iv, '0', EVP_MAX_IV_LENGTH);
EVP_ENV_INIT(algorithmType, pCipher, keyBuf, pKey);
EVP_CIPHER_CTX_init(pCtx);
if (EVP_EncryptInit_ex(pCtx, pCipher, NULL, (const unsigned char *)keyBuf, iv) == 0) {
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return -ERR_EVP_INIT_KEY;
}
pAesBuf = malloc(inSize + EVP_MAX_BLOCK_LENGTH);
if (pAesBuf == NULL) {
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return -ERR_MALLOC_MEMORY;
}
memset(pAesBuf, 0, inSize + EVP_MAX_BLOCK_LENGTH);
if (EVP_EncryptUpdate(pCtx, pAesBuf, &enBytes, pInBuf, (int)inSize) == 0) {
free(pAesBuf);
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return -ERR_EVP_UPDATE;
}
*pOutBuf = pAesBuf;
pAesBuf += enBytes;
*pOutSize += enBytes;
if (EVP_EncryptFinal_ex(pCtx, pAesBuf, &enBytes) == 0) {
//free(pOutBuf); // Maybe exception
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return -ERR_EVP_FINALE;
}
*pOutSize += enBytes;
EVP_CIPHER_CTX_cleanup(pCtx);
EVP_CIPHER_CTX_free(pCtx);
return ERR_SUCCESS;
}

View File

@ -0,0 +1,91 @@
//
// Created by xajhuang on 2023/3/29.
//
#ifdef SQLITE_ON
#include <sqlite3.h>
#include <string.h>
#include "zlog_module.h"
#include "user_errno.h"
#include "config.h"
#include "database.h"
#include "common.h"
static sqlite3 *g_pSqlHandle = NULL;
int db_sqlite3_init() {
int rc;
const char *pDbPath = cfg_get_sqlite_db_name();
if (pDbPath == NULL || strlen(pDbPath) == 0) {
return ERR_SUCCESS;
}
if (g_pSqlHandle == NULL) {
rc = sqlite3_open_v2(pDbPath, &g_pSqlHandle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
if (rc != SQLITE_OK) {
LOG_MOD(error,
ZLOG_MOD_DB,
"Create SQLite3 Database at %s error: %s(%d)\n",
pDbPath,
sqlite3_errstr(rc),
rc);
return -ERR_DB_CONNECT;
}
}
LOG_MOD(info, ZLOG_MOD_DB, "Used SQLite3 database: %s\n", pDbPath);
return ERR_SUCCESS;
}
int db_sqlite3_get_rows(const char *pSqlCmd, char ***dbResult, int *pnRow, int *pnColumn, char **pErr) {
if (pSqlCmd == NULL || strlen(pSqlCmd) == 0) {
LOG_MOD(error, ZLOG_MOD_DB, "Input params pSqlCmd error\n");
return -ERR_INPUT_PARAMS;
}
if (g_pSqlHandle) {
int rc = sqlite3_get_table(g_pSqlHandle, pSqlCmd, dbResult, pnRow, pnColumn, pErr);
if (rc != SQLITE_OK) {
LOG_MOD(error, ZLOG_MOD_DB, "Run {%s} SQL command error:\n%s\n", pSqlCmd, sqlite3_errmsg(g_pSqlHandle));
return -ERR_DB_SQL_EXEC;
}
return ERR_SUCCESS;
} else {
LOG_MOD(error, ZLOG_MOD_DB, "SQlite3 database uninit\n");
return -ERR_DB_UNINIT;
}
}
int db_sqlite3_sql_exec(const char *pSqlCmd, void *pCallback, void *pData, char **pErr) {
if (pSqlCmd == NULL || strlen(pSqlCmd) == 0) {
LOG_MOD(error, ZLOG_MOD_DB, "Input params pSqlCmd error\n");
return -ERR_INPUT_PARAMS;
}
if (g_pSqlHandle) {
int rc = sqlite3_exec(g_pSqlHandle, pSqlCmd, pCallback, pData, pErr);
if (rc != SQLITE_OK) {
LOG_MOD(error, ZLOG_MOD_DB, "Run {%s} SQL command error:\n%s\n", pSqlCmd, sqlite3_errmsg(g_pSqlHandle));
return -ERR_DB_SQL_EXEC;
}
return ERR_SUCCESS;
} else {
LOG_MOD(error, ZLOG_MOD_DB, "SQlite3 database uninit\n");
return -ERR_DB_UNINIT;
}
}
void db_sqlite3_uninit() {
if (g_pSqlHandle) {
DEBUG_CODE_LINE();
sqlite3_close(g_pSqlHandle);
}
}
#endif

View File

@ -0,0 +1,151 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `fdatasync' function. */
#define HAVE_FDATASYNC 1
/* Define to 1 if you have the `gmtime_r' function. */
#define HAVE_GMTIME_R 1
/* Define to 1 if the system has the type `int16_t'. */
#define HAVE_INT16_T 1
/* Define to 1 if the system has the type `int32_t'. */
#define HAVE_INT32_T 1
/* Define to 1 if the system has the type `int64_t'. */
#define HAVE_INT64_T 1
/* Define to 1 if the system has the type `int8_t'. */
#define HAVE_INT8_T 1
/* Define to 1 if the system has the type `intptr_t'. */
#define HAVE_INTPTR_T 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `isnan' function. */
#define HAVE_ISNAN 1
/* Define to 1 if you have the `crypto_cipher' library (-lcrypto). */
#define HAVE_LIBCRYPTO 1
/* Define to 1 if you have the `nss3' library (-lnss3). */
/* #undef HAVE_LIBNSS3 */
/* Define to 1 if you have the `tomcrypt' library (-ltomcrypt). */
/* #undef HAVE_LIBTOMCRYPT */
/* Define to 1 if you have the `localtime_r' function. */
#define HAVE_LOCALTIME_R 1
/* Define to 1 if you have the `localtime_s' function. */
/* #undef HAVE_LOCALTIME_S */
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the `malloc_usable_size' function. */
#define HAVE_MALLOC_USABLE_SIZE 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `pread' function. */
#define HAVE_PREAD 1
/* Define to 1 if you have the `pread64' function. */
#define HAVE_PREAD64 1
/* Define to 1 if you have the `pwrite' function. */
#define HAVE_PWRITE 1
/* Define to 1 if you have the `pwrite64' function. */
#define HAVE_PWRITE64 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strchrnul' function. */
#define HAVE_STRCHRNUL 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if the system has the type `uint16_t'. */
#define HAVE_UINT16_T 1
/* Define to 1 if the system has the type `uint32_t'. */
#define HAVE_UINT32_T 1
/* Define to 1 if the system has the type `uint64_t'. */
#define HAVE_UINT64_T 1
/* Define to 1 if the system has the type `uint8_t'. */
#define HAVE_UINT8_T 1
/* Define to 1 if the system has the type `uintptr_t'. */
#define HAVE_UINTPTR_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `usleep' function. */
#define HAVE_USLEEP 1
/* Define to 1 if you have the `utime' function. */
#define HAVE_UTIME 1
/* Define to 1 if you have the <zlib.h> header file. */
#define HAVE_ZLIB_H 1
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME "sqlcipher"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "sqlcipher 3.39.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "sqlcipher"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.39.2"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
#define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,130 @@
# json-c d'accord library (libjsoncdac)
jsonc-daccord is a lightweight JSON Schema validation library written in C, and is taking advantage of the libjson-c library.
## Design Goals
The goal is to have a lightweight JSON Schema validation implementation in C using json-c. json-c is popular in OpenWRT communities. Initially I just wanted it to support a small subset of JSON Schema to suit a need to validate simple json files. See the minimum build supports below. However to suit a broader audience, supporting more JSON Schema is important.
Currently the footprint of libjsoncdac.so is 8KB. The keep the footprint from bloating out, new features should be selectable using CMake options.
Minimal build supports:
- all: type, enum, required, properties, const.
- objects:
- strings: minLength, maxLength.
- integers and doubles: minimum, maximum.
- arrays: minItems, maxItems, uniqeItems, items.
## Example Use
Public headers:
See [jsoncdaccord.h](include/jsoncdaccord.h)
```C
int jdac_validate_file(const char *jsonfile, const char *jsonschemafile);
int jdac_validate(json_object *jobj, json_object *jschema);
int jdac_ref_set_localpath(const char *_localpath);
const char* jdac_errorstr(unsigned int jdac_errors);
```
Link your binary to: `-ljsoncdac -ljson-c`
Use the #include header: `#include <jsoncdaccord.h>`
Example C code:
```C
#include <stdio.h>
#include <json-c/json.h>
#include <jsoncdaccord.h>
int main(int argc, char *argv[])
{
char *json_file = "test.json";
char *schema_file = "schema.json";
// optional: load referenced schema files from filesystem
char *localpath = "/my/path/to_json_files/";
jdac_ref_set_localpath(localpath);
printf("validating %s with %s\n", json_file, schema_file);
int err = jdac_validate_file(json_file, schema_file);
if (err==JDAC_ERR_VALID) {
printf("validation ok\n");
} else {
printf("validate failed %d: %s\n", err, jdac_errorstr(err));
}
return err;
}
```
See [jdac-cli.c](libjsoncdac/jdac-cli.c) as well.
## Install
Building from source:
Install json-c and libcmocka-dev (used in the debug builds).
- Release version:
```
git clone --branch libjsoncdac-0.2 https://github.com/domoslabs/jsonc-daccord &&\
cd jsonc-daccord && mkdir build && cd build &&\
cmake .. -DCMAKE_BUILD_TYPE=Release && make && sudo make install
```
- Debug version:
```
git clone --branch libjsoncdac-0.2 https://github.com/domoslabs/jsonc-daccord &&\
cd jsonc-daccord && mkdir build && cd build &&\
cmake .. -DCMAKE_BUILD_TYPE=Debug && make && sudo make install
```
Note: After install you might need to run `sudo ldconfig`.
## CMake Options
build options:
| option | description |
| :------------------------- | :------------------------------------------------------- |
| CMAKE_BUILD_TYPE | Build as Release or Debug. Default: Release. |
| RUN_TEST_SUITE | Run JSON Schema test suite (CMAKE_BUILD_TYPE=Debug Only) |
| BUILD_PATTERN | Support *pattern*. |
| BUILD_PATTERNPROPERTIES | Support *patternProperties* |
| BUILD_ADDITIONALPROPERTIES | Support *additionalProperties* |
| BUILD_PROPERTYNAMES | Support *propertyNames* |
| BUILD_SUBSCHEMALOGIC | Support *allOf*, *anyOf*, *oneOf*, *not*, *if-then-else* |
| BUILD_CONTAINS | Support *contains*, *minContains*, and *maxContains* |
| BUILD_DOWNLOAD | Support downloading referenced schema files |
| BUILD_STORE | Support build a list of schema uri, id, and anchors |
| BUILD_REF | Support *$ref* keyword. load schemas by file. |
Note: All BUILD_* options are selected by default
## Run tests
For debug builds:
```
ctest
ctest -V # to see output of tests
```
Running test suites are currently optional, and are select with `RUN_TEST_SUITE=ON` in the cmake options.
## Command Line Interface
You can try the library with the jdac-cli command.
```/tmp/domos/domosqos-sta_statistics_json
jdac-cli -h
```
## To do
- prevent infinite recursion
## Related links
- https://json-schema.org/specification.html
- https://github.com/json-schema-org/JSON-Schema-Test-Suite
- https://github.com/json-c/json-c

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
{
"botenanna": "botenannna",
"boten": "boten",
"wuhu": "wublah",
"nullobject": null
}

View File

@ -0,0 +1,7 @@
{
"empty": {},
"botenanna": {
"annaaaa": "boten"
},
"nonobject": null
}

View File

@ -0,0 +1,35 @@
{
"test-int": {
"id": 123
},
"test-double": {
"id": 1.23
},
"test-string": {
"id": "1234"
},
"test-boolean": {
"id": true
},
"test-array": [
123,
"1234"
],
"test-array2": [
123,
{}
],
"test-array": {
"anna": [
{
"id": 1
},
{
"id": 2
},
{
"id": 3
}
]
}
}

View File

@ -0,0 +1,10 @@
{
"teststring1": "one",
"teststring2": "two",
"teststring3": "three",
"teststring4": "four",
"testinteger1": 1,
"testinteger2": 2,
"testinteger3": 3,
"testinteger4": 4
}

View File

@ -0,0 +1,53 @@
{
"test1": {
"flowarray": [
{
"key1": 5,
"key2": "hanz"
}
]
},
"wrongtype": {
"flowarray": [
{
"key1": "5",
"key2": "hanz"
}
]
},
"missingkey": {
"flowarray": [
{
"key2": "hanz"
}
]
},
"nestedarray": {
"flowarray": [
{
"key1": "hanz",
"key2": [
1,
2,
3,
4,
5
]
}
]
},
"nestedarrayofstrings": {
"flowarray": [
{
"key1": "hanz",
"key2": [
"1",
"2",
"3",
"4",
"5"
]
}
]
}
}

View File

@ -0,0 +1,7 @@
{
"array-1": [1],
"array-2": [1,2],
"array-3": [1,2,3],
"array-4": [1,2,3,4],
"array-5": [1,2,3,4,5]
}

View File

@ -0,0 +1,57 @@
{
"emptyobject": {},
"testjson": {
"computer": "banana",
"phone": 12345678,
"switch": true
},
"testjsontrue": {
"computer": "banana",
"phone": 12345678,
"switch": true,
"object": {"object":123},
"list": [1,2,3]
},
"testjsonfalse": {
"computer": 12345678,
"phone": "banana",
"switch": [1,2,3],
"object": true,
"list": {"object":123}
},
"testjsonstring-all": {
"computer1": "hansihansi",
"computer2": "hans",
"computer3": "ha",
"computer4": "han"
},
"testjsonstring-all-fail": {
"computer1": "hansihansi",
"computer2": "hansi",
"computer3": "han",
"computer4": "hans"
},
"testjsonstring2": {
"computer4": "ha"
},
"testjsonstring3": {
"computer4": "han"
},
"testjsonstring4": {
"computer4": "hans"
},
"testjsonstring5": {
"computer4": "hansp"
}
}

View File

@ -0,0 +1,36 @@
{
"alltrue": {
"person": {
"name": "Anna",
"husbands": 1
}
},
"nametooshort": {
"person": {
"name": "Ann",
"husbands": 1
}
},
"wrongtype": {
"person": {
"name": "Anna",
"husbands": "1"
}
},
"husbandmissing": {
"person": {
"name": "Anna"
}
},
"namemissing": {
"person": {
}
},
"empty": {
}
}

View File

@ -0,0 +1,11 @@
{
"test-emptyjson": {},
"test-keywords-abc": {"a":"a", "b":"b", "c":"c"},
"test-keywords-bc": {"b":"b", "c":"c"},
"test-keywords-ac": {"a":"a", "c":"c"},
"test-keywords-ab": {"a":"a", "b":"b"},
"test-keywords-a": {"a":"a"},
"test-keywords-b": {"b":"b"},
"test-keywords-c": {"c":"c"},
"test-wrongtype": 123
}

View File

@ -0,0 +1,8 @@
{
"test-object" : {"1":"2"},
"test-array" : [1,2,3],
"test-string" : "101",
"test-integer" : 101,
"test-double" : 101.1,
"test-boolean" : true
}

View File

@ -0,0 +1,10 @@
{
"array-empty": [],
"array-unique1": [1,2,3,4,5,6],
"array-unique2": ["one","two","three"],
"array-notunique1": [1,2,3,3,5,6],
"array-notunique2": [1,2,3,4,5,5],
"array-notunique3": [1,1,3,4,5,6],
"array-notunique4": [1,1,1,4,5,6],
"array-notunique5": ["one", "two", "two"]
}

View File

@ -0,0 +1,106 @@
{
"truejson":
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [ [444,445] ],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [0,1],
"proto": "tcp",
"confidence": 10,
"vector": [1,2,3,4,5,6,7,8,9]
}
]
}
]
},
"validport_toohigh":
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [ [444,445], [50000,100000] ],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [0,1],
"proto": "tcp",
"confidence": 10,
"vector": [1,2,3,4,5,6,7,8,9]
}
]
}
]
},
"ignore_indices_index_too_high":
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [ [444,445] ],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [0,20],
"proto": "tcp",
"confidence": 10,
"vector": [1,2,3,4,5,6,7,8,9]
}
]
}
]
},
"too_many_vector_elements":
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [ [444,445] ],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [0,1],
"proto": "tcp",
"confidence": 10,
"vector": [0,1,2,3,4,5,6,7,8,9,10]
}
]
}
]
}
}

View File

@ -0,0 +1,760 @@
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"ValidPorts": [
[
444,
444
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [
0,
1
],
"proto": "tcp",
"confidence": 10,
"vector": [
0,
0
]
}
]
},
{
"Service": "steamworks",
"NetifyName": "gaming.steamworks",
"ValidPorts": [
[
4380,
4380
],
[
27000,
27100
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 20,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
1300,
-214
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
1300,
1300
]
}
]
},
{
"Service": "leagueoflegends",
"NetifyName": "gaming.leagueoflegends",
"ValidPorts": [
[
5000,
5500
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
515,
-107
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
515,
515
]
}
]
},
{
"Service": "apex",
"NetifyName": "gaming.apex",
"ValidPorts": [
[
1024,
1124
],
[
18000,
18000
],
[
29900,
29900
],
[
37000,
40000
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
50,
-58
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
50,
50
]
}
]
},
{
"Service": "rainbow6",
"NetifyName": "gaming.rainbow6",
"ValidPorts": [
[
3074,
3074
],
[
4380,
4380
],
[
6015,
6015
],
[
10000,
10099
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
139,
139
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
139,
-131
]
}
]
},
{
"Service": "iperf3",
"NetifyName": "domos.iperf3",
"ValidPorts": [
[
5201,
5201
]
],
"vectors": [
{
"ID": "v2",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
4,
-4
]
}
]
},
{
"Service": "flent",
"NetifyName": "domos.flent",
"ValidPorts": [
[
2116,
2116
]
],
"vectors": [
{
"ID": "v2",
"ignore_indices": [],
"CT": 0,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
4,
-4
]
}
]
},
{
"Service": "unrealengine4",
"NetifyName": "gaming.unrealengine4",
"ValidPorts": [
[
12000,
65535
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
29,
-29
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
29,
29
]
}
]
},
{
"Service": "overwatch",
"NetifyName": "gaming.overwatch",
"ValidPorts": [
[
26400,
27000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
34,
-34
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
34,
34
]
}
]
},
{
"Service": "valorant",
"NetifyName": "gaming.valorant",
"ValidPorts": [
[
7000,
7500
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
53,
-33
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
53,
53
]
}
]
},
{
"Service": "seaofthieves",
"NetifyName": "gaming.seaofthieves",
"ValidPorts": [
[
30000,
32000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
51,
-88
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
51,
51
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
272,
60
]
}
]
},
{
"Service": "rust",
"NetifyName": "gaming.rust",
"ValidPorts": [
[
28015,
28015
],
[
28225,
28225
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
1372,
-28
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
1372,
1372
]
}
]
},
{
"Service": "minecraft",
"NetifyName": "gaming.minecraft",
"ValidPorts": [
[
19132,
19133
],
[
19000,
20000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
33,
1464
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
33,
33
]
}
]
},
{
"Service": "gta5",
"NetifyName": "gaming.gta5",
"ValidPorts": [
[
6672,
6672
],
[
61455,
61458
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
221,
0
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
221,
-221
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
237,
0
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
205,
0
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
141,
205
]
}
]
},
{
"Service": "starcraft2",
"NetifyName": "gaming.starcraft2",
"ValidPorts": [
[
3724,
3724
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
20,
-20
]
},
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
20,
20
]
}
]
},
{
"Service": "video-conferencing",
"NetifyName": "video-conferencing.video-conf",
"ValidPorts": [
[
3478,
3478
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 4,
"vector": []
}
]
},
{
"Service": "slack",
"NetifyName": "video-conferencing.slack",
"ValidPorts": [
[
22466,
22466
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "webex",
"NetifyName": "video-conferencing.webex",
"ValidPorts": [
[
9000,
9000
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "meet",
"NetifyName": "video-conferencing.meet",
"ValidPorts": [
[
19302,
19309
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "zoom",
"NetifyName": "video-conferencing.zoom",
"ValidPorts": [
[
3478,
3479
],
[
8801,
8802
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "bluejeans",
"NetifyName": "video-conferencing.bluejeans",
"ValidPorts": [
[
5000,
5000
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "teams/skype",
"NetifyName": "video-conferencing.teams/skype",
"ValidPorts": [
[
3478,
3481
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
}
]
}

View File

@ -0,0 +1,769 @@
{
"ID": "lcss_vectors",
"Version": "v01",
"Services": [
{
"Service": "slitherio",
"NetifyName": "gaming.slitherio",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
444,
444
]
],
"vectors": [
{
"ID": "v0",
"TT": 0,
"ignore_indices": [
0,
1
],
"proto": "tcp",
"confidence": 10,
"vector": [
0,
0
]
}
]
},
{
"Service": "steamworks",
"NetifyName": "gaming.steamworks",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
4380,
4380
],
[
27000,
27100
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 20,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
1300,
-214
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
1300,
1300
]
}
]
},
{
"Service": "leagueoflegends",
"NetifyName": "gaming.leagueoflegends",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
5000,
5500
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
515,
-107
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
515,
515
]
}
]
},
{
"Service": "apex",
"NetifyName": "gaming.apex",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
1024,
1124
],
[
18000,
18000
],
[
29900,
29900
],
[
37000,
40000
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
50,
-58
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
50,
50
]
}
]
},
{
"Service": "rainbow6",
"NetifyName": "gaming.rainbow6",
"max_diff": 1,
"max_length": 10,
"ValidPorts": [
[
3074,
3074
],
[
4380,
4380
],
[
6015,
6015
],
[
10000,
10099
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
139,
139
]
},
{
"ID": "v1",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
139,
-131
]
}
]
},
{
"Service": "iperf3",
"NetifyName": "domos.iperf3",
"ValidPorts": [
[
5201,
5201
]
],
"vectors": [
{
"ID": "v2",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
4,
-4
]
}
]
},
{
"Service": "flent",
"NetifyName": "domos.flent",
"ValidPorts": [
[
2116,
2116
]
],
"vectors": [
{
"ID": "v2",
"ignore_indices": [],
"CT": 0,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
4,
-4
]
}
]
},
{
"Service": "unrealengine4",
"NetifyName": "gaming.unrealengine4",
"ValidPorts": [
[
12000,
65535
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
29,
-29
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
29,
29
]
}
]
},
{
"Service": "overwatch",
"NetifyName": "gaming.overwatch",
"ValidPorts": [
[
26400,
27000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
34,
-34
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
34,
34
]
}
]
},
{
"Service": "valorant",
"NetifyName": "gaming.valorant",
"ValidPorts": [
[
7000,
7500
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
53,
-33
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
53,
53
]
}
]
},
{
"Service": "seaofthieves",
"NetifyName": "gaming.seaofthieves",
"ValidPorts": [
[
30000,
32000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
51,
-88
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
51,
51
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
272,
60
]
}
]
},
{
"Service": "rust",
"NetifyName": "gaming.rust",
"ValidPorts": [
[
28015,
28015
],
[
28225,
28225
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
1372,
-28
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
1372,
1372
]
}
]
},
{
"Service": "minecraft",
"NetifyName": "gaming.minecraft",
"ValidPorts": [
[
19132,
19133
],
[
19000,
20000
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
33,
1464
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
33,
33
]
}
]
},
{
"Service": "gta5",
"NetifyName": "gaming.gta5",
"ValidPorts": [
[
6672,
6672
],
[
61455,
61458
]
],
"vectors": [
{
"ID": "v0",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
221,
0
]
},
{
"ID": "v1",
"ignore_indices": [],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
221,
-221
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
237,
0
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
205,
0
]
},
{
"ID": "v3",
"ignore_indices": [
1
],
"CT": 2,
"TT": 0,
"proto": "udp",
"confidence": 10,
"vector": [
141,
205
]
}
]
},
{
"Service": "starcraft2",
"NetifyName": "gaming.starcraft2",
"ValidPorts": [
[
3724,
3724
]
],
"vectors": [
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
20,
-20
]
},
{
"ID": "v0",
"CT": 2,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 10,
"vector": [
20,
20
]
}
]
},
{
"Service": "video-conferencing",
"NetifyName": "video-conferencing.video-conf",
"ValidPorts": [
[
3478,
3478
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 4,
"vector": []
}
]
},
{
"Service": "slack",
"NetifyName": "video-conferencing.slack",
"ValidPorts": [
[
22466,
22466
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "webex",
"NetifyName": "video-conferencing.webex",
"ValidPorts": [
[
9000,
9000
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "meet",
"NetifyName": "video-conferencing.meet",
"ValidPorts": [
[
19302,
19309
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "zoom",
"NetifyName": "video-conferencing.zoom",
"ValidPorts": [
[
3478,
3479
],
[
8801,
8802
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "bluejeans",
"NetifyName": "video-conferencing.bluejeans",
"ValidPorts": [
[
5000,
5000
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
},
{
"Service": "teams/skype",
"NetifyName": "video-conferencing.teams/skype",
"ValidPorts": [
[
3478,
3481
]
],
"vectors": [
{
"ID": "v0",
"CT": 0,
"TT": 0,
"ignore_indices": [],
"proto": "udp",
"confidence": 6,
"vector": []
}
]
}
]
}

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1,68 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Represents a collection of flows. For testing ref defs",
"type": "object",
"properties": {
"flows": {
"type": "array",
"items": {
"$ref": "#/$defs/flow"
}
}
},
"required": [
"flows"
],
"$defs": {
"flow": {
"type": "object",
"properties": {
"flow_id": {
"type": "string"
},
"service_name": {
"type": "string"
},
"master_protocol": {
"type": "string"
},
"sport": {
"type": "integer"
},
"dport": {
"type": "integer"
},
"src": {
"type": "string"
},
"dst": {
"type": "string"
},
"proto": {
"type": "string"
},
"alive": {
"type": "string"
},
"active": {
"type": "boolean"
},
"extrakeythatdoesnotexist": {
"type": "string"
}
},
"required": [
"flow_id",
"service_name",
"master_protocol",
"sport",
"dport",
"src",
"dst",
"proto",
"alive",
"active"
]
}
}
}

View File

@ -0,0 +1,12 @@
{
"description": "string pattern side tests",
"schema-non-object": {
"pattern": true
},
"schema-invalid-regex": {
"pattern": "^[a-zA-Z0-9]*@[a-zA-Z0-9-_.]*[.]*?"
},
"schema-valid": {
"pattern": "boten*"
}
}

View File

@ -0,0 +1,23 @@
{
"description": "patternProperties side tests",
"schema-non-object": {
"patternProperties": true
},
"schema-invalid-regex": {
"patternProperties": {
"^[a-zA-Z0-9]*@[a-zA-Z0-9-_.]*[.]*?": {
"type": "object"
}
}
},
"schema-valid": {
"patternProperties": {
"boten*": {
"type": "string"
},
"anna.*": {
"type": "string"
}
}
}
}

View File

@ -0,0 +1,51 @@
{
"acceptstringandinteger": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"anyOf": [
{
"properties": {
"id": {
"type": "integer"
}
}
},
{
"properties": {
"id": {
"type": "string"
}
}
}
],
"required": [
"id"
]
},
"inarray": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"properties": {
"anna": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"required": [
"id"
]
}
]
}
}
}
},
"anyOfSchemaError": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"anyOf": [
"type"
]
}
}

View File

@ -0,0 +1,22 @@
{
"enum-string": {
"type": "string",
"enum": [
"one",
"two",
"three"
]
},
"enum-integer": {
"type": "integer",
"enum": [
1,
2,
3
]
},
"enum-schemaerror": {
"type": "integer",
"enum": "1,2,3"
}
}

View File

@ -0,0 +1,51 @@
{
"test1": {
"type": "object",
"properties": {
"flowarray": {
"type": "array",
"items": {
"type": "object",
"required": [
"key1",
"key2"
],
"properties": {
"key1": {
"type": "integer"
},
"key2": {
"type": "string"
},
}
}
}
}
},
"nested": {
"type": "object",
"properties": {
"flowarray": {
"type": "array",
"items": {
"type": "object",
"required": [
"key1",
"key2"
],
"properties": {
"key1": {
"type": "string"
},
"key2": {
"type": "array",
"items": {
"type": "integer"
}
},
}
}
}
}
}
}

View File

@ -0,0 +1,7 @@
{
"schema-2-3": {
"type": "array",
"maxItems": 3,
"minItems": 2
}
}

View File

@ -0,0 +1,80 @@
{
"noproperties":
{
"type": "object"
},
"emptyproperties":
{
"type": "object",
"properties": {}
},
"typetests":
{
"type": "object",
"properties": {
"computer": {
"type": "string"
},
"phone": {
"type": "integer"
},
"switch": {
"type": "boolean"
},
"object": {
"type": "object"
},
"list": {
"type": "array"
}
}
},
"typetests2":
{
"type": "object",
"properties": {
"computer": {
"type": "string"
},
"phone": {
"type": "integer"
},
"switch": {
"type": "boolean"
},
"object": {
"type": "object"
},
"list": {
"type": "array"
}
}
},
"string-properties":
{
"type": "object",
"properties": {
"computer1": {
"type": "string"
},
"computer2": {
"type": "string",
"maxLength": 4
},
"computer3": {
"type": "string",
"minLength": 2,
"maxLength": 2
},
"computer4": {
"type": "string",
"minLength": 3,
"maxLength": 4
}
}
}
}

View File

@ -0,0 +1,14 @@
{
"type": "object",
"properties": {
"person": {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 4},
"husbands": {"type": "integer"}
},
"required": ["name"]
}
},
"required": ["person"]
}

View File

@ -0,0 +1,12 @@
{
"test-emptyschema": {},
"test-norequired": {"type": "object"},
"test-required-empty": {"type": "object", "required": []},
"test-require-abc": {"type": "object", "required": ["a","b","c"]},
"test-require-bc": {"type": "object", "required": ["b","c"]},
"test-require-ac": {"type": "object", "required": ["a","c"]},
"test-require-ab": {"type": "object", "required": ["a","b"]},
"test-require-a": {"type": "object", "required": ["a"]},
"test-require-b": {"type": "object", "required": ["b"]},
"test-require-c": {"type": "object", "required": ["c"]}
}

View File

@ -0,0 +1,12 @@
{
"test-object" : {"type": "object"},
"test-array" : {"type": "array"},
"test-string" : {"type": "string"},
"test-integer" : {"type": "integer"},
"test-double" : {"type": "double"},
"test-boolean" : {"type": "boolean"},
"test-nonsense" : {"type": "nonsense"},
"test-nonstring" : {"type": 1 },
"test-nonstring2" : {"type": {"type": "yes" } }
}

View File

@ -0,0 +1,14 @@
{
"unique": {
"type": "array",
"uniqueItems": true
},
"notunique": {
"type": "array",
"uniqueItems": false
},
"schemaerror": {
"type": "array",
"uniqueItems": 1
}
}

View File

@ -0,0 +1,127 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"ID",
"Version",
"Services"
],
"properties": {
"ID": {
"type": "string",
"enum": [
"lcss_vectors"
]
},
"Version": {
"type": "string",
"minLength": 2
},
"Services": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"Service",
"NetifyName",
"ValidPorts",
"vectors"
],
"properties": {
"Service": {
"type": "string",
"minLength": 4
},
"NetifyName": {
"type": "string",
"minLength": 4
},
"max_diff": {
"type": "integer"
},
"max_length": {
"type": "integer"
},
"ValidPorts": {
"type": "array",
"minItems": 1,
"items": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"type": "integer",
"minimum": 1,
"maximum": 65535
}
}
},
"vectors": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"ID",
"CT",
"TT",
"ignore_indices",
"proto",
"confidence",
"vector"
],
"properties": {
"ID": {
"type": "string",
"enum": [
"v0",
"v1",
"v2",
"v3"
]
},
"CT": {
"type": "integer",
"minimum": 0
},
"TT": {
"type": "integer",
"minimum": 0
},
"ignore_indices": {
"type": "array",
"maxItems": 10,
"items": {
"type": "integer",
"minimum": 0,
"maximum": 9
}
},
"proto": {
"type": "string",
"enum": [
"tcp",
"udp"
]
},
"confidence": {
"type": "integer"
},
"vector": {
"type": "array",
"maxItems": 10,
"items": {
"type": "integer",
"minimum": -1500,
"maximum": 1500
}
}
}
}
}
}
}
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,78 @@
# Mongoose - Embedded Web Server / Embedded Networking Library
[![License: GPLv2/Commercial](https://img.shields.io/badge/License-GPLv2%20or%20Commercial-green.svg)](https://opensource.org/licenses/gpl-2.0.php)
[![Build Status]( https://github.com/cesanta/mongoose/workflows/build/badge.svg)](https://github.com/cesanta/mongoose/actions)
[![Code Coverage](https://codecov.io/gh/cesanta/mongoose/branch/master/graph/badge.svg)](https://codecov.io/gh/cesanta/mongoose)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/mongoose.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
Mongoose is a networking library for C/C++. It implements event-driven
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It is designed for
connecting devices and bringing them online. On the market since 2004, used by
vast number of open source and commercial products - it even runs on the
International Space Station! Mongoose makes embedded network programming fast,
robust, and easy. Features include:
- Cross-platform: works on Linux/UNIX, MacOS, Windows, Android, FreeRTOS, etc.
- Supported embedded architectures: ESP32, NRF52, STM32, NXP, and more
- Built-in protocols: plain TCP/UDP, HTTP, MQTT, Websocket
- SSL/TLS support: mbedTLS, OpenSSL or custom (via API)
- Asynchronous DNS resolver
- Tiny static and run-time footprint
- Source code is both ISO C and ISO C++ compliant
- Works with any network stack with socket API, like LwIP or FreeRTOS-Plus-TCP
- Very easy to integrate: just copy `mongoose.c` and `mongoose.h` files to your build tree
- Optional built-in TCP/IP stack with drivers for bare metal or RTOS firmwares
- A full device dashboard
[bare metal example on Nucleo-F429ZI](examples/stm32/nucleo-f429zi-baremetal)
is only 6 files
- For comparison, a CubeIDE generated HTTP example is 400+ files
- Detailed [documentation](https://mongoose.ws/documentation/) and
[tutorials](https://mongoose.ws/tutorials/)
# Commercial use
- Mongoose is used by hundreds of businesses, from Fortune500 giants like
Siemens, Schneider Electric, Broadcom, Bosch, Google, Samsung, Qualcomm, Caterpillar to the small businesses
- Used to solve a wide range of business needs, like implementing Web UI
interface on devices, RESTful API services, telemetry data exchange, remote
control for a product, remote software updates, remote monitoring, and others
- Deployed to hundreds of millions devices in production environment worldwide
- See [Case Studies](https://mongoose.ws/case-studies/) from our respected
customers like [Schneider Electric](https://mongoose.ws/case-studies/schneider-electric/) (industrial automation), [Broadcom](https://mongoose.ws/case-studies/broadcom/) (semiconductors), [Pilz](https://mongoose.ws/case-studies/pilz/) (industrial automation), and others
- See [Testimonials](https://mongoose.ws/testimonials/) from engineers that integrated Mongoose in their commercial products
- We provide [Evaluation and Commercial licensing](https://mongoose.ws/licensing/), [support](https://mongoose.ws/support/), consultancy and integration
assistance - don't hesitate to [contact us](https://mongoose.ws/contact/)
# Security
We take security seriously:
1. Mongoose repository runs a
[continuous integration test powered by GitHub](https://github.com/cesanta/mongoose/actions),
which runs through hundreds of unit tests on every commit to the repository.
Our [unit tests](https://github.com/cesanta/mongoose/tree/master/test)
are built with modern address sanitizer technologies, which help to find
security vulnerabilities early
2. Mongoose repository is integrated into Google's
[oss-fuzz continuous fuzzer](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
which scans for potential vulnerabilities continuously
3. We receive periodic vulnerability reports from the independent security
groups like
[Cisco Talos](https://www.cisco.com/c/en/us/products/security/talos.html),
[Microsoft Security Response Center](https://www.microsoft.com/en-us/msrc),
[MITRE Corporation](https://www.mitre.org/),
[Compass Security](https://www.compass-security.com/en/) and others.
In case of the vulnerability found, we act according to the industry best
practice: hold on to the publication, fix the software and notify all our
customers that have an appropriate subscription
4. Some of our customers (for example NASA)
have specific security requirements and run independent security audits,
of which we get notified and in case of any issue, act similar to (3).
# Contributions
Contributions are welcome! Please follow the guidelines below:
- Sign [Cesanta CLA](https://cesanta.com/cla.html) and send GitHub pull request
- Make sure that PRs have only one commit, and deal with one issue only

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 164 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 158 KiB

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1034 239" style="enable-background:new 0 0 1034 239;" xml:space="preserve">
<style type="text/css">
.st0{fill:#576174;}
.st1{fill:#FFFFFF;}
.st2{font-family:'Courier-Bold';}
.st3{font-size:16.7604px;}
.st4{fill:#00983A;}
.st5{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st6{fill:#45CFFF;}
.st7{fill:none;stroke:#A000FF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st8{fill:#A000FF;}
.st9{fill:none;stroke:#FFDE00;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
.st10{fill:#FFDE00;}
.st11{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
.st12{fill:#EA5B0C;}
</style>
<g>
<path class="st0" d="M485.3,224.22H8.5c-4.7,0-8.5-3.8-8.5-8.5V27.22c0-4.7,3.8-8.5,8.5-8.5h476.8c4.7,0,8.5,3.8,8.5,8.5v188.5
C493.8,220.32,490,224.22,485.3,224.22z"/>
<g>
<g>
<g>
<text transform="matrix(1 0 0 1 21.294 60.1267)" class="st1 st2 st3">struct mg_str k,v,s = mg_str(”a=333, b=777”);</text>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 21.294 136.2499)" class="st1 st2 st3">mg_commalist(&amp;s, &amp;k, &amp;v); </text>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 21.294 197.1485)" class="st1 st2 st3">mg_commalist(&amp;s, &amp;k, &amp;v); </text>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 291.5096 140.18)" class="st4 st2 st3">// 1st call</text>
<text transform="matrix(1 0 0 1 291.5096 199.8101)" class="st4 st2 st3">// 2nd call</text>
</g>
</g>
</g>
<g>
<polyline class="st5" points="336.4,64.52 336.4,68.52 317.8,68.52 317.8,64.52 "/>
<g>
<path class="st5" d="M122.3,59.62"/>
<g>
<polyline class="st5" points="327.5,76.82 327.6,94.02 203.3,94.02 203.3,116.12 "/>
<path class="st6" d="M331,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C329.5,74.42,331,75.92,331,77.62z"/>
</g>
</g>
<path class="st6" d="M203.2,114.92c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C206.5,116.32,205,114.92,203.2,114.92z"/>
</g>
<g>
<polyline class="st7" points="407.4,64.52 407.4,68.52 388.8,68.52 388.8,64.52 "/>
<g>
<path class="st5" d="M193.4,59.62"/>
<g>
<polyline class="st7" points="398.6,76.82 398.6,149.02 203.4,149.02 203.4,177.12 "/>
<path class="st8" d="M402,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C400.6,74.42,402,75.92,402,77.62z"/>
</g>
</g>
<path class="st8" d="M203.2,175.42c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C206.5,176.82,205,175.42,203.2,175.42z"/>
</g>
<g>
<polyline class="st9" points="440.8,64.52 440.8,68.52 414.2,68.52 414.2,64.52 "/>
<g>
<path class="st5" d="M218.8,59.62"/>
<g>
<polyline class="st9" points="428,76.82 428,163.02 245.7,163.02 245.7,176.12 "/>
<path class="st10" d="M431.4,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C430,74.42,431.4,75.92,431.4,77.62z"/>
</g>
</g>
<path class="st10" d="M245.4,175.42c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C248.7,176.82,247.2,175.42,245.4,175.42z
"/>
</g>
<g>
<polyline class="st11" points="372.8,64.52 372.8,68.52 343.2,68.52 343.2,64.52 "/>
<g>
<path class="st5" d="M164.7,59.62"/>
<g>
<polyline class="st11" points="358.3,76.62 358.3,104.82 245.7,105.02 245.7,116.12 "/>
<path class="st12" d="M361.4,77.62c0,1.8-1.4,3.2-3.2,3.3c-1.8,0.1-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C359.9,74.42,361.4,75.92,361.4,77.62z"/>
</g>
</g>
<path class="st12" d="M245.7,114.92c-1.8,0-3.2,1.3-3.3,3s1.4,3,3.2,3s3.2-1.3,3.3-3l0,0C248.9,116.32,247.4,114.92,245.7,114.92z
"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1034 158.07" style="enable-background:new 0 0 1034 158.07;" xml:space="preserve">
<style type="text/css">
.st0{fill:#67748A;}
.st1{fill:#FFFFFF;}
.st2{font-family:'Courier-Bold';}
.st3{font-size:16.7604px;}
.st4{fill:none;stroke:#45CFFF;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
.st5{fill:#45CFFF;}
.st6{font-family:'Arial-BoldMT';}
</style>
<g>
<path class="st0" d="M516.7,39.8v56.33c0,4.17-3.8,7.54-8.5,7.54H14.6H8.5c-4.7,0-8.5-3.37-8.5-7.54V39.8c0-4.17,3.8-7.54,8.5-7.54
h499.7C512.9,32.26,516.7,35.63,516.7,39.8z"/>
<text transform="matrix(1 0 0 1 51.0379 69.3318)" class="st1 st2 st3">GET /test \n\nGET /test \n\nGET test \n\n</text>
<g>
<polyline class="st4" points="189.5,76.47 189.5,80.47 51.8,80.47 51.8,76.47 "/>
<polyline class="st4" points="331.3,76.47 331.3,80.47 195.6,80.47 195.6,76.47 "/>
<polyline class="st4" points="462.7,76.47 462.7,80.47 336.9,80.47 336.9,76.47 "/>
</g>
<g>
<text transform="matrix(1 0 0 1 78.8909 148.8896)" class="st5 st6 st3">1st request</text>
<g>
<line class="st4" x1="120.2" y1="93.57" x2="120.3" y2="129.57"/>
<path class="st5" d="M117.1,92.57c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
C118.5,95.77,117.1,94.37,117.1,92.57z"/>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 217.3594 148.8891)" class="st5 st6 st3">2nd request </text>
<g>
<line class="st4" x1="263.8" y1="93.57" x2="263.9" y2="129.57"/>
<path class="st5" d="M260.7,92.57c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
C262.1,95.77,260.7,94.37,260.7,92.57z"/>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 354.7297 148.8896)" class="st5 st6 st3">3rd request </text>
<g>
<line class="st4" x1="399.4" y1="93.57" x2="399.4" y2="129.57"/>
<path class="st5" d="M396.2,92.57c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
C397.7,95.77,396.2,94.37,396.2,92.57z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1035.4 429.9" style="enable-background:new 0 0 1035.4 429.9;" xml:space="preserve">
<style type="text/css">
.st0{fill:#576174;}
.st1{fill:#67748A;}
.st2{fill:none;stroke:#87005B;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st3{fill:#87005B;}
.st4{fill:#FFFFFF;}
.st5{font-family:'Courier-Bold';}
.st6{font-size:16.7604px;}
.st7{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
.st8{fill:#EA5B0C;}
.st9{fill:none;stroke:#CA70FF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st10{fill:#CA70FF;}
.st11{fill:none;stroke:#FFDE00;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
.st12{fill:#FFDE00;}
.st13{fill:none;stroke:#00CF4F;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st14{fill:#00CF4F;}
.st15{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st16{fill:none;stroke:#EA5B0C;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st17{font-family:'Arial-BoldMT';}
.st18{font-size:24px;}
.st19{fill:#45CFFF;}
</style>
<g>
<path class="st0" d="M755.8,391.8H8.5c-4.7,0-8.5-3.8-8.5-8.5v-153c0-4.7,3.8-8.5,8.5-8.5h747.3c4.7,0,8.5,3.8,8.5,8.5v153
C764.3,388,760.5,391.8,755.8,391.8z"/>
<path class="st1" d="M996.9,261.5h-427c-4.7,0-8.5-3.8-8.5-8.5V81.2c0-4.7,3.8-8.5,8.5-8.5h427c4.7,0,8.5,3.8,8.5,8.5V253
C1005.4,257.7,1001.5,261.5,996.9,261.5z"/>
<g>
<polyline class="st2" points="598.1,238.2 598.1,242.3 787.7,242.3 787.7,238.2 "/>
<g>
<line class="st2" x1="689.3" y1="342.2" x2="276.4" y2="343.3"/>
<g>
<line class="st2" x1="689.4" y1="253.3" x2="689.4" y2="342.1"/>
<path class="st3" d="M689.4,249.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2l0,0
C686.1,250.7,687.6,249.3,689.4,249.3z"/>
</g>
</g>
<path class="st3" d="M274.2,340.4c1.8,0,3.2,1.4,3.3,3.2s-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2l0,0
C270.9,341.8,272.4,340.4,274.2,340.4z"/>
</g>
<text transform="matrix(1 0 0 1 26.0923 262.5192)" class="st4 st5 st6">struct mg_http_message {</text>
<text transform="matrix(1 0 0 1 45.542 286.2874)" class="st4 st5 st6">struct mg_str method; uri, query, proto; </text>
<text transform="matrix(1 0 0 1 45.542 306.3874)" class="st4 st5 st6">struct mg_http_header headers[MG_MAX_HTTP_HEADERS];</text>
<text transform="matrix(1 0 0 1 45.542 326.4874)" class="st4 st5 st6">struct mg_str body;</text>
<text transform="matrix(1 0 0 1 45.542 346.5874)" class="st4 st5 st6">struct mg_str message; </text>
<g>
<g>
<polyline class="st7" points="621.1,89.6 621.1,78.6 215.4,79.7 215.3,269.4 "/>
<path class="st8" d="M624.3,90.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C622.8,87.4,624.3,88.8,624.3,90.6z"/>
</g>
<path class="st8" d="M212.3,269.4c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
C213.7,272.6,212.3,271.2,212.3,269.4z"/>
</g>
<g>
<polyline class="st9" points="597.2,183.6 593.1,183.6 593.1,127.8 597.2,127.8 "/>
<g>
<polyline class="st9" points="582.4,156.2 575.2,156.2 575,302.8 563.4,302.8 "/>
<path class="st10" d="M586.1,156.2c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
C584.7,159.4,586.1,158,586.1,156.2z"/>
<path class="st10" d="M564.2,303c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2s1.4,3.2,3.2,3.3l0,0
C562.7,306.2,564.2,304.7,564.2,303z"/>
</g>
</g>
<text transform="matrix(1 0 0 1 601.1215 118.1291)" class="st4 st5 st6">POST /foo/bar/baz?aa=b&amp;cc=ddd HTTP/1.1</text>
<text transform="matrix(1 0 0 1 601.1215 138.2291)" class="st4 st5 st6">Content-Type: application/json</text>
<text transform="matrix(1 0 0 1 601.1215 158.3291)" class="st4 st5 st6">Content-Length: 19</text>
<text transform="matrix(1 0 0 1 601.1215 178.4291)" class="st4 st5 st6">Host: reqbin.com</text>
<g>
<g>
<g>
<polyline class="st11" points="712.3,90.6 712.4,67.6 277.8,67.6 279.7,269.3 "/>
<path class="st12" d="M715.6,90.8c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C714.1,87.6,715.6,89.1,715.6,90.8z"/>
</g>
<path class="st12" d="M276.5,269.4c0-1.8,1.4-3.2,3.2-3.3s3.2,1.4,3.3,3.2s-1.4,3.2-3.2,3.3l0,0
C278,272.6,276.5,271.2,276.5,269.4z"/>
</g>
<polyline class="st11" points="771.5,104.3 771.5,100.3 652.7,100.3 652.7,104.3 "/>
</g>
<g>
<g>
<g>
<polyline class="st13" points="836.3,90.6 836.3,56.6 342.8,56.6 344.7,268.3 "/>
<path class="st14" d="M839.5,90.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C838,87.4,839.5,88.9,839.5,90.6z"/>
</g>
<path class="st14" d="M341.4,269.3c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
C342.9,272.5,341.4,271.1,341.4,269.3z"/>
</g>
<polyline class="st15" points="981.4,104.2 981.4,100.2 902.6,100.2 902.6,104.2 "/>
</g>
<text transform="matrix(1 0 0 1 596.891 232.3658)" class="st4 st5 st6">{&quot;success&quot;: &quot;true&quot;}</text>
<polyline class="st16" points="643.1,104.4 643.1,100.4 599.3,100.4 599.3,104.4 "/>
<text transform="matrix(1 0 0 1 9.5506 207.5157)" class="st17 st18">Source Code</text>
<text transform="matrix(1 0 0 1 797.0799 32.3923)" class="st17 st18">HTTP message</text>
<text transform="matrix(1 0 0 1 26.0924 359.209)" class="st4 st5 st6">};</text>
<polyline class="st13" points="894.2,104.2 894.2,100.2 774.4,100.2 774.4,104.2 "/>
<g>
<g>
<polyline class="st15" points="941.3,90.6 941.3,45.6 412.8,45.6 414.7,268.3 "/>
<path class="st19" d="M944.5,90.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C943,87.4,944.5,88.9,944.5,90.6z"/>
</g>
<path class="st19" d="M411.4,269.3c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
C412.9,272.5,411.4,271.1,411.4,269.3z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1034 663.54" style="enable-background:new 0 0 1034 663.54;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st1{fill:#45CFFF;}
.st2{fill:#576174;}
.st3{fill:#FFFFFF;}
.st4{font-family:'Courier-Bold';}
.st5{font-size:16.7604px;}
.st6{font-family:'Arial-BoldMT';}
.st7{font-size:24px;}
.st8{fill:#67748A;}
.st9{fill:#8B9CBA;}
.st10{fill:none;stroke:#00CF4F;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st11{fill:#00CF4F;}
.st12{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
.st13{fill:#EA5B0C;}
.st14{fill:#414857;}
</style>
<g>
<g>
<polyline class="st0" points="498.5,624.21 498.5,628.21 447.9,628.21 447.9,624.21 "/>
<g>
<path class="st0" d="M491.8,844.81"/>
<g>
<path class="st1" d="M473.8,636.11c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
C477.1,637.61,475.6,636.11,473.8,636.11z"/>
</g>
</g>
<path class="st1" d="M296.7,852.71c-1.8,0-3.2,1.3-3.3,3c0,1.7,1.4,3,3.2,3c1.8,0,3.2-1.3,3.3-3l0,0
C299.9,854.01,298.5,852.71,296.7,852.71z"/>
</g>
<g>
<path class="st2" d="M584.6,199.01H8.5c-4.7,0-8.5-3.8-8.5-8.5V60.71c0-4.7,3.8-8.5,8.5-8.5h576.1c4.7,0,8.5,3.8,8.5,8.5v129.8
C593.1,195.21,589.3,199.01,584.6,199.01z"/>
<g>
<g>
<g>
<text transform="matrix(1 0 0 1 28.7 90.8107)" class="st3 st4 st5">struct mg_http_part part;</text>
<text transform="matrix(1 0 0 1 28.7 110.9108)" class="st3 st4 st5">size_t pos = 0;</text>
<text transform="matrix(1 0 0 1 28.7 151.1107)" class="st3 st4 st5">pos = mg_http_next_multipart(&amp;hm-&gt;body, pos, &amp;part);</text>
<text transform="matrix(1 0 0 1 28.7 171.3107)" class="st3 st4 st5">pos = mg_http_next_multipart(&amp;hm-&gt;body, pos, &amp;part);</text>
</g>
</g>
</g>
<text transform="matrix(1 0 0 1 1.3738 40.559)" class="st6 st7">Source Code</text>
</g>
<g>
<g>
<path class="st8" d="M685.5,646.41H8.5c-4.7,0-8.5-3.8-8.5-8.5v-362.9c0-4.7,3.8-8.5,8.5-8.5h677c4.7,0,8.5,3.8,8.5,8.5v362.9
C694,642.61,690.2,646.41,685.5,646.41z"/>
</g>
<path class="st9" d="M640.2,629.41H26.3c-4.7,0-8.5-3.8-8.5-8.5v-106.5c0-4.7,3.8-8.5,8.5-8.5h613.9c4.7,0,8.5,3.8,8.5,8.5v106.5
C648.7,625.61,644.8,629.41,640.2,629.41z"/>
<path class="st9" d="M644,490.91H30.1c-4.7,0-8.5-3.8-8.5-8.5v-106.5c0-4.7,3.8-8.5,8.5-8.5H644c4.7,0,8.5,3.8,8.5,8.5v106.5
C652.5,487.11,648.7,490.91,644,490.91z"/>
<g>
<text transform="matrix(1 0 0 1 0.0299 253.0343)" class="st6 st7">HTTP message</text>
</g>
<g>
<text transform="matrix(1 0 0 1 28.7 302.8107)" class="st3 st4 st5">POST /upload HTTP/1.1 </text>
<text transform="matrix(1 0 0 1 28.7 322.9107)" class="st3 st4 st5">Content-Type: multipart/form-data; boundary=&quot;--xyz&quot;</text>
<text transform="matrix(1 0 0 1 28.7 363.1107)" class="st3 st4 st5">--xyz</text>
<text transform="matrix(1 0 0 1 28.7 383.3107)" class="st3 st4 st5">Content-Disposition: form-data; name=&quot;foo&quot;; filename=&quot;a.txt&quot;</text>
<text transform="matrix(1 0 0 1 28.7 403.4107)" class="st3 st4 st5">Content-Type: text/plain</text>
<text transform="matrix(1 0 0 1 28.7 443.6107)" class="st3 st4 st5">hello world</text>
<text transform="matrix(1 0 0 1 28.7 483.8107)" class="st3 st4 st5">--xyz---</text>
<text transform="matrix(1 0 0 1 28.7 524.0107)" class="st3 st4 st5">Content-Disposition: form-data; name=&quot;bar&quot;; filename=&quot;b.txt&quot;</text>
<text transform="matrix(1 0 0 1 28.7 544.2108)" class="st3 st4 st5">Content-Type: text/plain</text>
<text transform="matrix(1 0 0 1 28.7 584.4108)" class="st3 st4 st5">hello world again</text>
<text transform="matrix(1 0 0 1 28.7 624.6107)" class="st3 st4 st5">--xyz--</text>
</g>
</g>
<g>
<g>
<polyline class="st10" points="569.5,162.51 574.5,162.51 574.5,176.11 569.5,176.11 "/>
<g>
<path class="st0" d="M726.8,392.91"/>
<g>
<polyline class="st10" points="587.3,169.71 726.7,169.71 726.6,569.31 684.3,569.31 "/>
<path class="st11" d="M585,166.41c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
C588.2,167.91,586.8,166.41,585,166.41z"/>
</g>
</g>
<path class="st11" d="M685,566.31c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3l0,0C688,567.61,686.6,566.31,685,566.31z"/>
</g>
<polyline class="st10" points="657.9,501.61 673.9,501.61 673.9,634.21 657.9,634.21 "/>
</g>
<g>
<g>
<polyline class="st12" points="569.5,143.21 574.5,143.21 574.5,156.81 569.5,156.81 "/>
<g>
<path class="st0" d="M726.8,254.61"/>
<g>
<polyline class="st12" points="587.3,150.41 710.7,150.41 710.6,431.01 684.3,431.01 "/>
<path class="st13" d="M585,147.11c-1.8,0-3.2,1.4-3.3,3.2s1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
C588.2,148.61,586.8,147.11,585,147.11z"/>
</g>
</g>
<path class="st13" d="M685,428.01c-1.7,0-3,1.3-3,3s1.3,3,3,3s3-1.3,3-3l0,0C688,429.31,686.6,428.01,685,428.01z"/>
</g>
<polyline class="st12" points="657.9,363.31 673.9,363.31 673.9,495.91 657.9,495.91 "/>
</g>
<text transform="matrix(1 0 0 1 537.9671 462.1467)" class="st14 st6 st7">Part 1</text>
<text transform="matrix(1 0 0 1 537.9671 600.4373)" class="st14 st6 st7">Part 2</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1034 480.6" style="enable-background:new 0 0 1034 480.6;" xml:space="preserve">
<style type="text/css">
.st0{fill:#67748A;}
.st1{fill:#8B9CBA;}
.st2{fill:#FFFFFF;}
.st3{font-family:'Courier-Bold';}
.st4{font-size:16.7604px;}
.st5{fill:#414857;}
.st6{font-family:'Arial-BoldMT';}
.st7{font-size:30px;}
.st8{font-size:24px;}
.st9{fill:#576174;}
.st10{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st11{fill:#45CFFF;}
.st12{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
.st13{fill:#EA5B0C;}
.st14{fill:none;stroke:#EA5B0C;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st15{fill:none;stroke:#FFDE00;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
.st16{fill:#FFDE00;}
</style>
<g>
<g>
<path class="st0" d="M908.4,454.9H272c-4.7,0-8.5-3.8-8.5-8.5V216c0-4.7,3.8-8.5,8.5-8.5h636.4c4.7,0,8.5,3.8,8.5,8.5v230.4
C916.9,451.1,913.1,454.9,908.4,454.9z"/>
<g>
<path class="st1" d="M898.6,430.8H284.7c-4.7,0-8.5-3.8-8.5-8.5V315.9c0-4.7,3.8-8.5,8.5-8.5h613.9c4.7,0,8.5,3.8,8.5,8.5v106.5
C907.1,427,903.3,430.8,898.6,430.8z"/>
<text transform="matrix(1 0 0 1 295.3688 243.086)" class="st2 st3 st4">POST /upload HTTP/1.1 </text>
<text transform="matrix(1 0 0 1 295.3688 263.186)" class="st2 st3 st4">Content-Type: multipart/form-data: boundary=&quot;--xyz&quot;</text>
<text transform="matrix(1 0 0 1 295.3688 303.386)" class="st2 st3 st4">--xyz</text>
<text transform="matrix(1 0 0 1 295.3688 323.586)" class="st2 st3 st4">Content-Disposition: form-data; name=&quot;foo&quot;; filename=&quot;a.txt&quot;</text>
<text transform="matrix(1 0 0 1 295.3688 343.686)" class="st2 st3 st4">Content-Type: text/plain</text>
<text transform="matrix(1 0 0 1 295.3688 383.886)" class="st2 st3 st4">hello world</text>
<text transform="matrix(1 0 0 1 295.3688 424.086)" class="st2 st3 st4">--xyz---</text>
</g>
</g>
<text transform="matrix(1 0 0 1 739.2766 414.2906)" class="st5 st6 st7">HTTP part</text>
<text transform="matrix(1 0 0 1 739.2764 193.4305)" class="st6 st8">HTTP message</text>
<path class="st9" d="M304.9,198H8.5c-4.7,0-8.5-3.8-8.5-8.5V64.8c0-4.7,3.8-8.5,8.5-8.5H305c4.7,0,8.5,3.8,8.5,8.5v124.7
C313.4,194.2,309.6,198,304.9,198z"/>
<g>
<g>
<text transform="matrix(1 0 0 1 25.2409 91.1617)" class="st2 st3 st4">struct mg_http_part {</text>
<text transform="matrix(1 0 0 1 47.0734 113.7079)" class="st2 st3 st4">struct mg_str name;</text>
<text transform="matrix(1 0 0 1 47.0734 133.8079)" class="st2 st3 st4">strucy mg_str filename;</text>
<text transform="matrix(1 0 0 1 47.0734 153.9079)" class="st2 st3 st4">struct mg_str body;</text>
</g>
</g>
<g>
<polyline class="st10" points="237.4,159 237.4,163 185.8,163 185.8,159 "/>
<g>
<polyline class="st10" points="211.7,348.3 349.5,348.4 349.5,355.6 "/>
<g>
<line class="st10" x1="211.6" y1="174.4" x2="211.6" y2="348.1"/>
<path class="st11" d="M211.6,170.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
C214.8,171.8,213.4,170.3,211.6,170.3z"/>
</g>
</g>
<path class="st11" d="M349.6,353.6c-1.8,0-3.2,1.4-3.3,3.2s1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
C352.8,355.1,351.4,353.6,349.6,353.6z"/>
<polyline class="st10" points="237.4,159 237.4,163 185.8,163 185.8,159 "/>
<polyline class="st10" points="407.3,371.1 407.3,367.1 293.3,367.1 293.3,371.1 "/>
</g>
<g>
<g>
<g>
<polyline class="st12" points="693.7,291.6 693.7,277.7 280.7,278.8 280.5,109.4 248.3,109.4 "/>
<path class="st13" d="M696.9,293.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C695.4,290.4,696.9,291.9,696.9,293.6z"/>
</g>
<path class="st13" d="M243.9,109.5c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
C245.3,112.7,243.9,111.3,243.9,109.5z"/>
</g>
<polyline class="st14" points="707.6,309.2 707.6,305.2 679.9,305.2 679.9,309.2 "/>
</g>
<text transform="matrix(1 0 0 1 0.8627 37.8099)" class="st6 st8">Source Code</text>
<text transform="matrix(1 0 0 1 25.2408 177.7241)" class="st2 st3 st4">};</text>
<g>
<g>
<g>
<polyline class="st15" points="863.8,291.5 863.7,218.6 329.7,218.7 329.6,130.3 298.4,130.3 "/>
<path class="st16" d="M867.1,293.6c0,1.8-1.4,3.2-3.2,3.3c-1.8,0-3.2-1.4-3.3-3.2c0-1.8,1.4-3.2,3.2-3.3l0,0
C865.6,290.3,867.1,291.8,867.1,293.6z"/>
</g>
<path class="st16" d="M293,130.1c0-1.8,1.4-3.2,3.2-3.3c1.8,0,3.2,1.4,3.3,3.2c0,1.8-1.4,3.2-3.2,3.3l0,0
C294.4,133.3,293,131.9,293,130.1z"/>
</g>
<polyline class="st15" points="888.7,309.1 888.7,305.1 838.9,305.1 838.9,309.1 "/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1034 331.2" style="enable-background:new 0 0 1034 331.2;" xml:space="preserve">
<style type="text/css">
.st0{fill:#576174;}
.st1{fill:#67748A;}
.st2{fill:#FFFFFF;}
.st3{font-family:'Courier-Bold';}
.st4{font-size:16.7604px;}
.st5{font-family:'Arial-BoldMT';}
.st6{font-size:24px;}
.st7{fill:none;stroke:#45CFFF;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st8{fill:#45CFFF;}
.st9{fill:none;stroke:#EA5B0C;stroke-width:2.793;stroke-linecap:round;stroke-linejoin:round;}
.st10{fill:#EA5B0C;}
.st11{fill:none;stroke:#EA5B0C;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st12{fill:none;stroke:#00CF4F;stroke-width:2.7934;stroke-linecap:round;stroke-linejoin:round;}
.st13{fill:#00CF4F;}
</style>
<g>
<path class="st0" d="M541.43,184.2H8.53c-4.7,0-8.5-3.8-8.5-8.5V54.8c0-4.7,3.8-8.5,8.5-8.5h532.9c4.7,0,8.5,3.8,8.5,8.5v120.9
C549.93,180.4,546.13,184.2,541.43,184.2z"/>
<g>
<path class="st1" d="M829.23,315.5h-370c-4.7,0-8.5-3.8-8.5-8.5V157c0-4.7,3.8-8.5,8.5-8.5h370c4.7,0,8.5,3.8,8.5,8.5v150
C837.83,311.7,833.93,315.5,829.23,315.5z"/>
<g>
<text transform="matrix(1 0 0 1 490.6096 184.0905)" class="st2 st3 st4">HTTP/1.1 200 OK</text>
<text transform="matrix(1 0 0 1 490.6096 204.1905)" class="st2 st3 st4">Content-Length; 13</text>
<text transform="matrix(1 0 0 1 490.6096 224.2905)" class="st2 st3 st4">X-Header-1: additional value 1</text>
<text transform="matrix(1 0 0 1 490.6096 244.3905)" class="st2 st3 st4">X-Header-2: additional value 2</text>
<text transform="matrix(1 0 0 1 490.8657 293.1559)" class="st2 st3 st4">Hello, world!</text>
</g>
</g>
<text transform="matrix(1 0 0 1 660.5036 137.3383)" class="st5 st6">HTTP message</text>
<g>
<g>
<text transform="matrix(1 0 0 1 20.7331 85.1617)" class="st2 st3 st4">mg_http_reply(c, 200</text>
<text transform="matrix(1 0 0 1 159.5657 113.7079)" class="st2 st3 st4">&quot;X-Header-1: additional value 1\r\n&quot;</text>
<text transform="matrix(1 0 0 1 159.5657 133.8079)" class="st2 st3 st4">&quot;X-Header-2: additional value 2\r\n&quot;,</text>
<text transform="matrix(1 0 0 1 159.5657 153.9079)" class="st2 st3 st4">&quot;Hello, %s!&quot;, &quot;world&quot;);</text>
</g>
</g>
<g>
<polyline class="st7" points="362.93,159 362.93,163 167.33,163 167.33,159 "/>
<g>
<polyline class="st7" points="265.93,256.6 552.13,256.7 552.13,264.4 "/>
<g>
<line class="st7" x1="265.83" y1="174.4" x2="265.83" y2="256.6"/>
<path class="st8" d="M265.83,170.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
C269.03,171.8,267.53,170.3,265.83,170.3z"/>
</g>
</g>
<path class="st8" d="M552.23,261.6c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2l0,0
C555.43,263.1,554.03,261.6,552.23,261.6z"/>
</g>
<g>
<g>
<g>
<polyline class="st9" points="206.33,53.6 206.43,37.6 596.43,38.7 596.53,161.3 "/>
<path class="st10" d="M203.23,54.6c0,1.8,1.4,3.2,3.2,3.3c1.8,0,3.2-1.4,3.3-3.2c0-1.8-1.4-3.2-3.2-3.3l0,0
C204.63,51.4,203.23,52.8,203.23,54.6z"/>
</g>
<path class="st10" d="M599.83,164c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
C598.33,167.2,599.83,165.8,599.83,164z"/>
</g>
<polyline class="st11" points="192.43,69.2 192.43,65.2 220.23,65.2 220.23,69.2 "/>
</g>
<text transform="matrix(1 0 0 1 -1.917133e-04 35.0037)" class="st5 st6">Source Code</text>
<g>
<polyline class="st12" points="160.13,135.9 156.03,135.9 156.03,100.1 160.13,100.1 "/>
<g>
<line class="st12" x1="123.93" y1="231" x2="469.73" y2="231"/>
<polyline class="st12" points="144.73,117.2 123.83,117.2 123.73,230.8 "/>
<path class="st13" d="M147.83,117.2c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
C146.33,120.4,147.83,119,147.83,117.2z"/>
<path class="st13" d="M474.83,230.8c0-1.8-1.4-3.2-3.2-3.3c-1.8,0-3.2,1.4-3.3,3.2c0,1.8,1.4,3.2,3.2,3.3l0,0
C473.43,234,474.83,232.5,474.83,230.8z"/>
</g>
</g>
<polyline class="st7" points="489.03,279.6 489.03,275.6 620.63,275.6 620.63,279.6 "/>
<polyline class="st12" points="487.63,248.3 483.63,248.3 483.63,211.5 487.63,211.5 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 869.6 185.67" style="enable-background:new 0 0 869.6 185.67;" xml:space="preserve">
<style type="text/css">
.st0{font-family:'Arial-BoldMT';}
.st1{font-size:24px;}
.st2{opacity:0.2;fill:#00983A;enable-background:new ;}
.st3{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st4{fill:#00983A;}
.st5{fill:none;stroke:#576174;stroke-miterlimit:10;}
.st6{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st7{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st8{font-family:'Courier-Bold';}
.st9{font-size:16.7604px;}
.st10{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
.st11{fill:#576174;}
.st12{font-family:'Courier';}
.st13{fill:none;}
.st14{fill:#7A8387;}
</style>
<g>
<text transform="matrix(1 0 0 1 1.0956 32.4549)" class="st0 st1">Memory</text>
<polyline class="st2" points="424.58,115.4 219.88,115.4 219.88,90.7 424.58,90.7 "/>
<g>
<g>
<g>
<polyline class="st3" points="458.98,115.4 218.98,115.4 218.98,90.7 458.98,90.7 "/>
<polyline class="st4" points="219.18,115.1 2.98,115.1 2.98,91.3 219.18,91.3 "/>
<line class="st3" x1="2.98" y1="69.2" x2="2.98" y2="130.4"/>
<line class="st5" x1="219.78" y1="69.2" x2="219.78" y2="130.4"/>
<line class="st5" x1="425.28" y1="69.2" x2="425.28" y2="130.4"/>
<path class="st6" d="M458.98,115.4"/>
<path class="st7" d="M33.98,114.6"/>
<path class="st7" d="M33.98,90.9"/>
<path class="st7" d="M2.98,90.7h216.8v24.9l-216.8-0.2C2.98,115.4,3.18,90.7,2.98,90.7z"/>
<line class="st3" x1="425.18" y1="90.8" x2="425.18" y2="115.3"/>
<path class="st6" d="M251.98,115.6"/>
<path class="st6" d="M251.98,91.9"/>
</g>
<g>
<text transform="matrix(1 0 0 1 -2.290726e-04 175.3858)" class="st4 st8 st9">buf</text>
</g>
<g>
<g>
<line class="st10" x1="2.68" y1="158.2" x2="2.68" y2="137.2"/>
<g>
<polygon class="st4" points="0.28,137.6 5.08,137.6 2.68,135.1 "/>
</g>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 214.6515 175.3858)" class="st4 st8 st9">len</text>
</g>
</g>
<g>
<g>
<line class="st10" x1="219.78" y1="158.2" x2="219.78" y2="137.2"/>
<g>
<polygon class="st4" points="217.38,137.6 222.18,137.6 219.78,135.1 "/>
</g>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 421.6186 175.3858)" class="st4 st8 st9">size</text>
</g>
</g>
<g>
<g>
<line class="st10" x1="425.38" y1="158.2" x2="425.38" y2="137.2"/>
<g>
<polygon class="st4" points="422.98,137.6 427.78,137.6 425.38,135.1 "/>
</g>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 93.1143 69.4458)" class="st11 st12 st9">data</text>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 273.8231 69.4458)" class="st11 st12 st9">free space</text>
</g>
</g>
<g>
<g>
<line class="st5" x1="132.98" y1="76.3" x2="13.98" y2="76.3"/>
<g>
<polygon class="st11" points="14.28,78.7 14.28,73.8 11.88,76.3 "/>
</g>
</g>
</g>
<g>
<line class="st13" x1="123.88" y1="76.3" x2="210.88" y2="76.3"/>
<g>
<line class="st5" x1="123.88" y1="76.3" x2="208.78" y2="76.3"/>
<g>
<polygon class="st11" points="208.48,73.8 208.48,78.7 210.88,76.3 "/>
</g>
</g>
</g>
<g>
<g>
<line class="st5" x1="320.38" y1="76.3" x2="414.28" y2="76.3"/>
<g>
<polygon class="st14" points="413.98,73.8 413.98,78.7 416.38,76.3 "/>
</g>
</g>
</g>
<g>
<g>
<line class="st5" x1="322.28" y1="76.3" x2="233.28" y2="76.3"/>
<g>
<polygon class="st14" points="233.68,78.7 233.68,73.8 231.18,76.3 "/>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 869 124.66" style="enable-background:new 0 0 869 124.66;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st1{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st2{fill:#00983A;}
.st3{font-family:'Courier-Bold';}
.st4{font-size:16.7604px;}
.st5{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
.st6{fill:#7A8387;}
</style>
<g>
<g>
<g>
<polyline class="st0" points="830.92,78.4 5.52,78.4 5.52,53.7 830.92,53.6 "/>
<line class="st1" x1="5.52" y1="32.2" x2="5.52" y2="93.4"/>
<path class="st0" d="M830.92,78.4"/>
<line class="st1" x1="36.52" y1="53.9" x2="36.52" y2="77.6"/>
<line class="st1" x1="68.92" y1="53.9" x2="68.92" y2="77.6"/>
<line class="st1" x1="101.42" y1="53.9" x2="101.42" y2="77.6"/>
<line class="st1" x1="133.72" y1="53.9" x2="133.72" y2="77.6"/>
<line class="st1" x1="166.22" y1="53.9" x2="166.22" y2="77.6"/>
<line class="st1" x1="198.52" y1="54.6" x2="198.52" y2="78.3"/>
<line class="st1" x1="230.92" y1="54.6" x2="230.92" y2="78.3"/>
</g>
<g>
<text transform="matrix(1 0 0 1 59.1908 40.8585)" class="st2 st3 st4">buf=NULL, len=0, size=0 </text>
</g>
<g>
<text transform="matrix(1 0 0 1 -1.811981e-04 109.9024)" class="st2 st3 st4">0</text>
</g>
<g>
<g>
<g>
<line class="st5" x1="46.72" y1="37.7" x2="17.72" y2="37.7"/>
<g>
<polygon class="st2" points="18.12,40.1 18.12,35.2 15.62,37.7 "/>
</g>
</g>
</g>
</g>
<g>
<path class="st6" d="M511.52,66.4c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S511.52,65.5,511.52,66.4z"/>
<path class="st6" d="M525.32,66.4c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S525.32,65.5,525.32,66.4z"/>
<path class="st6" d="M539.02,66.4c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S539.02,65.5,539.02,66.4z"/>
<path class="st6" d="M552.82,66.4c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6s0.7-1.6,1.6-1.6S552.82,65.5,552.82,66.4z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 869.6 127.5" style="enable-background:new 0 0 869.6 127.5;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.2;fill:#00983A;enable-background:new ;}
.st1{fill:#F2F3F3;}
.st2{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st3{fill:#00983A;}
.st4{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st5{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st6{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:square;stroke-linejoin:round;}
.st7{font-family:'Courier-Bold';}
.st8{font-size:16.7604px;}
.st9{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
.st10{fill:#7A8387;}
.st11{fill:#576174;}
.st12{fill:none;stroke:#576174;stroke-linecap:round;stroke-linejoin:round;}
.st13{fill:none;stroke:#7A8387;stroke-linecap:round;stroke-linejoin:round;}
.st14{fill:#333A45;}
</style>
<g>
<g>
<polyline class="st0" points="577.2,72.8 282.4,72.8 282.4,48 577.2,48 "/>
<g>
<g>
<g>
<polyline class="st1" points="122.6,72.8 5.9,72.8 5.9,48 122.6,48 "/>
<polyline class="st2" points="831.51,72.8 5.5,72.8 5.5,48 831.51,48 "/>
<polyline class="st3" points="282.7,72.5 122.5,72.5 122.5,47.7 282.7,47.7 "/>
<line class="st2" x1="122.5" y1="26.6" x2="122.5" y2="87.8"/>
<line class="st2" x1="283.3" y1="26.6" x2="283.3" y2="87.8"/>
<line class="st2" x1="576.8" y1="26.6" x2="576.8" y2="87.8"/>
<path class="st4" d="M831.51,72.8"/>
<line class="st5" x1="153.5" y1="48.3" x2="153.5" y2="72"/>
<line class="st2" x1="36.5" y1="48.3" x2="36.5" y2="72"/>
<line class="st2" x1="67.6" y1="48.3" x2="67.6" y2="72"/>
<line class="st5" x1="186" y1="48.3" x2="186" y2="72"/>
<line class="st5" x1="218.4" y1="48.3" x2="218.4" y2="72"/>
<line class="st5" x1="250.9" y1="48.3" x2="250.9" y2="72"/>
<line class="st2" x1="315.9" y1="48.3" x2="315.9" y2="72"/>
<line class="st2" x1="348.4" y1="48.3" x2="348.4" y2="72"/>
<line class="st2" x1="381.2" y1="48.3" x2="381.2" y2="72"/>
<line class="st2" x1="413.8" y1="48.3" x2="413.8" y2="72"/>
<line class="st2" x1="446.3" y1="48.3" x2="446.3" y2="72"/>
<line class="st2" x1="478.9" y1="48.3" x2="478.9" y2="72"/>
<line class="st5" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
<line class="st2" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
<line class="st5" x1="544.01" y1="48.3" x2="544.01" y2="72"/>
<line class="st2" x1="544.1" y1="48.3" x2="544.1" y2="72"/>
<line class="st6" x1="283.3" y1="73" x2="122.5" y2="72.8"/>
<line class="st6" x1="122.5" y1="48" x2="283.3" y2="48.1"/>
<path class="st4" d="M385.5,73"/>
<path class="st4" d="M385.5,49.3"/>
</g>
<g>
<text transform="matrix(1 0 0 1 127.5176 105.8013)" class="st3 st7 st8">buf</text>
</g>
<g>
<g>
<line class="st9" x1="122.2" y1="105.6" x2="122.2" y2="94.6"/>
<g>
<polygon class="st3" points="119.8,94.9 124.6,94.9 122.2,92.5 "/>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 286.6495 105.8008)" class="st3 st7 st8">len=5</text>
</g>
<g>
<g>
<line class="st9" x1="283.3" y1="105.6" x2="283.3" y2="94.6"/>
<g>
<polygon class="st3" points="280.9,94.9 285.8,94.9 283.3,92.5 "/>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 581.4624 105.8013)" class="st3 st7 st8">size=16</text>
</g>
<g>
<g>
<line class="st9" x1="576.9" y1="105.6" x2="576.9" y2="94.6"/>
<g>
<polygon class="st3" points="574.51,94.9 579.4,94.9 576.9,92.5 "/>
</g>
</g>
</g>
<g>
<path class="st10" d="M687.51,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S687.51,59.9,687.51,60.7z"/>
<path class="st10" d="M701.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S701.2,59.9,701.2,60.7z"/>
<path class="st10" d="M714.9,60.7c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
C714.2,59.1,714.9,59.9,714.9,60.7z"/>
<path class="st10" d="M728.7,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
C728.01,59.1,728.7,59.9,728.7,60.7z"/>
</g>
<g>
<path class="st10" d="M82.8,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S82.8,59.9,82.8,60.7z"/>
<path class="st10" d="M96.5,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6C95.8,59.1,96.5,59.9,96.5,60.7
z"/>
<path class="st10" d="M110.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S110.2,59.9,110.2,60.7z"/>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 180.6541 26.8123)" class="st11 st7 st8">data</text>
</g>
<g>
<text transform="matrix(1 0 0 1 387.363 26.8123)" class="st10 st7 st8">free space</text>
</g>
<g>
<g>
<line class="st12" x1="272.2" y1="33.6" x2="133.5" y2="33.6"/>
<g>
<polygon class="st11" points="271.9,36.2 273.5,33.6 271.9,31.1 271.8,31.1 271.8,36.2 "/>
</g>
<g>
<polygon class="st11" points="133.8,36.1 133.8,31.2 131.4,33.6 "/>
</g>
</g>
</g>
<g>
<g>
<line class="st13" x1="563.7" y1="33.6" x2="295.9" y2="33.6"/>
<g>
<polygon class="st10" points="563.4,36.1 563.4,31.2 565.8,33.6 "/>
</g>
<g>
<polygon class="st10" points="296.2,36.1 296.2,31.2 293.7,33.6 "/>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 615.4679 25.1898)" class="st10 st7 st8">non-allocated space</text>
</g>
<g>
<g>
<line class="st13" x1="593.7" y1="33.6" x2="829.7" y2="33.6"/>
<g>
<polygon class="st10" points="829.4,31.2 829.4,36.1 831.8,33.6 "/>
</g>
</g>
</g>
<g>
<g>
<line class="st13" x1="678.7" y1="33.6" x2="589.7" y2="33.6"/>
<g>
<polygon class="st10" points="590.01,36.1 590.01,31.2 587.6,33.6 "/>
</g>
</g>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 133.1212 64.9593)" class="st14 st7 st8">h</text>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 165.1564 64.9593)" class="st14 st7 st8">e</text>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 196.8744 64.9593)" class="st14 st7 st8">l</text>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 229.8611 64.9593)" class="st14 st7 st8">l</text>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 262.2135 64.9593)" class="st14 st7 st8">o</text>
</g>
</g>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 1.811981e-04 105.8011)" class="st3 st7 st8">0</text>
</g>
<line class="st2" x1="5.5" y1="26.4" x2="5.5" y2="87.6"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -0,0 +1,347 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 869.6 247.73" style="enable-background:new 0 0 869.6 247.73;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.2;fill:#00983A;enable-background:new ;}
.st1{fill:#00983A;}
.st2{fill:#FF80A4;}
.st3{fill:#F2F3F3;}
.st4{fill:none;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st5{fill:#F2F3F3;stroke:#7A8387;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st6{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;}
.st7{fill:none;stroke:#576174;stroke-width:1.2;stroke-linejoin:round;}
.st8{fill:none;stroke:#576174;stroke-width:1.2;stroke-linecap:square;stroke-linejoin:round;}
.st9{font-family:'Courier-Bold';}
.st10{font-size:16.7604px;}
.st11{fill:none;stroke:#00983A;stroke-linecap:round;stroke-linejoin:round;}
.st12{fill:#7A8387;}
.st13{fill:#576174;}
.st14{fill:none;stroke:#576174;stroke-linecap:round;stroke-linejoin:round;}
.st15{fill:none;stroke:#7A8387;stroke-linecap:round;stroke-linejoin:round;}
.st16{fill:#333A45;}
</style>
<g>
<g>
<polyline class="st0" points="577.2,72.8 282.4,72.8 282.4,48 577.2,48 "/>
<g>
<g>
<g>
<rect x="250.9" y="47.7" class="st1" width="32.4" height="24.8"/>
<rect x="153.5" y="47.7" class="st2" width="97.3" height="24.8"/>
<polyline class="st3" points="122.6,72.8 5.9,72.8 5.9,48 122.6,48 "/>
<polyline class="st4" points="831.51,72.8 5.5,72.8 5.5,48 831.51,48 "/>
<rect x="122.5" y="47.7" class="st1" width="31" height="24.8"/>
<line class="st4" x1="122.5" y1="26.6" x2="122.5" y2="87.8"/>
<line class="st4" x1="576.8" y1="26.6" x2="576.8" y2="87.8"/>
<path class="st5" d="M831.51,72.8"/>
<line class="st6" x1="153.5" y1="48.3" x2="153.5" y2="72"/>
<line class="st4" x1="36.5" y1="48.3" x2="36.5" y2="72"/>
<line class="st4" x1="67.6" y1="48.3" x2="67.6" y2="72"/>
<line class="st6" x1="186" y1="48.3" x2="186" y2="72"/>
<line class="st6" x1="218.4" y1="48.3" x2="218.4" y2="72"/>
<line class="st7" x1="250.9" y1="73" x2="250.81" y2="47.7"/>
<line class="st4" x1="315.9" y1="48.3" x2="315.9" y2="72"/>
<line class="st4" x1="348.4" y1="48.3" x2="348.4" y2="72"/>
<line class="st4" x1="381.2" y1="48.3" x2="381.2" y2="72"/>
<line class="st4" x1="413.8" y1="48.3" x2="413.8" y2="72"/>
<line class="st4" x1="446.3" y1="48.3" x2="446.3" y2="72"/>
<line class="st4" x1="478.9" y1="48.3" x2="478.9" y2="72"/>
<line class="st6" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
<line class="st4" x1="511.51" y1="48.3" x2="511.51" y2="72"/>
<line class="st6" x1="544.01" y1="48.3" x2="544.01" y2="72"/>
<line class="st4" x1="544.1" y1="48.3" x2="544.1" y2="72"/>
<line class="st8" x1="283.3" y1="73" x2="122.5" y2="72.8"/>
<line class="st8" x1="122.5" y1="48" x2="283.3" y2="48.1"/>
<path class="st5" d="M385.5,73"/>
<path class="st5" d="M385.5,49.3"/>
<line class="st4" x1="283.3" y1="26.6" x2="283.3" y2="87.8"/>
</g>
<g>
<text transform="matrix(1 0 0 1 127.5176 105.8013)" class="st1 st9 st10">buf</text>
</g>
<g>
<g>
<line class="st11" x1="122.2" y1="105.6" x2="122.2" y2="94.6"/>
<g>
<polygon class="st1" points="119.8,94.9 124.6,94.9 122.2,92.5 "/>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 286.6495 105.8008)" class="st1 st9 st10">len=5</text>
</g>
<g>
<g>
<line class="st11" x1="283.3" y1="105.6" x2="283.3" y2="94.6"/>
<g>
<polygon class="st1" points="280.9,94.9 285.8,94.9 283.3,92.5 "/>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 581.4624 105.8013)" class="st1 st9 st10">size=16</text>
</g>
<g>
<g>
<line class="st11" x1="576.9" y1="105.6" x2="576.9" y2="94.6"/>
<g>
<polygon class="st1" points="574.51,94.9 579.4,94.9 576.9,92.5 "/>
</g>
</g>
</g>
<g>
<path class="st12" d="M687.51,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S687.51,59.9,687.51,60.7z"/>
<path class="st12" d="M701.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S701.2,59.9,701.2,60.7z"/>
<path class="st12" d="M714.9,60.7c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
C714.2,59.1,714.9,59.9,714.9,60.7z"/>
<path class="st12" d="M728.7,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
C728.01,59.1,728.7,59.9,728.7,60.7z"/>
</g>
<g>
<path class="st12" d="M82.8,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S82.8,59.9,82.8,60.7z"/>
<path class="st12" d="M96.5,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6C95.8,59.1,96.5,59.9,96.5,60.7
z"/>
<path class="st12" d="M110.2,60.7c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S110.2,59.9,110.2,60.7z"/>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 180.6541 26.8123)" class="st13 st9 st10">data</text>
</g>
<g>
<text transform="matrix(1 0 0 1 387.363 26.8123)" class="st12 st9 st10">free space</text>
</g>
<g>
<g>
<line class="st14" x1="272.2" y1="33.6" x2="133.5" y2="33.6"/>
<g>
<polygon class="st13" points="271.9,36.2 273.5,33.6 271.9,31.1 271.8,31.1 271.8,36.2 "/>
</g>
<g>
<polygon class="st13" points="133.8,36.1 133.8,31.2 131.4,33.6 "/>
</g>
</g>
</g>
<g>
<g>
<line class="st15" x1="563.7" y1="33.6" x2="295.9" y2="33.6"/>
<g>
<polygon class="st12" points="563.4,36.1 563.4,31.2 565.8,33.6 "/>
</g>
<g>
<polygon class="st12" points="296.2,36.1 296.2,31.2 293.7,33.6 "/>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 615.4679 25.1898)" class="st12 st9 st10">non-allocated space</text>
</g>
<g>
<g>
<line class="st15" x1="593.7" y1="33.6" x2="829.7" y2="33.6"/>
<g>
<polygon class="st12" points="829.4,31.2 829.4,36.1 831.8,33.6 "/>
</g>
</g>
</g>
<g>
<g>
<line class="st15" x1="678.7" y1="33.6" x2="589.7" y2="33.6"/>
<g>
<polygon class="st12" points="590.01,36.1 590.01,31.2 587.6,33.6 "/>
</g>
</g>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 133.1212 64.9593)" class="st16 st9 st10">h</text>
</g>
</g>
<g>
<g>
<g>
<text transform="matrix(1 0 0 1 165.1564 64.9593)" class="st16 st9 st10">e</text>
</g>
</g>
</g>
<g>
<g>
<g>
<text transform="matrix(1 0 0 1 196.8744 64.9593)" class="st16 st9 st10">l</text>
</g>
</g>
</g>
<g>
<g>
<g>
<text transform="matrix(1 0 0 1 229.8611 64.9593)" class="st16 st9 st10">l</text>
</g>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 262.2135 64.9593)" class="st16 st9 st10">o</text>
</g>
</g>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 1.811981e-04 105.8011)" class="st1 st9 st10">0</text>
</g>
<line class="st4" x1="5.5" y1="26.4" x2="5.5" y2="87.6"/>
</g>
<g>
<g>
<polyline class="st0" points="577.2,207.99 186.3,207.99 186.3,183.19 577.2,183.19 "/>
<g>
<g>
<g>
<polyline class="st3" points="122.6,207.99 5.9,207.99 5.9,183.19 122.6,183.19 "/>
<polyline class="st4" points="831.51,207.99 5.5,207.99 5.5,183.19 831.51,183.19 "/>
<polyline class="st1" points="186.3,207.69 122.5,207.69 122.5,182.89 186.3,182.89 "/>
<line class="st4" x1="122.5" y1="161.79" x2="122.5" y2="222.99"/>
<line class="st4" x1="186" y1="161.79" x2="186" y2="222.99"/>
<line class="st4" x1="576.8" y1="161.79" x2="576.8" y2="222.99"/>
<path class="st5" d="M831.51,207.99"/>
<line class="st6" x1="153.5" y1="183.49" x2="153.5" y2="207.19"/>
<line class="st4" x1="36.5" y1="183.49" x2="36.5" y2="207.19"/>
<line class="st4" x1="67.6" y1="183.49" x2="67.6" y2="207.19"/>
<line class="st6" x1="186" y1="183.49" x2="186" y2="207.99"/>
<line class="st4" x1="218.4" y1="183.49" x2="218.4" y2="207.19"/>
<line class="st4" x1="250.9" y1="183.49" x2="250.9" y2="207.19"/>
<line class="st4" x1="283.3" y1="183.49" x2="283.3" y2="207.19"/>
<line class="st4" x1="315.9" y1="183.49" x2="315.9" y2="207.19"/>
<line class="st4" x1="348.4" y1="183.49" x2="348.4" y2="207.19"/>
<line class="st4" x1="381.2" y1="183.49" x2="381.2" y2="207.19"/>
<line class="st4" x1="413.8" y1="183.49" x2="413.8" y2="207.19"/>
<line class="st4" x1="446.3" y1="183.49" x2="446.3" y2="207.19"/>
<line class="st4" x1="478.9" y1="183.49" x2="478.9" y2="207.19"/>
<line class="st6" x1="511.51" y1="183.49" x2="511.51" y2="207.19"/>
<line class="st4" x1="511.51" y1="183.49" x2="511.51" y2="207.19"/>
<line class="st6" x1="544.01" y1="183.49" x2="544.01" y2="207.19"/>
<line class="st4" x1="544.1" y1="183.49" x2="544.1" y2="207.19"/>
<line class="st8" x1="186" y1="208.19" x2="122.5" y2="207.99"/>
<line class="st8" x1="122.5" y1="183.19" x2="186" y2="183.29"/>
<path class="st5" d="M385.5,208.19"/>
<path class="st5" d="M385.5,184.49"/>
</g>
<g>
<text transform="matrix(1 0 0 1 127.5176 240.9952)" class="st1 st9 st10">buf</text>
</g>
<g>
<g>
<line class="st11" x1="122.2" y1="240.79" x2="122.2" y2="229.79"/>
<g>
<polygon class="st1" points="119.8,230.09 124.6,230.09 122.2,227.69 "/>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 189.2273 240.9947)" class="st1 st9 st10">len=2</text>
</g>
<g>
<g>
<line class="st11" x1="185.88" y1="240.79" x2="185.88" y2="229.79"/>
<g>
<polygon class="st1" points="183.48,230.09 188.38,230.09 185.88,227.69 "/>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 581.4624 240.9952)" class="st1 st9 st10">size=16</text>
</g>
<g>
<g>
<line class="st11" x1="576.9" y1="240.79" x2="576.9" y2="229.79"/>
<g>
<polygon class="st1" points="574.51,230.09 579.4,230.09 576.9,227.69 "/>
</g>
</g>
</g>
<g>
<path class="st12" d="M687.51,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
S687.51,195.09,687.51,195.89z"/>
<path class="st12" d="M701.2,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S701.2,195.09,701.2,195.89z
"/>
<path class="st12" d="M714.9,195.89c0,0.9-0.7,1.6-1.6,1.6c-0.9,0-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
S714.9,195.09,714.9,195.89z"/>
<path class="st12" d="M728.7,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
C728.01,194.29,728.7,195.09,728.7,195.89z"/>
</g>
<g>
<path class="st12" d="M82.8,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S82.8,195.09,82.8,195.89z"/>
<path class="st12" d="M96.5,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6
C95.8,194.29,96.5,195.09,96.5,195.89z"/>
<path class="st12" d="M110.2,195.89c0,0.9-0.7,1.6-1.6,1.6s-1.6-0.7-1.6-1.6c0-0.9,0.7-1.6,1.6-1.6S110.2,195.09,110.2,195.89z
"/>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 133.6541 162.0062)" class="st13 st9 st10">data</text>
</g>
<g>
<text transform="matrix(1 0 0 1 327.363 162.0062)" class="st12 st9 st10">free space</text>
</g>
<g>
<g>
<line class="st14" x1="175.2" y1="168.79" x2="133.5" y2="168.79"/>
<g>
<polygon class="st13" points="174.9,171.39 176.5,168.79 174.9,166.29 174.8,166.29 174.8,171.39 "/>
</g>
<g>
<polygon class="st13" points="133.8,171.29 133.8,166.39 131.4,168.79 "/>
</g>
</g>
</g>
<g>
<g>
<line class="st15" x1="563.7" y1="168.79" x2="197.49" y2="168.79"/>
<g>
<polygon class="st12" points="563.4,171.29 563.4,166.39 565.8,168.79 "/>
</g>
<g>
<polygon class="st12" points="197.79,171.29 197.79,166.39 195.29,168.79 "/>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 615.4679 160.3837)" class="st12 st9 st10">non-allocated space</text>
</g>
<g>
<g>
<line class="st15" x1="593.7" y1="168.79" x2="829.7" y2="168.79"/>
<g>
<polygon class="st12" points="829.4,166.39 829.4,171.29 831.8,168.79 "/>
</g>
</g>
</g>
<g>
<g>
<line class="st15" x1="678.7" y1="168.79" x2="589.7" y2="168.79"/>
<g>
<polygon class="st12" points="590.01,171.29 590.01,166.39 587.6,168.79 "/>
</g>
</g>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 133.1212 200.1532)" class="st16 st9 st10">h</text>
</g>
</g>
<g>
<g>
<text transform="matrix(1 0 0 1 165.1565 200.1532)" class="st16 st9 st10">o</text>
</g>
</g>
</g>
</g>
</g>
<g>
<text transform="matrix(1 0 0 1 1.811981e-04 240.995)" class="st1 st9 st10">0</text>
</g>
<line class="st4" x1="5.5" y1="161.59" x2="5.5" y2="222.79"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because it is too large Load Diff

BIN
srcs/libs/docs/sds.pdf Normal file

Binary file not shown.

BIN
srcs/libs/docs/uthash.pdf Normal file

Binary file not shown.

BIN
srcs/libs/docs/utlist.pdf Normal file

Binary file not shown.

Binary file not shown.

BIN
srcs/libs/docs/utstack.pdf Normal file

Binary file not shown.

BIN
srcs/libs/docs/utstring.pdf Normal file

Binary file not shown.

BIN
srcs/libs/docs/zlog-EN.pdf Normal file

Binary file not shown.

7535
srcs/libs/docs/zlog.lyx Normal file

File diff suppressed because it is too large Load Diff

BIN
srcs/libs/docs/zmq.chm Normal file

Binary file not shown.

107
srcs/libs/fs_watch/fs_mon.c Normal file
View File

@ -0,0 +1,107 @@
//
// Created by xajhuang on 2023/2/9.
//
#include <uv.h>
#include "uthash/uthash.h"
#include "misc.h"
#include "common.h"
#include "user_errno.h"
#include "zlog_module.h"
#include "task_manager.h"
#include "fs_watch.h"
typedef struct {
char watchPath[MAX_PATH];
watch_cb pCb;
uv_fs_event_t *uv_event;
UT_hash_handle hh; ///< UT Hash handle
} WATCH_CONTENT, *PWATCH_CONTENT;
PWATCH_CONTENT g_watchContent = NULL;
static void monitor_cb(uv_fs_event_t *handle, const char *filename, int events, int status) {
PWATCH_CONTENT pCtx = (PWATCH_CONTENT)handle->data;
char path[1024];
size_t size = 1023;
uv_fs_event_getpath(handle, path, &size);
path[size] = '\0';
if (pCtx && pCtx->pCb) {
pCtx->pCb(path, filename, events, pCtx->watchPath);
}
#if 1
fprintf(stderr, "Change detected in %s: ", path);
if (events & UV_RENAME) {
fprintf(stderr, "renamed");
}
if (events & UV_CHANGE) {
fprintf(stderr, "changed");
}
fprintf(stderr, " %s\n", filename ? filename : "");
#endif
}
int add_watch_path(const char *pFsPath, watch_cb cb) {
PWATCH_CONTENT pCtx;
if (cb == NULL || pFsPath == NULL || !file_exists(pFsPath)) {
LOG_MOD(debug, ZLOG_MOD_WATCH, "Watch path [%s] notify function <%p>\n", pFsPath ? pFsPath : "<NULL>", cb);
return -ERR_INPUT_PARAMS;
}
HASH_FIND_STR(g_watchContent, pFsPath, pCtx);
if (pCtx != NULL) {
return -ERR_ITEM_EXISTS;
}
pCtx = (PWATCH_CONTENT)malloc(sizeof(WATCH_CONTENT));
if (pCtx == NULL) {
LOG_MOD(error, ZLOG_MOD_WATCH, "Malloc memory error of %ld size\n", sizeof(WATCH_CONTENT));
return -ERR_MALLOC_MEMORY;
}
pCtx->uv_event = (uv_fs_event_t *)malloc(sizeof(uv_fs_event_t));
if (pCtx->uv_event == NULL) {
LOG_MOD(error, ZLOG_MOD_WATCH, "Malloc memory error of %ld size\n", sizeof(uv_fs_event_t));
free(pCtx);
return -ERR_MALLOC_MEMORY;
}
memset(pCtx, 0, sizeof(WATCH_CONTENT));
strcpy(pCtx->watchPath, pFsPath);
pCtx->pCb = cb;
pCtx->uv_event->data = pCtx;
uv_fs_event_init(get_task_manager(), pCtx->uv_event);
uv_fs_event_start(pCtx->uv_event, monitor_cb, pFsPath, UV_FS_EVENT_RECURSIVE);
HASH_ADD_STR(g_watchContent, watchPath, pCtx);
return ERR_SUCCESS;
}
int remove_watch_path(const char *pFsPath) {
PWATCH_CONTENT pCtx;
if (pFsPath == NULL || !file_exists(pFsPath)) {
LOG_MOD(debug, ZLOG_MOD_WATCH, "Remove Watch path [%s]\n", pFsPath ? pFsPath : "<NULL>");
return -ERR_INPUT_PARAMS;
}
HASH_FIND_STR(g_watchContent, pFsPath, pCtx);
if (pCtx != NULL) {
HASH_DEL(g_watchContent, pCtx);
uv_fs_event_stop(pCtx->uv_event);
free(pCtx->uv_event);
free(pCtx);
}
return ERR_SUCCESS;
}

174
srcs/libs/hardware/cpu.c Normal file
View File

@ -0,0 +1,174 @@
//
// Created by xajhu on 2021/7/6 0006.
//
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <uv.h>
#include "hardware.h"
#include "misc.h"
#include "user_errno.h"
#include "config.h"
#include "common.h"
typedef struct {
unsigned long cpuTotal;
unsigned long cpuIdle;
} CPU_TIME;
#define CMD_CPU_NUM ("cat /proc/cpuinfo| grep \"physical id\" | sort | uniq | wc -l")
#define CMD_CPU_CORE ("cat /proc/cpuinfo| grep \"cpu cores\" | uniq | awk \'{print $4}\'")
#define CMP_CPU_LOGIC_CORE ("cat /proc/cpuinfo| grep \"cpu cores\" | wc -l")
#define SUM_CPU_TIME(x) ((x).user + (x).nice + (x).sys + (x).idle + (x).irq)
static int g_isInit = FALSE;
static CPU_INFO g_cpuInfo;
static int get_cpu_info_cmd(const char *pCmd) {
char *pRet = NULL;
char *pOver;
long val;
if (shell_with_output(pCmd, &pRet) != ERR_SUCCESS || pRet == NULL || strlen(pRet) == 0) {
if (pRet) {
free(pRet);
}
return -ERR_CALL_SHELL;
}
errno = 0;
val = strtol(pRet, &pOver, 10);
free(pRet);
if (/*(pOver != NULL && strlen(pOver)) ||*/ errno != 0) {
return -ERR_STRING_TO_NUMBER;
}
return (int)val;
}
static int get_cpu_number() {
return get_cpu_info_cmd(CMD_CPU_NUM);
}
static int get_cpu_core_number() {
return get_cpu_info_cmd(CMD_CPU_CORE);
}
static int get_cpu_logic_core() {
return get_cpu_info_cmd(CMP_CPU_LOGIC_CORE);
}
int get_cpu_desc(PCPU_DESC pDesc) {
uv_cpu_info_t *pCpu = NULL;
int nCpu;
if (uv_cpu_info(&pCpu, &nCpu) != 0 || nCpu <= 0) {
if (pCpu) {
uv_free_cpu_info(pCpu, nCpu);
}
return -ERR_SYS_GET_CPU_INFO;
}
if (pDesc) {
memset(pDesc->cpuName, 0, MEM_VALUE_SIZE * 4);
strcpy(pDesc->cpuName, (pCpu[0].model));
pDesc->cpuSpeed = pCpu[0].speed;
}
uv_free_cpu_info(pCpu, nCpu);
return ERR_SUCCESS;
}
static int get_cpu_time_info(unsigned long *pTotal, unsigned long *pIdle) {
uv_cpu_info_t *pCpu = NULL;
int i, nCpu;
if (pTotal == NULL || pIdle == NULL) {
return -ERR_INPUT_PARAMS;
}
if (uv_cpu_info(&pCpu, &nCpu) != 0 || nCpu <= 0) {
if (pCpu) {
uv_free_cpu_info(pCpu, nCpu);
}
return -ERR_SYS_GET_CPU_INFO;
}
// 清零计算值
*pTotal = *pIdle = 0;
for (i = 0; i < nCpu; i++) {
*pIdle += pCpu[i].cpu_times.idle;
*pTotal += SUM_CPU_TIME(pCpu[i].cpu_times);
}
uv_free_cpu_info(pCpu, nCpu);
return ERR_SUCCESS;
}
static void cpuUsedRefresh() {
CPU_TIME beginTime, endTime;
memset(&beginTime, 0, sizeof(CPU_TIME));
memset(&endTime, 0, sizeof(CPU_TIME));
if (get_cpu_time_info(&beginTime.cpuTotal, &beginTime.cpuIdle) != ERR_SUCCESS) {
return;
}
// 延时 1s 后再获取1次CPU信息
uv_sleep(1000);
if (get_cpu_time_info(&endTime.cpuTotal, &endTime.cpuIdle) != ERR_SUCCESS) {
return;
} else {
uint64_t idle = endTime.cpuIdle - beginTime.cpuIdle;
uint64_t total = endTime.cpuTotal - beginTime.cpuTotal;
g_cpuInfo.cpuUsed = 1.0 - ((double)idle / (double)total);
g_cpuInfo.timestamp = time(NULL);
}
}
int cpu_watch_init() {
memset(&g_cpuInfo, 0, sizeof(CPU_INFO));
g_cpuInfo.nCpus = get_cpu_number();
g_cpuInfo.nLogicCores = get_cpu_logic_core();
g_cpuInfo.nCores = get_cpu_core_number();
g_cpuInfo.timestamp = time(NULL);
get_cpu_desc(&g_cpuInfo.cpuCoreDesc);
g_isInit = TRUE;
return ERR_SUCCESS;
}
int get_cpu_info(PCPU_INFO pInfo) {
if (pInfo == NULL) {
return -ERR_INPUT_PARAMS;
}
if (g_isInit == FALSE) {
memset(&g_cpuInfo, 0, sizeof(CPU_INFO));
g_cpuInfo.nCpus = get_cpu_number();
g_cpuInfo.nLogicCores = get_cpu_logic_core();
g_cpuInfo.nCores = get_cpu_core_number();
g_cpuInfo.timestamp = time(NULL);
get_cpu_desc(&g_cpuInfo.cpuCoreDesc);
g_isInit = TRUE;
} else if (cfg_get_watch_cpu()) {
cpuUsedRefresh();
}
memcpy(pInfo, &g_cpuInfo, sizeof(CPU_INFO));
return ERR_SUCCESS;
}

137
srcs/libs/hardware/disk.c Normal file
View File

@ -0,0 +1,137 @@
//
// Created by xajhu on 2021/7/6 0006.
//
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
#include <sds/sds.h>
#include "user_errno.h"
#include "hardware.h"
#include "uthash/uthash.h"
#include "config.h"
#include "common.h"
#define MAX_SIZE_LEN (16)
//#define CMD_DISK_FILESYSTEM ("df -h | awk \'{if (NR > 1){print $0}}\'")
#define CMD_DISK_FILESYSTEM ("df -h | awk \'{if (NR > 1){print $1\"|\"$2\"|\"$3\"|\"$4\"|\"$5\"|\"$6}}\'")
typedef struct {
char fileSystem[MAX_PATH];
char mntDevice[MAX_PATH];
char diskSize[MAX_SIZE_LEN];
char diskUsed[MAX_SIZE_LEN];
char diskFree[MAX_SIZE_LEN];
char diskUsedPercent[MAX_SIZE_LEN];
unsigned long timestamp;
UT_hash_handle hh;
} DISK_PART_INFO, *PDISK_PART_INFO;
static uv_rwlock_t g_uvLock;
static PDISK_PART_INFO g_diskPartInfo = NULL;
static int disk_info_refresh() {
int i = 0;
int errCode = ERR_SUCCESS;
FILE *fp;
char buf[MAX_PATH * 2];
fp = popen(CMD_DISK_FILESYSTEM, "r");
if (fp == NULL) {
return -ERR_OPEN_FILE;
}
while (fgets(buf, 1024, fp) != NULL && i < MAX_WATCH_DISK_DEVICE) {
int nItems;
sds tmpStr = sdsnew(buf);
sds *pToken = sdssplitlen(tmpStr, (int)sdslen(tmpStr), "|", 1, &nItems);
if (nItems == 6) {
PDISK_PART_INFO pTmp = NULL;
sdstrim(pToken[0], "\n");
sdstrim(pToken[1], "\n");
sdstrim(pToken[2], "\n");
sdstrim(pToken[3], "\n");
sdstrim(pToken[4], "\n");
sdstrim(pToken[5], "\n");
HASH_FIND_STR(g_diskPartInfo, pToken[5], pTmp);
if (pTmp) {
uv_rwlock_wrlock(&g_uvLock);
strcpy(pTmp->diskSize, pToken[1]);
strcpy(pTmp->diskFree, pToken[3]);
strcpy(pTmp->diskUsedPercent, pToken[4]);
pTmp->timestamp = time(NULL);
uv_rwlock_wrunlock(&g_uvLock);
} else {
pTmp = (PDISK_PART_INFO)malloc(sizeof(DISK_PART_INFO));
if (pTmp) {
uv_rwlock_wrlock(&g_uvLock);
strcpy(pTmp->fileSystem, pToken[0]);
strcpy(pTmp->diskSize, pToken[1]);
strcpy(pTmp->diskUsed, pToken[2]);
strcpy(pTmp->diskFree, pToken[3]);
strcpy(pTmp->diskUsedPercent, pToken[4]);
strcpy(pTmp->mntDevice, pToken[5]);
HASH_ADD_STR(g_diskPartInfo, mntDevice, pTmp);
uv_rwlock_wrunlock(&g_uvLock);
} else {
errCode = -ERR_MALLOC_MEMORY;
}
}
i++;
}
sdsfreesplitres(pToken, nItems);
sdsfree(tmpStr);
}
pclose(fp);
return errCode;
}
int get_disk_info(PDISK_INFO pInfo) {
PDISK_PART_INFO pItem, pTmp;
PDISK_PART_USED pDisk;
if (pInfo == NULL) {
return -ERR_INPUT_PARAMS;
}
if (cfg_get_watch_disk()) {
disk_info_refresh();
}
uv_rwlock_rdlock(&g_uvLock);
pInfo->nItems = HASH_COUNT(g_diskPartInfo);
pInfo->timestamp = time(NULL);
pDisk = pInfo->diskPartInfo;
HASH_ITER(hh, g_diskPartInfo, pItem, pTmp) {
pDisk->deviceName = pItem->mntDevice;
pDisk->diskSize = pItem->diskSize;
pDisk->diskUsed = pItem->diskUsed;
pDisk->usedPercent = pItem->diskUsedPercent;
pDisk++;
}
uv_rwlock_rdunlock(&g_uvLock);
return ERR_SUCCESS;
}
int disk_watch_info() {
uv_rwlock_init(&g_uvLock);
if (disk_info_refresh() != ERR_SUCCESS) {
return -ERR_SYS_DISK_GET_INFO;
}
return ERR_SUCCESS;
}

View File

@ -0,0 +1,168 @@
//
// Created by xajhu on 2021/7/6 0006.
//
#include <string.h>
#include <uv.h>
#include "s2j/s2j.h"
#include "hardware.h"
#include "user_errno.h"
#include "config.h"
#include "common.h"
#include "task_manager.h"
static HARDWARE_INFO g_hardwareInfo;
void hardwareRefreshCb(uv_timer_t *UNUSED(pArg)) {
if (cfg_get_watch_sensor()) {
get_sensor_info(&g_hardwareInfo.sensorInfo);
}
if (cfg_get_watch_disk()) {
get_disk_info(&g_hardwareInfo.diskInfo);
}
if (cfg_get_watch_cpu()) {
get_cpu_info(&g_hardwareInfo.cpuInfo);
}
if (cfg_get_watch_memory()) {
get_memory_info(&g_hardwareInfo.memInfo);
}
//printf("%s\n", get_hardware_json());
}
int init_hardware() {
static uv_timer_t uvTm;
unsigned int period = cfg_get_hardware_refresh_period();
if (period >= REFRESH_MAX_PERIOD) {
period = 10000;
} else {
period *= 1000;
}
uv_timer_init(get_task_manager(), &uvTm);
memset(&g_hardwareInfo, 0, sizeof(HARDWARE_INFO));
cpu_watch_init();
memory_watch_init();
disk_watch_info();
sensor_watch_init();
uv_timer_start(&uvTm, hardwareRefreshCb, period, period);
return ERR_SUCCESS;
}
/***************************************************************
* CPU_INFO json
***************************************************************/
static cJSON *struct_to_json_CPU_DESC(void *pObj) {
PCPU_DESC pCpuDesc = (PCPU_DESC)pObj; //&((PCPU_INFO)pObj)->cpuCoreDesc;
s2j_create_json_obj(pJsonObj);
s2j_json_set_basic_element(pJsonObj, pCpuDesc, int, cpuSpeed);
s2j_json_set_basic_element(pJsonObj, pCpuDesc, string, cpuName);
return pJsonObj;
}
static cJSON *struct_to_json_CPU_INFO(void *pObj) {
PCPU_INFO pCpuInfo = (PCPU_INFO)pObj; //&((PHARDWARE_INFO)pObj)->cpuInfo;
s2j_create_json_obj(pJsonObj);
s2j_json_set_basic_element(pJsonObj, pCpuInfo, int, nCores);
s2j_json_set_basic_element(pJsonObj, pCpuInfo, int, nLogicCores);
s2j_json_set_basic_element(pJsonObj, pCpuInfo, int, nCpus);
s2j_json_set_basic_element(pJsonObj, pCpuInfo, double, cpuUsed);
s2j_json_set_basic_element(pJsonObj, pCpuInfo, int, timestamp);
s2j_json_set_struct_element_by_func(pJsonObj, pCpuInfo, CPU_DESC, cpuCoreDesc);
return pJsonObj;
}
/***************************************************************
* MEMORY_INFO json
***************************************************************/
static cJSON *struct_to_json_MEMORY_INFO(void *pObj) {
PMEMORY_INFO pMemInfo = (PMEMORY_INFO)pObj;
s2j_create_json_obj(pJsonObj);
s2j_json_set_basic_element(pJsonObj, pMemInfo, string, cachedMemSize);
s2j_json_set_basic_element(pJsonObj, pMemInfo, string, bufferMemSize);
s2j_json_set_basic_element(pJsonObj, pMemInfo, string, availMemSize);
s2j_json_set_basic_element(pJsonObj, pMemInfo, string, freeMemSize);
s2j_json_set_basic_element(pJsonObj, pMemInfo, string, totalMemSize);
s2j_json_set_basic_element(pJsonObj, pMemInfo, int, timestamp);
return pJsonObj;
}
/***************************************************************
* DISK_INFO json
***************************************************************/
static cJSON *struct_to_json_DISK_PART_USED(void *pObj) {
PDISK_PART_USED pDisk = (PDISK_PART_USED)pObj;
s2j_create_json_obj(pJsonObj);
s2j_json_set_basic_element(pJsonObj, pDisk, string, deviceName);
s2j_json_set_basic_element(pJsonObj, pDisk, string, diskSize);
s2j_json_set_basic_element(pJsonObj, pDisk, string, diskUsed);
s2j_json_set_basic_element(pJsonObj, pDisk, string, usedPercent);
return pJsonObj;
}
static cJSON *struct_to_json_DISK_INFO(void *pObj) {
PDISK_INFO pDiskInfo = (PDISK_INFO)pObj;
s2j_create_json_obj(pJsonObj);
s2j_json_set_basic_element(pJsonObj, pDiskInfo, int, nItems);
s2j_json_set_basic_element(pJsonObj, pDiskInfo, int, timestamp);
s2j_json_set_struct_array_element_by_func(pJsonObj, pDiskInfo, DISK_PART_USED, diskPartInfo, pDiskInfo->nItems);
return pJsonObj;
}
/***************************************************************
* SENSOR_INFO json
***************************************************************/
static cJSON *struct_to_json_SENSOR_ITEM(void *pObj) {
PSENSOR_ITEM pSensor = (PSENSOR_ITEM)pObj;
s2j_create_json_obj(pJsonObj);
s2j_json_set_basic_element(pJsonObj, pSensor, string, sensorName);
s2j_json_set_basic_element(pJsonObj, pSensor, string, value);
s2j_json_set_basic_element(pJsonObj, pSensor, string, unit);
s2j_json_set_basic_element(pJsonObj, pSensor, string, status);
return pJsonObj;
}
static cJSON *struct_to_json_SENSOR_INFO(void *pObj) {
PSENSOR_INFO pSensorInfo = (PSENSOR_INFO)pObj;
s2j_create_json_obj(pJsonObj);
s2j_json_set_basic_element(pJsonObj, pSensorInfo, int, nItems);
s2j_json_set_basic_element(pJsonObj, pSensorInfo, int, timestamp);
s2j_json_set_struct_array_element_by_func(pJsonObj, pSensorInfo, SENSOR_ITEM, sensorInfo, pSensorInfo->nItems);
return pJsonObj;
}
const char *get_hardware_json() {
const char *pJsonStr;
s2j_create_json_obj(pJsonObj);
s2j_json_set_struct_element_by_func(pJsonObj, &g_hardwareInfo, CPU_INFO, cpuInfo);
s2j_json_set_struct_element_by_func(pJsonObj, &g_hardwareInfo, MEMORY_INFO, memInfo);
s2j_json_set_struct_element_by_func(pJsonObj, &g_hardwareInfo, DISK_INFO, diskInfo);
s2j_json_set_struct_element_by_func(pJsonObj, &g_hardwareInfo, SENSOR_INFO, sensorInfo);
pJsonStr = cJSON_Print(pJsonObj);
cJSON_Delete(pJsonObj);
return pJsonStr;
}

View File

@ -0,0 +1,187 @@
//
// Created by xajhu on 2021/7/8 0008.
//
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
#include <sds/sds.h>
#include "hardware.h"
#include "user_errno.h"
#include "uthash/uthash.h"
#include "misc.h"
#include "common.h"
#include "config.h"
#define MAX_SENSOR_STR (32)
//#define CMD_SENSOR_INFO ("ipmitool sensor | awk '{gsub(/\|/, \"\"); print $0}'")
#define CMD_SENSOR_INFO ("ipmitool sensor")
#define CMD_IPMITOOL_ENABLE ("whereis ipmitool | awk '{print $2}'")
typedef struct {
char name[MAX_SENSOR_STR]; ///< 传感器名称
char valUnit[MAX_SENSOR_STR]; ///< 传感器值单位
char value[MAX_SENSOR_STR]; ///< 传感器值, >=0: 正常值, <0: 错误码
char lnr[MAX_SENSOR_STR]; ///< Lower Non-Recoverable
char lc[MAX_SENSOR_STR]; ///< Lower Critical
char lnc[MAX_SENSOR_STR]; ///< Lower Non-Critical
char unc[MAX_SENSOR_STR]; ///< Upper Non-Critical
char uc[MAX_SENSOR_STR]; ///< Upper Critical
char unr[MAX_SENSOR_STR]; ///< Upper Non-Critical
char status[MAX_SENSOR_STR]; ///< 设备状态 0: failed, 1: Ok, and other
unsigned long timestamp; ///< 更新时间戳
UT_hash_handle hh;
} IPMI_SENSOR_INFO, *PIPMI_SENSOR_INFO;
static const char *g_ipmiDev[] = {"/dev/ipmi0", "/dev/ipmi/0", "/dev/ipmidev/0"};
static uv_rwlock_t g_uvLock;
static PIPMI_SENSOR_INFO g_pSensorInfo = NULL;
static int sensor_info_refresh() {
int i = 0;
int errCode = ERR_SUCCESS;
FILE *fp;
char buf[1024];
char *pRet = NULL;
if (shell_with_output(CMD_IPMITOOL_ENABLE, &pRet) != ERR_SUCCESS || pRet == NULL || strlen(pRet) == 0) {
if (pRet) {
free(pRet);
}
return -ERR_ITEM_UNEXISTS;
}
fp = popen(CMD_SENSOR_INFO, "r");
if (fp == NULL) {
return -ERR_OPEN_FILE;
}
while (fgets(buf, 1024, fp) != NULL && i < MAX_SENSOR_ITEMS) {
int nItems;
sds tmpStr = sdsnew(buf);
sds *pToken = sdssplitlen(tmpStr, (int)sdslen(tmpStr), "|", 1, &nItems);
if (nItems == 10) {
PIPMI_SENSOR_INFO pTmp = NULL;
sdstrim(pToken[0], " \n");
sdstrim(pToken[1], " \n");
sdstrim(pToken[2], " \n");
sdstrim(pToken[3], " \n");
sdstrim(pToken[4], " \n");
sdstrim(pToken[5], " \n");
sdstrim(pToken[6], " \n");
sdstrim(pToken[7], " \n");
sdstrim(pToken[8], " \n");
sdstrim(pToken[9], " \n");
HASH_FIND_STR(g_pSensorInfo, pToken[0], pTmp);
if (pTmp) {
uv_rwlock_wrlock(&g_uvLock);
strcpy(pTmp->value, pToken[1]);
strcpy(pTmp->valUnit, pToken[2]);
strcpy(pTmp->status, pToken[3]);
pTmp->timestamp = time(NULL);
uv_rwlock_wrunlock(&g_uvLock);
} else {
pTmp = (PIPMI_SENSOR_INFO)malloc(sizeof(IPMI_SENSOR_INFO));
if (pTmp) {
uv_rwlock_wrlock(&g_uvLock);
strcpy(pTmp->name, pToken[0]);
strcpy(pTmp->value, pToken[1]);
strcpy(pTmp->valUnit, pToken[2]);
strcpy(pTmp->status, pToken[3]);
strcpy(pTmp->lnr, pToken[4]);
strcpy(pTmp->lc, pToken[5]);
strcpy(pTmp->lnc, pToken[6]);
strcpy(pTmp->unc, pToken[7]);
strcpy(pTmp->uc, pToken[8]);
strcpy(pTmp->unr, pToken[9]);
HASH_ADD_STR(g_pSensorInfo, name, pTmp);
uv_rwlock_wrunlock(&g_uvLock);
} else {
errCode = -ERR_MALLOC_MEMORY;
}
}
i++;
#if 0
printf("name: [%s]\n", pTmp->name);
printf("value: [%s]\n", pTmp->value);
printf("valUnit: [%s]\n", pTmp->valUnit);
printf("status: [%s]\n", pTmp->status);
printf("lnr: [%s]\n", pTmp->lnr);
printf("lc: [%s]\n", pTmp->lc);
printf("lnc: [%s]\n", pTmp->lnc);
printf("unc: [%s]\n", pTmp->unc);
printf("uc: [%s]\n", pTmp->uc);
printf("unr: [%s]\n\n\n", pTmp->unr);
#endif
}
sdsfreesplitres(pToken, nItems);
sdsfree(tmpStr);
memset(buf, 0, sizeof(buf));
}
pclose(fp);
return errCode;
}
int get_sensor_info(PSENSOR_INFO pInfo) {
PIPMI_SENSOR_INFO pItem, pTmp;
PSENSOR_ITEM pSensor;
if (pInfo == NULL) {
return -ERR_INPUT_PARAMS;
}
if (cfg_get_watch_sensor()) {
sensor_info_refresh();
}
uv_rwlock_rdlock(&g_uvLock);
pInfo->nItems = HASH_COUNT(g_pSensorInfo);
pInfo->timestamp = time(NULL);
pSensor = pInfo->sensorInfo;
HASH_ITER(hh, g_pSensorInfo, pItem, pTmp) {
pSensor->sensorName = pItem->name;
pSensor->value = pItem->value;
pSensor->unit = pItem->valUnit;
pSensor->status = pItem->status;
pSensor++;
}
uv_rwlock_rdunlock(&g_uvLock);
return ERR_SUCCESS;
}
int sensor_watch_init() {
int i, devOk = FALSE;
int n = ARRAY_SIZE(g_ipmiDev);
uv_rwlock_init(&g_uvLock);
for (i = 0; i < n; i++) {
if (file_exists(g_ipmiDev[i])) {
devOk = TRUE;
break;
}
}
if (!devOk) {
return -ERR_SYS_IPMI_UNSUP;
}
if (sensor_info_refresh() != ERR_SUCCESS) {
return -ERR_SYS_SENSOR_GET_INFO;
}
return ERR_SUCCESS;
}

164
srcs/libs/hardware/memory.c Normal file
View File

@ -0,0 +1,164 @@
//
// Created by xajhu on 2021/7/6 0006.
//
#include <stdlib.h>
#include <uv.h>
#include <string.h>
#include <sds/sds.h>
#include "hardware.h"
#include "user_errno.h"
#include "uthash/uthash.h"
#include "common.h"
#include "config.h"
#define CMD_MEMORY_INFO ("cat /proc/meminfo | awk \'{print $1\"|\"$2\"|\"$3}\'")
#define M_SIZE (1024 * 1024)
#define KEY_NAME (32)
#define KEY_VALUE (32)
#define VALUE_UNIT (8)
typedef struct {
char itemName[KEY_NAME];
char itemValue[KEY_VALUE];
char valUnit[VALUE_UNIT];
unsigned long timestamp;
UT_hash_handle hh;
} KERNEL_MEM_INFO, *PKERNEL_MEM_INFO;
static uv_rwlock_t g_uvLock;
static PKERNEL_MEM_INFO g_pMemInfo = NULL;
static const char *g_memKeyName[] = {"MemTotal", "MemFree", "MemAvailable", "Buffers", "Cached"};
unsigned int get_sys_free_memory() {
return uv_get_free_memory() / M_SIZE;
}
unsigned int get_sys_total_memory() {
return uv_get_total_memory() / M_SIZE;
}
static int memory_info_refresh() {
int errCode = ERR_SUCCESS;
FILE *fp;
char buf[MAX_PATH * 2];
fp = popen(CMD_MEMORY_INFO, "r");
if (fp == NULL) {
return -ERR_OPEN_FILE;
}
while (fgets(buf, 1024, fp) != NULL) {
int nItems;
sds tmpStr = sdsnew(buf);
sds *pToken = sdssplitlen(tmpStr, (int)sdslen(tmpStr), "|", 1, &nItems);
if (nItems == 3) {
PKERNEL_MEM_INFO pTmp = NULL;
HASH_FIND_STR(g_pMemInfo, pToken[0], pTmp);
if (pTmp) {
uv_rwlock_wrlock(&g_uvLock);
strcpy(pTmp->itemName, sdstrim(pToken[0], ": \n"));
strcpy(pTmp->itemValue, sdstrim(pToken[1], " \n"));
strcpy(pTmp->valUnit, sdstrim(pToken[2], " \n"));
pTmp->timestamp = time(NULL);
uv_rwlock_wrunlock(&g_uvLock);
} else {
pTmp = (PKERNEL_MEM_INFO)malloc(sizeof(KERNEL_MEM_INFO));
if (pTmp) {
uv_rwlock_wrlock(&g_uvLock);
strcpy(pTmp->itemName, sdstrim(pToken[0], ": \n"));
strcpy(pTmp->itemValue, sdstrim(pToken[1], " \n"));
strcpy(pTmp->valUnit, sdstrim(pToken[2], " \n"));
pTmp->timestamp = time(NULL);
HASH_ADD_STR(g_pMemInfo, itemName, pTmp);
uv_rwlock_wrunlock(&g_uvLock);
} else {
errCode = -ERR_MALLOC_MEMORY;
}
}
}
sdsfreesplitres(pToken, nItems);
sdsfree(tmpStr);
}
pclose(fp);
return errCode;
}
int memory_watch_init() {
uv_rwlock_init(&g_uvLock);
if (memory_info_refresh() != ERR_SUCCESS) {
return -ERR_SYS_DISK_GET_INFO;
}
return ERR_SUCCESS;
}
#define MEM_VALUE_SET(dst, src) \
do { \
if ((src) == NULL) \
continue; \
if ((src)->valUnit && strlen((src)->valUnit) > 0) { \
sprintf(dst, "%s %s", (src)->itemValue, (src)->valUnit); \
} else { \
sprintf(dst, "%s", (src)->itemValue); \
} \
} while (0)
int get_memory_info(PMEMORY_INFO pInfo) {
int i, n = ARRAY_SIZE(g_memKeyName);
if (pInfo == NULL) {
return -ERR_INPUT_PARAMS;
}
if (cfg_get_watch_memory()) {
memory_info_refresh();
}
uv_rwlock_rdlock(&g_uvLock);
for (i = 0; i < n; i++) {
PKERNEL_MEM_INFO pTmp = NULL;
HASH_FIND_STR(g_pMemInfo, g_memKeyName[i], pTmp);
if (pTmp) {
switch (i) {
case 0:
MEM_VALUE_SET(pInfo->totalMemSize, pTmp);
break;
case 1:
MEM_VALUE_SET(pInfo->freeMemSize, pTmp);
break;
case 2:
MEM_VALUE_SET(pInfo->availMemSize, pTmp);
break;
case 3:
MEM_VALUE_SET(pInfo->bufferMemSize, pTmp);
break;
case 4:
MEM_VALUE_SET(pInfo->cachedMemSize, pTmp);
break;
default:
continue;
}
}
}
uv_rwlock_rdunlock(&g_uvLock);
pInfo->timestamp = time(NULL);
return ERR_SUCCESS;
}

View File

@ -0,0 +1,8 @@
//
// Created by xajhu on 2021/6/29 0029.
//
#ifndef DAEMON_AGENT__AGENT_MAIN_H
#define DAEMON_AGENT__AGENT_MAIN_H
#endif //DAEMON_AGENT__AGENT_MAIN_H

View File

@ -0,0 +1,18 @@
//
// Created by xajhu on 2021/6/29 0029.
//
#ifndef DAEMON_AGENT_BANNER_BANNER_H
#define DAEMON_AGENT_BANNER_BANNER_H
#ifdef __cplusplus
extern "C" {
#endif
#define BANNER_FILE "config/banner.txt"
void banner_show();
#ifdef __cplusplus
}
#endif
#endif //DAEMON_AGENT_BANNER_BANNER_H

View File

@ -0,0 +1,271 @@
//
// Created by xajhuang on 2023/4/6.
//
#ifndef BITSET_H
#define BITSET_H
#include <common.h>
#ifdef __cplusplus
extern "C" {
#endif
// For compatibility with MSVC with the use of `restrict`
#if (__STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && defined(__STDC_VERSION__))
#define CBITSET_RESTRICT restrict
#else
#define CBITSET_RESTRICT
#endif // (__STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && defined(__STDC_VERSION__ ))
struct bitset_s {
uint64_t *CBITSET_RESTRICT array;
size_t arraysize;
size_t capacity;
};
typedef struct bitset_s bitset_t;
/* Create a new bitset. Return NULL in case of failure. */
bitset_t *bitset_create(void);
/* Create a new bitset able to contain size bits. Return NULL in case of failure. */
bitset_t *bitset_create_with_capacity(size_t size);
/* Free memory. */
void bitset_free(bitset_t *bitset);
/* Set all bits to zero. */
void bitset_clear(bitset_t *bitset);
/* Create a copy */
bitset_t *bitset_copy(const bitset_t *bitset);
/* Resize the bitset. Return TRUE in case of success, FALSE for failure. Pad with zeroes new buffer areas if requested. */
int bitset_resize(bitset_t *bitset, size_t newarraysize, int padwithzeroes);
/* returns how many bytes of memory the backend buffer uses */
static inline size_t bitset_size_in_bytes(const bitset_t *bitset) {
return bitset->arraysize * sizeof(uint64_t);
}
/* returns how many bits can be accessed */
static inline size_t bitset_size_in_bits(const bitset_t *bitset) {
return bitset->arraysize * 64;
}
/* returns how many words (64-bit) of memory the backend buffer uses */
static inline size_t bitset_size_in_words(const bitset_t *bitset) {
return bitset->arraysize;
}
/* Grow the bitset so that it can support newarraysize * 64 bits with padding. Return TRUE in case of success, FALSE for failure. */
static inline int bitset_grow(bitset_t *bitset, size_t newarraysize) {
if (bitset->capacity < newarraysize) {
uint64_t *newarray;
bitset->capacity = newarraysize * 2;
if ((newarray = (uint64_t *)realloc(bitset->array, sizeof(uint64_t) * bitset->capacity)) == NULL) {
free(bitset->array);
return FALSE;
}
bitset->array = newarray;
}
memset(bitset->array + bitset->arraysize, 0, sizeof(uint64_t) * (newarraysize - bitset->arraysize));
bitset->arraysize = newarraysize;
return TRUE; // success!
}
/* attempts to recover unused memory, return FALSE in case of reallocation failure */
int bitset_trim(bitset_t *bitset);
/* shifts all bits by 's' positions so that the bitset representing values 1,2,10 would represent values 1+s, 2+s, 10+s */
void bitset_shift_left(bitset_t *bitset, size_t s);
/* shifts all bits by 's' positions so that the bitset representing values 1,2,10 would represent values 1-s, 2-s, 10-s, negative values are deleted */
void bitset_shift_right(bitset_t *bitset, size_t s);
/* Set the ith bit. Attempts to resize the bitset if needed (may silently fail) */
static inline void bitset_set(bitset_t *bitset, size_t i) {
size_t shiftedi = i >> 6;
if (shiftedi >= bitset->arraysize) {
if (!bitset_grow(bitset, shiftedi + 1)) {
return;
}
}
bitset->array[shiftedi] |= ((uint64_t)1) << (i % 64);
}
/* Set the ith bit to the specified value. Attempts to resize the bitset if needed (may silently fail) */
static inline void bitset_set_to_value(bitset_t *bitset, size_t i, int flag) {
size_t shiftedi = i >> 6;
uint64_t mask = ((uint64_t)1) << (i % 64);
uint64_t dynmask = ((uint64_t)flag) << (i % 64);
if (shiftedi >= bitset->arraysize) {
if (!bitset_grow(bitset, shiftedi + 1)) {
return;
}
}
uint64_t w = bitset->array[shiftedi];
w &= ~mask;
w |= dynmask;
bitset->array[shiftedi] = w;
}
static inline void bitset_cls_bit(bitset_t *bitset, size_t i) {
bitset_set_to_value(bitset, i, 0);
}
/* Get the value of the ith bit. */
static inline int bitset_get(const bitset_t *bitset, size_t i) {
size_t shiftedi = i >> 6;
if (shiftedi >= bitset->arraysize) {
return FALSE;
}
return (bitset->array[shiftedi] & (((uint64_t)1) << (i % 64))) != 0;
}
/* Count number of bits set. */
size_t bitset_count(const bitset_t *bitset);
/* Find the index of the first bit set. */
size_t bitset_minimum(const bitset_t *bitset);
/* Find the index of the last bit set. */
size_t bitset_maximum(const bitset_t *bitset);
/* compute the union in-place (to b1), returns TRUE if successful, to generate a new bitset first call bitset_copy */
int bitset_inplace_union(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* report the size of the union (without materializing it) */
size_t bitset_union_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* compute the intersection in-place (to b1), to generate a new bitset first call bitset_copy */
void bitset_inplace_intersection(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* report the size of the intersection (without materializing it) */
size_t bitset_intersection_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* returns TRUE if the bitsets contain no common elements */
int bitsets_disjoint(const bitset_t *b1, const bitset_t *b2);
/* returns TRUE if the bitsets contain any common elements */
int bitsets_intersect(const bitset_t *b1, const bitset_t *b2);
/* returns TRUE if b1 contains all the set bits of b2 */
int bitset_contains_all(const bitset_t *b1, const bitset_t *b2);
/* compute the difference in-place (to b1), to generate a new bitset first call bitset_copy */
void bitset_inplace_difference(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* compute the size of the difference */
size_t bitset_difference_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* compute the symmetric difference in-place (to b1), return TRUE if successful, to generate a new bitset first call bitset_copy */
int bitset_inplace_symmetric_difference(bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* compute the size of the symmetric difference */
size_t bitset_symmetric_difference_count(const bitset_t *CBITSET_RESTRICT b1, const bitset_t *CBITSET_RESTRICT b2);
/* iterate over the set bits
like so :
for(size_t i = 0; nextSetBit(b,&i) ; i++) {
//.....
}
*/
static inline int nextSetBit(const bitset_t *bitset, size_t *i) {
size_t x = *i >> 6;
if (x >= bitset->arraysize) {
return FALSE;
}
uint64_t w = bitset->array[x];
w >>= (*i & 63);
if (w != 0) {
*i += __builtin_ctzll(w);
return TRUE;
}
x++;
while (x < bitset->arraysize) {
w = bitset->array[x];
if (w != 0) {
*i = x * 64 + __builtin_ctzll(w);
return TRUE;
}
x++;
}
return FALSE;
}
/* Iterate over the set bits
like so :
size_t buffer[256];
size_t howmany = 0;
for(size_t startfrom = 0; (howmany = nextSetBits(b,buffer,256, &startfrom)) > 0 ; startfrom++) {
//.....
}
*/
static inline size_t nextSetBits(const bitset_t *bitset, size_t *buffer, size_t capacity, size_t *startfrom) {
if (capacity == 0) {
return 0; // sanity check
}
size_t x = *startfrom >> 6;
if (x >= bitset->arraysize) {
return 0; // nothing more to iterate over
}
uint64_t w = bitset->array[x];
w >>= (*startfrom & 63);
size_t howmany = 0;
size_t base = x << 6;
while (howmany < capacity) {
while (w != 0) {
uint64_t t = w & (~w + 1);
int r = __builtin_ctzll(w);
buffer[howmany++] = r + base;
if (howmany == capacity) {
goto end;
}
w ^= t;
}
x += 1;
if (x == bitset->arraysize) {
break;
}
base += 64;
w = bitset->array[x];
}
end:
if (howmany > 0) {
*startfrom = buffer[howmany - 1];
}
return howmany;
}
typedef int (*bitset_iterator)(size_t value, void *param);
// return TRUE if uninterrupted
static inline int bitset_for_each(const bitset_t *b, bitset_iterator iterator, void *ptr) {
size_t base = 0;
for (size_t i = 0; i < b->arraysize; ++i) {
uint64_t w = b->array[i];
while (w != 0) {
uint64_t t = w & (~w + 1);
int r = __builtin_ctzll(w);
if (!iterator(r + base, ptr)) {
return FALSE;
}
w ^= t;
}
base += 64;
}
return TRUE;
}
//static inline void bitset_print(const bitset_t *b) {
// printf("{");
// for (size_t i = 0; nextSetBit(b, &i); i++) {
// printf("%zu, ", i);
// }
// printf("}");
//}
#ifdef __cplusplus
}
#endif
#endif //BITSET_H

Some files were not shown because too many files have changed in this diff Show More