opkg update
-[ -n "${CI_HELPER:=''}" ] || CI_HELPER="/ci/.github/workflows/ci_helpers.sh"
+export CI_HELPER="/ci/.github/workflows/ci_helpers.sh"
for PKG in /ci/*.ipk; do
tar -xzOf "$PKG" ./control.tar.gz | tar xzf - ./control
continue
fi
- export PKG_NAME PKG_VERSION CI_HELPER
+ export PKG_NAME PKG_VERSION
if [ -f "$PRE_TEST_SCRIPT" ]; then
echo "Use package specific pre-test.sh"
fi
subject="$(git show -s --format=%s $commit)"
- if echo "$subject" | grep -q -e '^[0-9A-Za-z,+/_-]\+: ' -e '^Revert '; then
+ if echo "$subject" | grep -q -e '^[0-9A-Za-z,+/_-]\+: ' -e '^Revert ' -e '^CONTRIBUTING.md' -e '^README.md'; then
success "Commit subject line seems ok ($subject)"
else
err "Commit subject line MUST start with '<package name>: ' ($subject)"
echo "$EOF" >> $GITHUB_ENV
- name: Build
- uses: openwrt/gh-action-sdk@v5
+ uses: openwrt/gh-action-sdk@v7
env:
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
FEEDNAME: packages_ci
INDEX: 1
KEY_BUILD: ${{ env.KEY_BUILD }}
+ V: s
- name: Move created packages to project dir
+ if: always()
run: cp bin/packages/${{ matrix.arch }}/packages_ci/* . || true
- name: Collect metadata
+ if: always()
run: |
MERGE_ID=$(git rev-parse --short HEAD)
echo "MERGE_ID=$MERGE_ID" >> $GITHUB_ENV
echo "ARCHIVE_NAME=${{matrix.arch}}-PR$PRNUMBER-$MERGE_ID" >> $GITHUB_ENV
- name: Generate metadata
+ if: always()
run: |
cat << _EOF_ > PKG-INFO
Metadata-Version: 2.1
cat PKG-INFO
- name: Store packages
+ if: always()
uses: actions/upload-artifact@v3
with:
name: ${{env.ARCHIVE_NAME}}-packages
PKG-INFO
- name: Store logs
+ if: always()
uses: actions/upload-artifact@v3
with:
name: ${{env.ARCHIVE_NAME}}-logs
PKG-INFO
- name: Remove logs
+ if: always()
run: sudo rm -rf logs/ || true
- name: Check if any packages were built
OpenWrt version and therefore includes the `PKG_RELEASE`, which isn't usually
part of the running programs version.
-The following snippet show a script that tests different binaries, depending
+The following snippet shows a script that tests different binaries depending on
what IPK package was installed. The `gpsd` Makefile produces both a `gpsd` and
-a `gpsd-clients` IPK package.
+a `gpsd-clients` IPK packages.
```shell
#!/bin/sh
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
include ../../lang/rust/rust-package.mk
include $(TOPDIR)/rules.mk
PKG_NAME:=zabbix
-PKG_VERSION:=6.2.3
-PKG_RELEASE:=3
+PKG_VERSION:=6.4.7
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://cdn.zabbix.com/zabbix/sources/stable/$(basename $(PKG_VERSION))/ \
https://cdn.zabbix.com/zabbix/sources/oldstable/$(basename $(PKG_VERSION))/
-PKG_HASH:=2be7e57fb33a55fee71480598e317ffa6a8ee5a39639a7e1b42b2ea6872107b5
+PKG_HASH:=6b4e81f07de4c82c7994871bea51be4d6427683fa9a7fbe112fd7559b3670e49
PKG_MAINTAINER:=Etienne CHAMPETIER <champetier.etienne@gmail.com>
PKG_LICENSE:=GPL-2.0
TITLE:=Zabbix
URL:=https://www.zabbix.com/
USERID:=zabbix=53:zabbix=53
- DEPENDS+=$(ICONV_DEPENDS) +libpcre +zlib
+ DEPENDS+=$(ICONV_DEPENDS) +libpcre2 +zlib
endef
define Package/zabbix-agentd
+ZABBIX_MYSQL:libmariadbclient \
@(!ZABBIX_SQLITE) \
+libevent2 \
+ +libevent2-pthreads \
+fping
endef
+ZABBIX_MYSQL:libmariadbclient \
+ZABBIX_SQLITE:libsqlite3 \
+libevent2 \
+ +libevent2-pthreads \
+fping
endef
$(if $(CONFIG_ZABBIX_MYSQL),--with-mysql) \
$(if $(CONFIG_ZABBIX_POSTGRESQL),--with-postgresql) \
$(if $(CONFIG_ZABBIX_SQLITE),--with-sqlite3=$(STAGING_DIR)/usr) \
- --with-libevent=$(STAGING_DIR)/usr/include/libevent \
- --with-libpcre=$(STAGING_DIR)/usr/include \
+ --with-libevent=$(STAGING_DIR)/usr/include \
+ --with-libpcre2=$(STAGING_DIR)/usr/include \
--with-zlib=$(STAGING_DIR)/usr/include
ifeq ($(BUILD_VARIANT),openssl)
---- a/src/libs/zbxcommon/str.c
-+++ b/src/libs/zbxcommon/str.c
-@@ -49,7 +49,7 @@ static const char help_message_footer[]
+--- a/src/libs/zbxcommon/misc.c
++++ b/src/libs/zbxcommon/misc.c
+@@ -329,7 +329,7 @@ void zbx_help(void)
void zbx_version(void)
{
printf("%s (Zabbix) %s\n", title_message, ZABBIX_VERSION);
include $(TOPDIR)/rules.mk
GO_VERSION_MAJOR_MINOR:=1.21
-GO_VERSION_PATCH:=2
+GO_VERSION_PATCH:=5
PKG_NAME:=golang
PKG_VERSION:=$(GO_VERSION_MAJOR_MINOR)$(if $(GO_VERSION_PATCH),.$(GO_VERSION_PATCH))
PKG_SOURCE:=go$(PKG_VERSION).src.tar.gz
PKG_SOURCE_URL:=$(GO_SOURCE_URLS)
-PKG_HASH:=45e59de173baec39481854490d665b726cec3e5b159f6b4172e5ec7780b2c201
+PKG_HASH:=285cbbdf4b6e6e62ed58f370f3f6d8c30825d6e56c5853c66d3c23bcdb09db19
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=BSD-3-Clause
include $(TOPDIR)/rules.mk
PKG_NAME:=lua-eco
-PKG_VERSION:=3.0.1
+PKG_VERSION:=3.1.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL=https://github.com/zhaojh329/lua-eco/releases/download/v$(PKG_VERSION)
-PKG_HASH:=96f008932e319739df2fe99dc1cba7e9a1a389015a4b96ad0f63d95bb6422b09
+PKG_HASH:=bb48af3f65a2c5d69b06b32ec2734bcb77cc6315b208be4fe3b0ae5fc0a82a33
PKG_MAINTAINER:=Jianhui Zhao <zhaojh329@gmail.com>
PKG_LICENSE:=MIT
Package/lua-eco-netlink=$(call Package/lua-eco/Module,netlink,+lua-eco-socket)
Package/lua-eco-ip=$(call Package/lua-eco/Module,ip utils,+lua-eco-netlink)
Package/lua-eco-nl80211=$(call Package/lua-eco/Module,nl80211,+lua-eco-netlink)
+Package/lua-eco-ssh=$(call Package/lua-eco/Module,ssh,+lua-eco-socket +libssh2)
define Package/lua-eco-ssl/config
choice
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nl80211.so $(1)/usr/local/lib/lua/5.3/eco/core
endef
+define Package/lua-eco-ssh/install
+ $(INSTALL_DIR) $(1)/usr/local/lib/lua/5.3/eco/core
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/ssh.lua $(1)/usr/local/lib/lua/5.3/eco
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ssh.so $(1)/usr/local/lib/lua/5.3/eco/core
+endef
+
$(eval $(call BuildPackage,lua-eco))
$(eval $(call BuildPackage,lua-eco-log))
$(eval $(call BuildPackage,lua-eco-base64))
$(eval $(call BuildPackage,lua-eco-netlink))
$(eval $(call BuildPackage,lua-eco-ip))
$(eval $(call BuildPackage,lua-eco-nl80211))
+$(eval $(call BuildPackage,lua-eco-ssh))
include $(TOPDIR)/rules.mk
PKG_NAME:=luajit2
-PKG_VERSION:=2.1-20230410
+PKG_VERSION:=2.1-20231117
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/openresty/luajit2/archive/refs/tags/v$(PKG_VERSION).tar.gz?
-PKG_HASH:=77bbcbb24c3c78f51560017288f3118d995fe71240aa379f5818ff6b166712ff
+PKG_HASH:=cc92968c57c00303eb9eaebf65cc8b29a0f851670f16bb514896ab5057ae381f
PKG_MAINTAINER:=Javier Marcet <javier@marcet.info>
PKG_LICENSE:=MIT
-#define LUA_LUADIR "/lua/5.1/"
+#define LUA_LROOT "/usr"
+#define LUA_LUADIR "/lua/"
- #define LUA_LJDIR "/luajit-2.1.0-beta3/"
+ #define LUA_LJDIR "/luajit-2.1/"
#ifdef LUA_ROOT
+++ /dev/null
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2023 Luca Barbato
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=maturin
-PKG_VERSION:=0.14.15
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/PyO3/maturin/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=60cbf8ff73a36333c3f5483ca679a52169839db381f06683d8e61a6c00c28cf7
-
-PKG_MAINTAINER:=Luca Barbato <lu_zero@luminem.org>
-PKG_LICENSE:=Apache-2.0 MIT
-PKG_LICENSE_FILES:=license-apache license-mit
-
-HOST_BUILD_DEPENDS:=rust/host
-PKG_HOST_ONLY:=1
-
-include $(INCLUDE_DIR)/host-build.mk
-include $(INCLUDE_DIR)/package.mk
-include ../rust/rust-host-build.mk
-
-define Package/maturin
- SECTION:=lang
- CATEGORY:=Languages
- SUBMENU:=Rust
- TITLE:=Build and publish crates as python packages
- DEPENDS:=$(RUST_ARCH_DEPENDS)
- URL:=https://maturin.rs
-endef
-
-define Package/maturin/description
- Build and publish crates with pyo3, rust-cpython, cffi and uniffi
- bindings as well as rust binaries as python packages.
-endef
-
-$(eval $(call RustBinHostBuild))
-$(eval $(call HostBuild))
-$(eval $(call BuildPackage,maturin))
include $(TOPDIR)/rules.mk
PKG_NAME:=node
-PKG_VERSION:=v18.18.0
+PKG_VERSION:=v20.10.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://nodejs.org/dist/$(PKG_VERSION)
-PKG_HASH:=e4d4dbac3634d99f892f00db47da78f98493c339582e8a95fb2dd59f5cfe0f90
+PKG_HASH:=32eb256eebd8cacd5574e6631e54b42be7ec8ebe25ad47a8ca685403bad15535
PKG_MAINTAINER:=Hirokazu MORIKAWA <morikw2@gmail.com>, Adrian Panella <ianchi74@outlook.com>
PKG_LICENSE:=MIT
PKG_BUILD_DEPENDS:=python3/host
PKG_BUILD_PARALLEL:=1
PKG_INSTALL:=1
-PKG_BUILD_FLAGS:=no-mips16
PKG_ASLR_PIE:=0
include $(INCLUDE_DIR)/host-build.mk
SUBMENU:=Node.js
TITLE:=Node.js is a platform built on Chrome's JavaScript runtime
URL:=https://nodejs.org/
- DEPENDS:=@HAS_FPU @(i386||x86_64||arm||aarch64||mipsel) \
- +libstdcpp +libopenssl +zlib +libnghttp2 +libuv \
+ DEPENDS:=@HAS_FPU @(i386||x86_64||arm||aarch64) \
+ +libstdcpp +libopenssl +zlib +libnghttp2 \
+libcares +libatomic +NODEJS_ICU_SYSTEM:icu +NODEJS_ICU_SYSTEM:icu-full-data
endef
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses
an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js'
package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
+
*** The following preparations must be made on the host side. ***
- 1. gcc 8.3 or higher is required.
+ 1. gcc 10.1 or higher is required.
2. To build a 32-bit target, gcc-multilib, g++-multilib are required.
3. Requires libatomic package. (If necessary, install the 32-bit library at the same time.)
ex) sudo apt-get install gcc-multilib g++-multilib
--shared-zlib \
--shared-openssl \
--shared-nghttp2 \
- --shared-libuv \
--shared-cares \
--with-intl=$(if $(CONFIG_NODEJS_ICU_SMALL),small-icu,$(if $(CONFIG_NODEJS_ICU_SYSTEM),system-icu,none)) \
$(if $(findstring +neon",$(CONFIG_CPU_TYPE)),--with-arm-fpu=neon) \
endef
define Host/Install
- $(RM) -rf $(1)/lib/node_modules/npm
+ rm -f $(1)/bin/npm
+ rm -f $(1)/bin/npx
+ rm -rf $(1)/lib/node_modules/npm
+ rm -f $(1)/bin/corepack
+ rm -rf $(1)/lib/node_modules/corepack
$(call Host/Install/Default)
endef
--- a/lib/internal/modules/cjs/loader.js
+++ b/lib/internal/modules/cjs/loader.js
-@@ -1391,7 +1391,8 @@ Module._initPaths = function() {
+@@ -1537,7 +1537,8 @@ Module._initPaths = function() {
path.resolve(process.execPath, '..') :
path.resolve(process.execPath, '..', '..');
result = clock_gettime(CLOCK_MONOTONIC, &ts);
--- a/deps/v8/src/base/platform/platform-posix.cc
+++ b/deps/v8/src/base/platform/platform-posix.cc
-@@ -1066,7 +1066,7 @@ bool Thread::Start() {
+@@ -1147,7 +1147,7 @@ bool Thread::Start() {
#if V8_OS_DARWIN
// Default on Mac OS X is 512kB -- bump up to 1MB
stack_size = 1 * 1024 * 1024;
--- /dev/null
+--- a/deps/uv/uv.gyp
++++ b/deps/uv/uv.gyp
+@@ -155,6 +155,7 @@
+ 'target_name': 'libuv',
+ 'toolsets': ['host', 'target'],
+ 'type': '<(uv_library)',
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ 'include',
+ 'src/',
--- /dev/null
+--- a/deps/zlib/zlib.gyp
++++ b/deps/zlib/zlib.gyp
+@@ -9,6 +9,7 @@
+ 'arm_fpu%': '',
+ 'llvm_version%': '0.0',
+ },
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'conditions': [
+ ['use_system_zlib==0', {
+ 'targets': [
--- /dev/null
+--- a/node.gyp
++++ b/node.gyp
+@@ -1193,6 +1193,7 @@
+ 'dependencies': [
+ 'deps/simdutf/simdutf.gyp:simdutf#host',
+ ],
++ 'libraries!':[ '-licui18n', '-licuuc', '-licudata', '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
+ 'include_dirs': [
+ 'tools'
+ ],
--- /dev/null
+--- a/tools/icu/icu-generic.gyp
++++ b/tools/icu/icu-generic.gyp
+@@ -106,6 +106,7 @@
+ 'sources': [
+ '<@(icu_src_i18n)'
+ ],
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(icu_path)/source/i18n',
+ ],
+@@ -114,6 +115,7 @@
+ ],
+ 'dependencies': [ 'icuucx', 'icu_implementation', 'icu_uconfig', 'icu_uconfig_target' ],
+ 'direct_dependent_settings': {
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(icu_path)/source/i18n',
+ ],
+@@ -200,6 +202,7 @@
+ # full data - no trim needed
+ 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/icudt<(icu_ver_major)_dat.<(icu_asm_ext)' ],
+ 'dependencies': [ 'genccode#host', 'icupkg#host', 'icu_implementation#host', 'icu_uconfig' ],
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(icu_path)/source/common',
+ ],
+@@ -284,6 +287,7 @@
+ # This file contains the small ICU data
+ 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/icusmdt<(icu_ver_major)_dat.<(icu_asm_ext)' ],
+ # for umachine.h
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(icu_path)/source/common',
+ ],
+@@ -300,6 +304,7 @@
+ 'sources': [
+ '<@(icu_src_stubdata)'
+ ],
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(icu_path)/source/common',
+ ],
+@@ -339,6 +344,7 @@
+ '_XOPEN_SOURCE_EXTENDED=0',
+ ]}],
+ ],
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(icu_path)/source/common',
+ ],
+@@ -348,6 +354,7 @@
+ 'cflags_c': ['-std=c99'],
+ 'export_dependent_settings': [ 'icu_uconfig', 'icu_uconfig_target' ],
+ 'direct_dependent_settings': {
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(icu_path)/source/common',
+ ],
+@@ -378,6 +385,7 @@
+ '<(icu_path)/source/tools/toolutil/dbgutil.cpp',
+ '<(icu_path)/source/tools/toolutil/dbgutil.h',
+ ],
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(icu_path)/source/common',
+ '<(icu_path)/source/i18n',
+@@ -397,6 +405,7 @@
+ }]
+ ],
+ 'direct_dependent_settings': {
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(icu_path)/source/common',
+ '<(icu_path)/source/i18n',
+@@ -418,6 +427,7 @@
+ 'target_name': 'genrb',
+ 'type': 'executable',
+ 'toolsets': [ 'host' ],
++ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
+ 'dependencies': [ 'icutools', 'icu_implementation' ],
+ 'sources': [
+ '<@(icu_src_genrb)'
+@@ -440,6 +450,7 @@
+ 'target_name': 'iculslocs',
+ 'toolsets': [ 'host' ],
+ 'type': 'executable',
++ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
+ 'dependencies': [ 'icutools' ],
+ 'sources': [
+ 'iculslocs.cc',
+@@ -458,6 +469,7 @@
+ 'target_name': 'icupkg',
+ 'toolsets': [ 'host' ],
+ 'type': 'executable',
++ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
+ 'dependencies': [ 'icutools' ],
+ 'sources': [
+ '<@(icu_src_icupkg)',
+@@ -475,6 +487,7 @@
+ 'target_name': 'genccode',
+ 'toolsets': [ 'host' ],
+ 'type': 'executable',
++ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
+ 'dependencies': [ 'icutools' ],
+ 'sources': [
+ '<@(icu_src_genccode)',
--- /dev/null
+--- a/tools/v8_gypfiles/v8.gyp
++++ b/tools/v8_gypfiles/v8.gyp
+@@ -73,6 +73,7 @@
+ ],
+ 'hard_dependency': 1,
+ 'direct_dependent_settings': {
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(SHARED_INTERMEDIATE_DIR)',
+ ],
+@@ -194,6 +195,7 @@
+ '<@(torque_outputs_cc)',
+ '<@(torque_outputs_inc)',
+ ],
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(SHARED_INTERMEDIATE_DIR)',
+ ],
+@@ -215,6 +217,7 @@
+ 'sources': [
+ '<(generate_bytecode_builtins_list_output)',
+ ],
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(generate_bytecode_output_root)',
+ '<(SHARED_INTERMEDIATE_DIR)',
+@@ -252,6 +255,7 @@
+ 'sources': [
+ '<(V8_ROOT)/src/init/setup-isolate-full.cc',
+ ],
++ 'include_dirs': [ '<!@(echo "$STAGING_DIR"/usr/../usr/include)' ],
+ }, # v8_init
+ {
+ 'target_name': 'v8_initializers',
+@@ -263,9 +267,11 @@
+ 'v8_shared_internal_headers',
+ 'v8_pch',
+ ],
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(SHARED_INTERMEDIATE_DIR)',
+ '<(generate_bytecode_output_root)',
++ '<!@(echo "$STAGING_DIR"/usr/../usr/include)',
+ ],
+ 'sources': [
+ '<!@pymod_do_main(GN-scraper "<(V8_ROOT)/BUILD.gn" "\\"v8_initializers.*?sources = ")',
+@@ -689,6 +695,7 @@
+ 'toolsets': ['host', 'target'],
+ 'direct_dependent_settings': {
+ 'sources': ['<!@pymod_do_main(GN-scraper "<(V8_ROOT)/BUILD.gn" "v8_compiler_sources = ")'],
++ 'include_dirs': [ '<!@(echo "$STAGING_DIR"/usr/../usr/include)' ],
+ 'conditions': [
+ ['v8_target_arch=="ia32"', {
+ 'sources': [
+@@ -797,6 +804,8 @@
+ 'target_name': 'v8_turboshaft',
+ 'type': 'static_library',
+ 'toolsets': ['host', 'target'],
++ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
++ 'include_dirs': [ '<!@(echo "$STAGING_DIR"/usr/../usr/include)' ],
+ 'dependencies': [
+ 'generate_bytecode_builtins_list',
+ 'run_torque',
+@@ -821,6 +830,7 @@
+ 'run_torque',
+ 'v8_maybe_icu',
+ ],
++ 'include_dirs': [ '<!@(echo "$STAGING_DIR"/usr/../usr/include)' ],
+ 'conditions': [
+ ['(is_component_build and not v8_optimized_debug and v8_enable_fast_mksnapshot) or v8_enable_turbofan==0', {
+ 'dependencies': [
+@@ -861,6 +871,7 @@
+ ],
+ 'includes': ['inspector.gypi'],
+ 'direct_dependent_settings': {
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(generate_bytecode_output_root)',
+ '<(SHARED_INTERMEDIATE_DIR)',
+@@ -1474,6 +1485,7 @@
+ }],
+ ],
+ 'direct_dependent_settings': {
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(V8_ROOT)/include',
+ ],
+@@ -1494,6 +1506,7 @@
+ {
+ 'target_name': 'bytecode_builtins_list_generator',
+ 'type': 'executable',
++ 'libraries!':[ '-licui18n', '-licuuc', '-licudata', '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
+ 'conditions': [
+ ['want_separate_host_toolset', {
+ 'toolsets': ['host'],
+@@ -1522,6 +1535,9 @@
+ {
+ 'target_name': 'mksnapshot',
+ 'type': 'executable',
++ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
++ 'library_dirs':[ '../../../../staging_dir/hostpkg/share/icu/current/lib' ],
++ 'include_dirs': [ '<!@(echo "$STAGING_DIR"/usr/../usr/include)' ],
+ 'dependencies': [
+ 'v8_base_without_compiler',
+ 'v8_compiler_for_mksnapshot',
+@@ -1549,6 +1565,7 @@
+ {
+ 'target_name': 'torque',
+ 'type': 'executable',
++ 'libraries!':[ '-licui18n', '-licuuc', '-licudata', '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
+ 'dependencies': [
+ 'torque_base',
+ # "build/win:default_exe_manifest",
+@@ -1591,6 +1608,7 @@
+ {
+ 'target_name': 'torque-language-server',
+ 'type': 'executable',
++ 'libraries!':[ '-licui18n', '-licuuc', '-licudata', '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
+ 'conditions': [
+ ['want_separate_host_toolset', {
+ 'toolsets': ['host'],
+@@ -1622,6 +1640,8 @@
+ {
+ 'target_name': 'gen-regexp-special-case',
+ 'type': 'executable',
++ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
++ 'library_dirs':[ '../../../../staging_dir/hostpkg/share/icu/current/lib' ],
+ 'dependencies': [
+ 'v8_libbase',
+ # "build/win:default_exe_manifest",
+@@ -1840,6 +1860,7 @@
+ }],
+ ],
+ 'direct_dependent_settings': {
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(V8_ROOT)/include',
+ ],
+@@ -1961,15 +1982,19 @@
+ }],
+ ],
+ 'direct_dependent_settings': {
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(V8_ROOT)/third_party/zlib',
+ '<(V8_ROOT)/third_party/zlib/google',
++ '<!@(echo "$STAGING_DIR"/usr/../usr/include)',
+ ],
+ },
+ 'defines': [ 'ZLIB_IMPLEMENTATION' ],
++ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
+ 'include_dirs': [
+ '<(V8_ROOT)/third_party/zlib',
+ '<(V8_ROOT)/third_party/zlib/google',
++ '<!@(echo "$STAGING_DIR"/usr/../usr/include)',
+ ],
+ 'sources': [
+ '<(V8_ROOT)/third_party/zlib/adler32.c',
+++ /dev/null
---- a/tools/icu/icu-generic.gyp
-+++ b/tools/icu/icu-generic.gyp
-@@ -418,6 +418,7 @@
- 'target_name': 'genrb',
- 'type': 'executable',
- 'toolsets': [ 'host' ],
-+ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
- 'dependencies': [ 'icutools', 'icu_implementation' ],
- 'sources': [
- '<@(icu_src_genrb)'
-@@ -440,6 +441,7 @@
- 'target_name': 'iculslocs',
- 'toolsets': [ 'host' ],
- 'type': 'executable',
-+ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
- 'dependencies': [ 'icutools' ],
- 'sources': [
- 'iculslocs.cc',
-@@ -458,6 +460,7 @@
- 'target_name': 'icupkg',
- 'toolsets': [ 'host' ],
- 'type': 'executable',
-+ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
- 'dependencies': [ 'icutools' ],
- 'sources': [
- '<@(icu_src_icupkg)',
-@@ -475,6 +478,7 @@
- 'target_name': 'genccode',
- 'toolsets': [ 'host' ],
- 'type': 'executable',
-+ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
- 'dependencies': [ 'icutools' ],
- 'sources': [
- '<@(icu_src_genccode)',
---- a/tools/v8_gypfiles/v8.gyp
-+++ b/tools/v8_gypfiles/v8.gyp
-@@ -1397,6 +1397,7 @@
- {
- 'target_name': 'bytecode_builtins_list_generator',
- 'type': 'executable',
-+ 'libraries!':[ '-licui18n', '-licuuc', '-licudata', '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
- 'conditions': [
- ['want_separate_host_toolset', {
- 'toolsets': ['host'],
-@@ -1425,6 +1426,8 @@
- {
- 'target_name': 'mksnapshot',
- 'type': 'executable',
-+ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
-+ 'library_dirs':[ '../../../../staging_dir/hostpkg/share/icu/current/lib' ],
- 'dependencies': [
- 'v8_base_without_compiler',
- 'v8_compiler_for_mksnapshot',
-@@ -1458,6 +1461,7 @@
- {
- 'target_name': 'torque',
- 'type': 'executable',
-+ 'libraries!':[ '-licui18n', '-licuuc', '-licudata', '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
- 'dependencies': [
- 'torque_base',
- # "build/win:default_exe_manifest",
-@@ -1500,6 +1504,7 @@
- {
- 'target_name': 'torque-language-server',
- 'type': 'executable',
-+ 'libraries!':[ '-licui18n', '-licuuc', '-licudata', '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
- 'conditions': [
- ['want_separate_host_toolset', {
- 'toolsets': ['host'],
-@@ -1531,6 +1536,8 @@
- {
- 'target_name': 'gen-regexp-special-case',
- 'type': 'executable',
-+ 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
-+ 'library_dirs':[ '../../../../staging_dir/hostpkg/share/icu/current/lib' ],
- 'dependencies': [
- 'v8_libbase',
- # "build/win:default_exe_manifest",
+++ /dev/null
---- a/deps/zlib/zlib.gyp
-+++ b/deps/zlib/zlib.gyp
-@@ -9,6 +9,7 @@
- 'arm_fpu%': '',
- 'llvm_version%': '0.0',
- },
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'conditions': [
- ['use_system_zlib==0', {
- 'targets': [
---- a/tools/v8_gypfiles/v8.gyp
-+++ b/tools/v8_gypfiles/v8.gyp
-@@ -60,6 +60,7 @@
- ],
- 'hard_dependency': 1,
- 'direct_dependent_settings': {
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ],
-@@ -181,6 +182,7 @@
- '<@(torque_outputs_cc)',
- '<@(torque_outputs_inc)',
- ],
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ],
-@@ -202,6 +204,7 @@
- 'sources': [
- '<(generate_bytecode_builtins_list_output)',
- ],
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(generate_bytecode_output_root)',
- '<(SHARED_INTERMEDIATE_DIR)',
-@@ -249,9 +252,11 @@
- 'v8_base_without_compiler',
- 'v8_shared_internal_headers',
- ],
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- '<(generate_bytecode_output_root)',
-+ '<!@(echo "$STAGING_DIR"/usr/../usr/include)',
- ],
- 'sources': [
- '<!@pymod_do_main(GN-scraper "<(V8_ROOT)/BUILD.gn" "\\"v8_initializers.*?sources = ")',
-@@ -769,6 +774,7 @@
- ],
- 'includes': ['inspector.gypi'],
- 'direct_dependent_settings': {
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(generate_bytecode_output_root)',
- '<(SHARED_INTERMEDIATE_DIR)',
-@@ -1377,6 +1383,7 @@
- }],
- ],
- 'direct_dependent_settings': {
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(V8_ROOT)/include',
- ],
-@@ -1761,6 +1768,7 @@
- }],
- ],
- 'direct_dependent_settings': {
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(V8_ROOT)/include',
- ],
-@@ -1941,15 +1949,19 @@
- }],
- ],
- 'direct_dependent_settings': {
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(V8_ROOT)/third_party/zlib',
- '<(V8_ROOT)/third_party/zlib/google',
-+ '<!@(echo "$STAGING_DIR"/usr/../usr/include)',
- ],
- },
- 'defines': [ 'ZLIB_IMPLEMENTATION' ],
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(V8_ROOT)/third_party/zlib',
- '<(V8_ROOT)/third_party/zlib/google',
-+ '<!@(echo "$STAGING_DIR"/usr/../usr/include)',
- ],
- 'sources': [
- '<(V8_ROOT)/third_party/zlib/adler32.c',
+++ /dev/null
---- a/tools/v8_gypfiles/v8.gyp
-+++ b/tools/v8_gypfiles/v8.gyp
-@@ -242,6 +242,7 @@
- 'sources': [
- '<(V8_ROOT)/src/init/setup-isolate-full.cc',
- ],
-+ 'include_dirs': [ '<!@(echo "$STAGING_DIR"/usr/../usr/include)' ],
- }, # v8_init
- {
- 'target_name': 'v8_initializers',
-@@ -714,6 +715,7 @@
- 'v8_shared_internal_headers',
- ],
- 'sources': ['<@(v8_compiler_sources)'],
-+ 'include_dirs': [ '<!@(echo "$STAGING_DIR"/usr/../usr/include)' ],
- 'conditions': [
- ['OS=="win"', {
- 'msvs_precompiled_header': '<(V8_ROOT)/../../tools/msvs/pch/v8_pch.h',
-@@ -1435,6 +1437,7 @@
- 'type': 'executable',
- 'libraries!':[ '-lcrypto', '-lssl', '-lz', '-lhttp_parser', '-luv', '-lnghttp2', '-lcares' ],
- 'library_dirs':[ '../../../../staging_dir/hostpkg/share/icu/current/lib' ],
-+ 'include_dirs': [ '<!@(echo "$STAGING_DIR"/usr/../usr/include)' ],
- 'dependencies': [
- 'v8_base_without_compiler',
- 'v8_compiler_for_mksnapshot',
+++ /dev/null
---- a/deps/v8/src/compiler/backend/mips/code-generator-mips.cc
-+++ b/deps/v8/src/compiler/backend/mips/code-generator-mips.cc
-@@ -4101,7 +4101,7 @@ void CodeGenerator::AssembleReturn(Instr
- } else if (FLAG_debug_code) {
- __ Assert(eq, AbortReason::kUnexpectedAdditionalPopValue,
- g.ToRegister(additional_pop_count),
-- Operand(static_cast<int64_t>(0)));
-+ Operand(static_cast<int32_t>(0)));
- }
- }
- // Functions with JS linkage have at least one parameter (the receiver).
+++ /dev/null
---- a/tools/icu/icu-generic.gyp
-+++ b/tools/icu/icu-generic.gyp
-@@ -106,6 +106,7 @@
- 'sources': [
- '<@(icu_src_i18n)'
- ],
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(icu_path)/source/i18n',
- ],
-@@ -114,6 +115,7 @@
- ],
- 'dependencies': [ 'icuucx', 'icu_implementation', 'icu_uconfig', 'icu_uconfig_target' ],
- 'direct_dependent_settings': {
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(icu_path)/source/i18n',
- ],
-@@ -200,6 +202,7 @@
- # full data - no trim needed
- 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/icudt<(icu_ver_major)_dat.<(icu_asm_ext)' ],
- 'dependencies': [ 'genccode#host', 'icupkg#host', 'icu_implementation#host', 'icu_uconfig' ],
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(icu_path)/source/common',
- ],
-@@ -284,6 +287,7 @@
- # This file contains the small ICU data
- 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/icusmdt<(icu_ver_major)_dat.<(icu_asm_ext)' ],
- # for umachine.h
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(icu_path)/source/common',
- ],
-@@ -300,6 +304,7 @@
- 'sources': [
- '<@(icu_src_stubdata)'
- ],
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(icu_path)/source/common',
- ],
-@@ -339,6 +344,7 @@
- '_XOPEN_SOURCE_EXTENDED=0',
- ]}],
- ],
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(icu_path)/source/common',
- ],
-@@ -348,6 +354,7 @@
- 'cflags_c': ['-std=c99'],
- 'export_dependent_settings': [ 'icu_uconfig', 'icu_uconfig_target' ],
- 'direct_dependent_settings': {
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(icu_path)/source/common',
- ],
-@@ -378,6 +385,7 @@
- '<(icu_path)/source/tools/toolutil/dbgutil.cpp',
- '<(icu_path)/source/tools/toolutil/dbgutil.h',
- ],
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(icu_path)/source/common',
- '<(icu_path)/source/i18n',
-@@ -397,6 +405,7 @@
- }]
- ],
- 'direct_dependent_settings': {
-+ 'include_dirs!': [ '<!@(echo "$STAGING_DIR"/usr/include)' ],
- 'include_dirs': [
- '<(icu_path)/source/common',
- '<(icu_path)/source/i18n',
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
-@@ -1321,13 +1322,6 @@ function lookupAndConnect(self, options)
+@@ -1330,13 +1331,6 @@ function lookupAndConnect(self, options)
hints: options.hints || 0,
};
--- a/configure.py
+++ b/configure.py
-@@ -1291,7 +1291,6 @@ def configure_node(o):
+@@ -1270,7 +1270,6 @@ def configure_node(o):
# Enable branch protection for arm64
if target_arch == 'arm64':
include $(TOPDIR)/rules.mk
PKG_NAME:=perl-text-csv_xs
-PKG_VERSION:=1.51
+PKG_VERSION:=1.52
PKG_RELEASE:=1
PKG_SOURCE:=Text-CSV_XS-$(PKG_VERSION).tgz
PKG_SOURCE_URL:=https://cpan.metacpan.org/authors/id/H/HM/HMBRAND
-PKG_HASH:=b1831d4d5f90ec6ad7f111a2e4bc5ca6dce7d17d7e57f17ace42b0f3ca140372
+PKG_HASH:=e415aa705badf84b359dc4c0f0c982f1bf708481daa14756f3136e7c89c0e41d
PKG_BUILD_DIR:=$(BUILD_DIR)/perl/Text-CSV_XS-$(PKG_VERSION)
PKG_MAINTAINER:=Philip Prindeville <philipp@redfish-solutions.com>
PKG_NAME:=perl
PKG_VERSION:=$(PERL_VERSION)
-PKG_RELEASE:=9
-
-PKG_SOURCE_URL:=\
- https://cpan.metacpan.org/src/5.0 \
- https://cpan.uib.no/src/5.0 \
- https://mirrors.rit.edu/CPAN/src/5.0 \
- https://mirror.transip.net/CPAN/src/5.0 \
- https://mirrors.sonic.net/cpan/src/5.0 \
- https://www.cpan.org/src/5.0
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=https://www.cpan.org/src/5.0
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_HASH:=fea7162d4cca940a387f0587b93f6737d884bf74d8a9d7cfd978bc12cd0b202d
+PKG_HASH:=d91115e90b896520e83d4de6b52f8254ef2b70a8d545ffab33200ea9f1cf29e8
PKG_LICENSE:=GPL-1.0-or-later Artistic-1.0-Perl
PKG_LICENSE_FILES:=Copying Artistic README
-PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>, \
- Philip Prindeville <philipp@redfish-solutions.com>
+PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>, Philip Prindeville <philipp@redfish-solutions.com>
PKG_CPE_ID:=cpe:/a:perl:perl
# Build settings
d_atanh='define'
d_atolf='undef'
d_atoll='define'
+d_attribute_always_inline='define'
d_attribute_deprecated='define'
d_attribute_format='define'
d_attribute_malloc='define'
d_attribute_noreturn='define'
d_attribute_pure='define'
d_attribute_unused='define'
+d_attribute_visibility='define'
d_attribute_warn_unused_result='define'
d_backtrace='define'
d_bcmp='define'
d_fd_set='define'
d_fdclose='undef'
d_fdim='define'
+d_ffs='define'
+d_ffsl='define'
d_fgetpos='define'
d_finite='define'
d_finitel='undef'
d_gdbmndbm_h_uses_prototypes='undef'
d_getaddrinfo='define'
d_getcwd='define'
+d_getenv_preserves_other_thread='define'
d_getespwnam='undef'
d_getfsstat='undef'
d_getgrent='define'
d_nextafter='define'
d_nice='define'
d_nl_langinfo='define'
+d_nl_langinfo_l='define'
+d_non_int_bitfields='define'
d_nv_zero_is_allbits_zero='define'
d_old_pthread_create_joinable='undef'
d_oldpthreads='undef'
d_semop='define'
d_sendmsg='define'
d_setegid='define'
+d_setenv='define'
d_seteuid='define'
d_setgrent='define'
d_setgrent_r='undef'
d_setitimer='define'
d_setlinebuf='define'
d_setlocale='define'
+d_setlocale_accepts_any_locale_name='undef'
d_setlocale_r='undef'
d_setnent='define'
d_setnetent_r='undef'
d_snprintf='define'
d_sockaddr_in6="$owrt:ipv6"
d_sockaddr_sa_len='undef'
+d_sockaddr_storage='define'
d_sockatmark='undef'
d_sockatmarkproto='undef'
d_socket='define'
d_strtoull='define'
d_strtouq='define'
d_strxfrm='define'
+d_strxfrm_l='define'
d_suidsafe='undef'
d_symlink='define'
d_syscall='define'
d_telldir='define'
d_telldirproto='define'
d_tgamma='define'
+d_thread_local='define'
d_thread_safe_nl_langinfo_l='define'
d_time='define'
d_timegm='define'
d_times='define'
d_tm_tm_gmtoff='define'
d_tm_tm_zone='define'
+d_towlower='define'
+d_towupper='define'
d_trunc='define'
d_truncate='define'
d_truncl='define'
d_vsnprintf='define'
d_wait4='define'
d_waitpid='define'
+d_wcrtomb='define'
d_wcscmp='define'
d_wcstombs='define'
d_wcsxfrm='define'
i_sysstat='define'
i_sysstatfs='define'
i_sysstatvfs='define'
+i_syssyscall='define'
i_systime='define'
i_systimek='undef'
i_systimes='define'
i_varhdr='stdarg.h'
i_vfork='undef'
i_wchar='define'
+i_wctype='define'
i_xlocale='undef'
ignore_versioned_solibs='y'
inc_version_list=' '
spitshell='cat'
src='.'
ssizetype='ssize_t'
+st_dev_sign='1'
+st_dev_size='8'
st_ino_sign='1'
st_ino_size='8'
startperl='#!/usr/bin/perl'
use5005threads='undef'
usecbacktrace='undef'
usecrosscompile='define'
+usedefaultstrict='undef'
usedevel='undef'
usedl='define'
usedtrace='undef'
vi=''
voidflags='15'
xlibpth='/usr/lib/386 /lib/386'
+xlocale_needed='undef'
yacc='yacc'
yaccflags=''
zcat=''
}
($owrt:libc eq 'musl') {
- # musl does not provide a working setlocale(). It accepts arbitrary locales
- # and makes them act as if they were C.UTF-8.
- d_setlocale='undef'
-
d_stdio_ptr_lval='undef'
d_stdio_ptr_lval_sets_cnt='undef'
d_stdiobase='undef'
--- /dev/null
+owrt:arch=riscv
+owrt:bits=64
+owrt:endian=little
+
+ccsymbols=''
+cppccsymbols=''
+cppsymbols='_FILE_OFFSET_BITS=64 _FORTIFY_SOURCE=2 _GNU_SOURCE=1 _LARGEFILE64_SOURCE=1 _LARGEFILE_SOURCE=1 _LP64=1 _POSIX_C_SOURCE=200809L _POSIX_SOURCE=1 _REENTRANT=1 _STDC_PREDEF_H=1 _XOPEN_SOURCE=700 _XOPEN_SOURCE_EXTENDED=1 __ATOMIC_ACQUIRE=2 __ATOMIC_ACQ_REL=4 __ATOMIC_CONSUME=1 __ATOMIC_RELAXED=0 __ATOMIC_RELEASE=3 __ATOMIC_SEQ_CST=5 __BIGGEST_ALIGNMENT__=16 __BYTE_ORDER__=1234 __CHAR16_TYPE__=short\ unsigned\ int __CHAR32_TYPE__=unsigned\ int __CHAR_BIT__=8 __CHAR_UNSIGNED__=1 __DBL_DECIMAL_DIG__=17 __DBL_DENORM_MIN__=((double)4.94065645841246544176568792868221372e-324L) __DBL_DIG__=15 __DBL_EPSILON__=((double)2.22044604925031308084726333618164062e-16L) __DBL_HAS_DENORM__=1 __DBL_HAS_INFINITY__=1 __DBL_HAS_QUIET_NAN__=1 __DBL_MANT_DIG__=53 __DBL_MAX_10_EXP__=308 __DBL_MAX_EXP__=1024 __DBL_MAX__=((double)1.79769313486231570814527423731704357e+308L) __DBL_MIN_10_EXP__=(-307) __DBL_MIN_EXP__=(-1021) __DBL_MIN__=((double)2.22507385850720138309023271733240406e-308L) __DEC128_EPSILON__=1E-33DL __DEC128_MANT_DIG__=34 __DEC128_MAX_EXP__=6145 __DEC128_MAX__=9.999999999999999999999999999999999E6144DL __DEC128_MIN_EXP__=(-6142) __DEC128_MIN__=1E-6143DL __DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL __DEC32_EPSILON__=1E-6DF __DEC32_MANT_DIG__=7 __DEC32_MAX_EXP__=97 __DEC32_MAX__=9.999999E96DF __DEC32_MIN_EXP__=(-94) __DEC32_MIN__=1E-95DF __DEC32_SUBNORMAL_MIN__=0.000001E-95DF __DEC64_EPSILON__=1E-15DD __DEC64_MANT_DIG__=16 __DEC64_MAX_EXP__=385 __DEC64_MAX__=9.999999999999999E384DD __DEC64_MIN_EXP__=(-382) __DEC64_MIN__=1E-383DD __DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD __DECIMAL_DIG__=36 __DEC_EVAL_METHOD__=2 __ELF__=1 __FINITE_MATH_ONLY__=0 __FLOAT_WORD_ORDER__=1234 __FLT128_DECIMAL_DIG__=36 __FLT128_DENORM_MIN__=6.47517511943802511092443895822764655e-4966F128 __FLT128_DIG__=33 __FLT128_EPSILON__=1.92592994438723585305597794258492732e-34F128 __FLT128_HAS_DENORM__=1 __FLT128_HAS_INFINITY__=1 __FLT128_HAS_QUIET_NAN__=1 __FLT128_MANT_DIG__=113 __FLT128_MAX_10_EXP__=4932 __FLT128_MAX_EXP__=16384 __FLT128_MAX__=1.18973149535723176508575932662800702e+4932F128 __FLT128_MIN_10_EXP__=(-4931) __FLT128_MIN_EXP__=(-16381) __FLT128_MIN__=3.36210314311209350626267781732175260e-4932F128 __FLT32X_DECIMAL_DIG__=17 __FLT32X_DENORM_MIN__=4.94065645841246544176568792868221372e-324F32x __FLT32X_DIG__=15 __FLT32X_EPSILON__=2.22044604925031308084726333618164062e-16F32x __FLT32X_HAS_DENORM__=1 __FLT32X_HAS_INFINITY__=1 __FLT32X_HAS_QUIET_NAN__=1 __FLT32X_MANT_DIG__=53 __FLT32X_MAX_10_EXP__=308 __FLT32X_MAX_EXP__=1024 __FLT32X_MAX__=1.79769313486231570814527423731704357e+308F32x __FLT32X_MIN_10_EXP__=(-307) __FLT32X_MIN_EXP__=(-1021) __FLT32X_MIN__=2.22507385850720138309023271733240406e-308F32x __FLT32_DECIMAL_DIG__=9 __FLT32_DENORM_MIN__=1.40129846432481707092372958328991613e-45F32 __FLT32_DIG__=6 __FLT32_EPSILON__=1.19209289550781250000000000000000000e-7F32 __FLT32_HAS_DENORM__=1 __FLT32_HAS_INFINITY__=1 __FLT32_HAS_QUIET_NAN__=1 __FLT32_MANT_DIG__=24 __FLT32_MAX_10_EXP__=38 __FLT32_MAX_EXP__=128 __FLT32_MAX__=3.40282346638528859811704183484516925e+38F32 __FLT32_MIN_10_EXP__=(-37) __FLT32_MIN_EXP__=(-125) __FLT32_MIN__=1.17549435082228750796873653722224568e-38F32 __FLT64X_DECIMAL_DIG__=36 __FLT64X_DENORM_MIN__=6.47517511943802511092443895822764655e-4966F64x __FLT64X_DIG__=33 __FLT64X_EPSILON__=1.92592994438723585305597794258492732e-34F64x __FLT64X_HAS_DENORM__=1 __FLT64X_HAS_INFINITY__=1 __FLT64X_HAS_QUIET_NAN__=1 __FLT64X_MANT_DIG__=113 __FLT64X_MAX_10_EXP__=4932 __FLT64X_MAX_EXP__=16384 __FLT64X_MAX__=1.18973149535723176508575932662800702e+4932F64x __FLT64X_MIN_10_EXP__=(-4931) __FLT64X_MIN_EXP__=(-16381) __FLT64X_MIN__=3.36210314311209350626267781732175260e-4932F64x __FLT64_DECIMAL_DIG__=17 __FLT64_DENORM_MIN__=4.94065645841246544176568792868221372e-324F64 __FLT64_DIG__=15 __FLT64_EPSILON__=2.22044604925031308084726333618164062e-16F64 __FLT64_HAS_DENORM__=1 __FLT64_HAS_INFINITY__=1 __FLT64_HAS_QUIET_NAN__=1 __FLT64_MANT_DIG__=53 __FLT64_MAX_10_EXP__=308 __FLT64_MAX_EXP__=1024 __FLT64_MAX__=1.79769313486231570814527423731704357e+308F64 __FLT64_MIN_10_EXP__=(-307) __FLT64_MIN_EXP__=(-1021) __FLT64_MIN__=2.22507385850720138309023271733240406e-308F64 __FLT_DECIMAL_DIG__=9 __FLT_DENORM_MIN__=1.40129846432481707092372958328991613e-45F __FLT_DIG__=6 __FLT_EPSILON__=1.19209289550781250000000000000000000e-7F __FLT_EVAL_METHOD_TS_18661_3__=0 __FLT_EVAL_METHOD__=0 __FLT_HAS_DENORM__=1 __FLT_HAS_INFINITY__=1 __FLT_HAS_QUIET_NAN__=1 __FLT_MANT_DIG__=24 __FLT_MAX_10_EXP__=38 __FLT_MAX_EXP__=128 __FLT_MAX__=3.40282346638528859811704183484516925e+38F __FLT_MIN_10_EXP__=(-37) __FLT_MIN_EXP__=(-125) __FLT_MIN__=1.17549435082228750796873653722224568e-38F __FLT_RADIX__=2 __FP_FAST_FMA=1 __FP_FAST_FMAF32=1 __FP_FAST_FMAF32x=1 __FP_FAST_FMAF64=1 __FP_FAST_FMAF=1 __GCC_ATOMIC_BOOL_LOCK_FREE=1 __GCC_ATOMIC_CHAR16_T_LOCK_FREE=1 __GCC_ATOMIC_CHAR32_T_LOCK_FREE=2 __GCC_ATOMIC_CHAR_LOCK_FREE=1 __GCC_ATOMIC_INT_LOCK_FREE=2 __GCC_ATOMIC_LLONG_LOCK_FREE=2 __GCC_ATOMIC_LONG_LOCK_FREE=2 __GCC_ATOMIC_POINTER_LOCK_FREE=2 __GCC_ATOMIC_SHORT_LOCK_FREE=1 __GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1 __GCC_ATOMIC_WCHAR_T_LOCK_FREE=2 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4=1 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8=1 __GCC_IEC_559=2 __GCC_IEC_559_COMPLEX=2 __GLIBC_MINOR__=27 __GLIBC__=2 __GNUC_MINOR__=2 __GNUC_PATCHLEVEL__=0 __GNUC_STDC_INLINE__=1 __GNUC__=8 __GNU_LIBRARY__=6 __GXX_ABI_VERSION=1013 __INT16_C=__INT16_C __INT16_MAX__=0x7fff __INT16_TYPE__=short\ int __INT32_C=__INT32_C __INT32_MAX__=0x7fffffff __INT32_TYPE__=int __INT64_C=__INT64_C __INT64_MAX__=0x7fffffffffffffffL __INT64_TYPE__=long\ int __INT8_C=__INT8_C __INT8_MAX__=0x7f __INT8_TYPE__=signed\ char __INTMAX_C=__INTMAX_C __INTMAX_MAX__=0x7fffffffffffffffL __INTMAX_TYPE__=long\ int __INTMAX_WIDTH__=64 __INTPTR_MAX__=0x7fffffffffffffffL __INTPTR_TYPE__=long\ int __INTPTR_WIDTH__=64 __INT_FAST16_MAX__=0x7fffffffffffffffL __INT_FAST16_TYPE__=long\ int __INT_FAST16_WIDTH__=64 __INT_FAST32_MAX__=0x7fffffffffffffffL __INT_FAST32_TYPE__=long\ int __INT_FAST32_WIDTH__=64 __INT_FAST64_MAX__=0x7fffffffffffffffL __INT_FAST64_TYPE__=long\ int __INT_FAST64_WIDTH__=64 __INT_FAST8_MAX__=0x7f __INT_FAST8_TYPE__=signed\ char __INT_FAST8_WIDTH__=8 __INT_LEAST16_MAX__=0x7fff __INT_LEAST16_TYPE__=short\ int __INT_LEAST16_WIDTH__=16 __INT_LEAST32_MAX__=0x7fffffff __INT_LEAST32_TYPE__=int __INT_LEAST32_WIDTH__=32 __INT_LEAST64_MAX__=0x7fffffffffffffffL __INT_LEAST64_TYPE__=long\ int __INT_LEAST64_WIDTH__=64 __INT_LEAST8_MAX__=0x7f __INT_LEAST8_TYPE__=signed\ char __INT_LEAST8_WIDTH__=8 __INT_MAX__=0x7fffffff __INT_WIDTH__=32 __LDBL_DECIMAL_DIG__=36 __LDBL_DENORM_MIN__=6.47517511943802511092443895822764655e-4966L __LDBL_DIG__=33 __LDBL_EPSILON__=1.92592994438723585305597794258492732e-34L __LDBL_HAS_DENORM__=1 __LDBL_HAS_INFINITY__=1 __LDBL_HAS_QUIET_NAN__=1 __LDBL_MANT_DIG__=113 __LDBL_MAX_10_EXP__=4932 __LDBL_MAX_EXP__=16384 __LDBL_MAX__=1.18973149535723176508575932662800702e+4932L __LDBL_MIN_10_EXP__=(-4931) __LDBL_MIN_EXP__=(-16381) __LDBL_MIN__=3.36210314311209350626267781732175260e-4932L __LONG_LONG_MAX__=0x7fffffffffffffffLL __LONG_LONG_WIDTH__=64 __LONG_MAX__=0x7fffffffffffffffL __LONG_WIDTH__=64 __LP64__=1 __ORDER_BIG_ENDIAN__=4321 __ORDER_LITTLE_ENDIAN__=1234 __ORDER_PDP_ENDIAN__=3412 __PIC__=2 __PIE__=2 __PRAGMA_REDEFINE_EXTNAME=1 __PTRDIFF_MAX__=0x7fffffffffffffffL __PTRDIFF_TYPE__=long\ int __PTRDIFF_WIDTH__=64 __REGISTER_PREFIX__= __SCHAR_MAX__=0x7f __SCHAR_WIDTH__=8 __SHRT_MAX__=0x7fff __SHRT_WIDTH__=16 __SIG_ATOMIC_MAX__=0x7fffffff __SIG_ATOMIC_MIN__=(-0x7fffffff\ -\ 1) __SIG_ATOMIC_TYPE__=int __SIG_ATOMIC_WIDTH__=32 __SIZEOF_DOUBLE__=8 __SIZEOF_FLOAT__=4 __SIZEOF_INT128__=16 __SIZEOF_INT__=4 __SIZEOF_LONG_DOUBLE__=16 __SIZEOF_LONG_LONG__=8 __SIZEOF_LONG__=8 __SIZEOF_POINTER__=8 __SIZEOF_PTRDIFF_T__=8 __SIZEOF_SHORT__=2 __SIZEOF_SIZE_T__=8 __SIZEOF_WCHAR_T__=4 __SIZEOF_WINT_T__=4 __SIZE_MAX__=0xffffffffffffffffUL __SIZE_TYPE__=long\ unsigned\ int __SIZE_WIDTH__=64 __STDC_HOSTED__=1 __STDC_IEC_559_COMPLEX__=1 __STDC_IEC_559__=1 __STDC_ISO_10646__=201706L __STDC_NO_THREADS__=1 __STDC_UTF_16__=1 __STDC_UTF_32__=1 __STDC_VERSION__=201710L __STDC__=1 __UINT16_C=__UINT16_C __UINT16_MAX__=0xffff __UINT16_TYPE__=short\ unsigned\ int __UINT32_C=__UINT32_C __UINT32_MAX__=0xffffffffU __UINT32_TYPE__=unsigned\ int __UINT64_C=__UINT64_C __UINT64_MAX__=0xffffffffffffffffUL __UINT64_TYPE__=long\ unsigned\ int __UINT8_C=__UINT8_C __UINT8_MAX__=0xff __UINT8_TYPE__=unsigned\ char __UINTMAX_C=__UINTMAX_C __UINTMAX_MAX__=0xffffffffffffffffUL __UINTMAX_TYPE__=long\ unsigned\ int __UINTPTR_MAX__=0xffffffffffffffffUL __UINTPTR_TYPE__=long\ unsigned\ int __UINT_FAST16_MAX__=0xffffffffffffffffUL __UINT_FAST16_TYPE__=long\unsigned\ int __UINT_FAST32_MAX__=0xffffffffffffffffUL __UINT_FAST32_TYPE__=long\ unsigned\ int __UINT_FAST64_MAX__=0xffffffffffffffffUL __UINT_FAST64_TYPE__=long\ unsigned\ int __UINT_FAST8_MAX__=0xff __UINT_FAST8_TYPE__=unsigned\ char__UINT_LEAST16_MAX__=0xffff __UINT_LEAST16_TYPE__=short\ unsigned\ int __UINT_LEAST32_MAX__=0xffffffffU __UINT_LEAST32_TYPE__=unsigned\ int __UINT_LEAST64_MAX__=0xffffffffffffffffUL __UINT_LEAST64_TYPE__=long\ unsigned\ int __UINT_LEAST8_MAX__=0xff __UINT_LEAST8_TYPE__=unsigned\ char __USER_LABEL_PREFIX__= __USE_FILE_OFFSET64=1 __USE_GNU=1 __USE_LARGEFILE64=1 __USE_LARGEFILE=1 __USE_MISC=1 __USE_POSIX199309=1 __USE_POSIX199506=1 __USE_POSIX2=1 __USE_POSIX=1 __USE_UNIX98=1 __USE_XOPEN=1 __USE_XOPEN_EXTENDED=1 __VERSION__="8.2.0" __WCHAR_MAX__=0x7fffffff __WCHAR_MIN__=(-0x7fffffff\ -\ 1) __WCHAR_TYPE__=int __WCHAR_WIDTH__=32 __WINT_MAX__=0xffffffffU __WINT_MIN__=0U __WINT_TYPE__=unsigned\ int __WINT_WIDTH__=32 __gnu_linux__=1 __has_include=__has_include __has_include_next=__has_include_next __linux=1 __linux__=1 __pic__=2 __pie__=2 __riscv=1 __riscv_atomic=1 __riscv_cmodel_pic=1 __riscv_compressed=1 __riscv_div=1 __riscv_fdiv=1 __riscv_flen=64 __riscv_float_abi_double=1 __riscv_fsqrt=1 __riscv_mul=1 __riscv_muldiv=1 __riscv_xlen=64 __unix=1 __unix__=1 linux=1 unix=1'
+
+d_casti32='define'
+d_double_style_ieee='define'
+d_modflproto='define'
+doublekind='3'
+fpossize='16'
+longdblkind='1'
+need_va_copy='undef'
+quadkind='2'
+
+owrt:sig_count='64'
+owrt:sigs='ZERO HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS'
+owrt:sig_name_extra='IOT CLD POLL UNUSED'
+owrt:sig_num_extra='6 17 29 31'
# Set the version here
PERL_REVISION=5
-PERL_VERSION=28
-PERL_SUBVERSION=1
+PERL_VERSION=38
+PERL_SUBVERSION=2
# (api_revison, api_version, api_subversion) = (revision, version, 0) usually
PERL_API_REVISION=5
-PERL_API_VERSION=28
+PERL_API_VERSION=38
PERL_API_SUBVERSION=0
-known_extensions='B Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/DProf Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/Glob Filter/Util/Call GDBM_File Hash/Util I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc NDBM_File ODBM_File Opcode POSIX PerlIO/encoding PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Text/Soundex Time/HiRes Time/Piece Unicode/Normalize Win32 Win32API/File Win32CORE XS/APItest XS/Typemap attrs re threads threads/shared Hash/Util/FieldHash'
-extensions='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate XS/APItest XS/Typemap arybase attributes mro re threads threads/shared Archive/Tar Attribute/Handlers AutoLoader B/Debug CPAN CPAN/Meta CPAN/Meta/Requirements CPAN/Meta/YAML Carp Config/Perl/V Devel/SelfStubber Digest Dumpvalue Env Errno Exporter ExtUtils/CBuilder ExtUtils/Command ExtUtils/Constant ExtUtils/Install ExtUtils/MakeMaker ExtUtils/Manifest ExtUtils/Miniperl ExtUtils/ParseXS File/Fetch File/Find File/Path File/Temp FileCache Filter/Simple Getopt/Long HTTP/Tiny I18N/Collate I18N/LangTags IO/Compress IO/Socket/IP IO/Zlib IPC/Cmd IPC/Open3 JSON/PP Locale/Codes Locale/Maketext Locale/Maketext/Simple Math/BigInt Math/BigRat Math/Complex Memoize Module/CoreList Module/Load Module/Load/Conditional Module/Loaded Module/Metadata NEXT Net/Ping Params/Check Parse/CPAN/Meta Perl/OSType PerlIO/via/QuotedPrint Pod/Checker Pod/Escapes Pod/Functions Pod/Html Pod/Parser Pod/Perldoc Pod/Simple Pod/Usage Safe Search/Dict SelfLoader Term/ANSIColor Term/Cap Term/Complete Term/ReadLine Test Test/Harness Test/Simple Text/Abbrev Text/Balanced Text/ParseWords Text/Tabs Thread/Queue Thread/Semaphore Tie/File Tie/Memoize Tie/RefHash Time/Local XSLoader autodie autouse base bignum constant encoding/warnings experimental if lib libnet parent perlfaq podlators Unicode/Normalize version'
-nonxs_ext='Archive/Tar Attribute/Handlers AutoLoader B/Debug CPAN CPAN/Meta CPAN/Meta/Requirements CPAN/Meta/YAML Carp Config/Perl/V Devel/SelfStubber Digest Dumpvalue Env Errno Exporter ExtUtils/CBuilder ExtUtils/Command ExtUtils/Constant ExtUtils/Install ExtUtils/MakeMaker ExtUtils/Manifest ExtUtils/Miniperl ExtUtils/ParseXS File/Fetch File/Find File/Path File/Temp FileCache Filter/Simple Getopt/Long HTTP/Tiny I18N/Collate I18N/LangTags IO/Compress IO/Socket/IP IO/Zlib IPC/Cmd IPC/Open3 JSON/PP Locale/Codes Locale/Maketext Locale/Maketext/Simple Math/BigInt Math/BigRat Math/Complex Memoize Module/CoreList Module/Load Module/Load/Conditional Module/Loaded Module/Metadata NEXT Net/Ping Params/Check Parse/CPAN/Meta Perl/OSType PerlIO/via/QuotedPrint Pod/Checker Pod/Escapes Pod/Functions Pod/Html Pod/Parser Pod/Perldoc Pod/Simple Pod/Usage Safe Search/Dict SelfLoader Term/ANSIColor Term/Cap Term/Complete Term/ReadLine Test Test/Harness Test/Simple Text/Abbrev Text/Balanced Text/ParseWords Text/Tabs Thread/Queue Thread/Semaphore Tie/File Tie/Memoize Tie/RefHash Time/Local XSLoader autodie autouse base bignum constant encoding/warnings experimental if lib libnet parent perlfaq podlators Unicode/Normalize version'
-dynamic_ext='B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd DB_File Data/Dumper Devel/PPPort Devel/Peek Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util MIME/Base64 Math/BigInt/FastCalc Opcode POSIX PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via SDBM_File Socket Storable Sys/Hostname Sys/Syslog Tie/Hash/NamedCapture Time/HiRes Time/Piece Unicode/Collate XS/APItest XS/Typemap arybase attributes mro re threads threads/shared'
+dynamic_ext='attributes B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd Data/Dumper DB_File Devel/Peek Devel/PPPort Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call GDBM_File Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util Math/BigInt/FastCalc MIME/Base64 mro Opcode PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via POSIX re SDBM_File Socket Storable Sys/Hostname Sys/Syslog threads threads/shared Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap'
+extensions='attributes B Compress/Raw/Bzip2 Compress/Raw/Zlib Cwd Data/Dumper DB_File Devel/Peek Devel/PPPort Digest/MD5 Digest/SHA Encode Fcntl File/DosGlob File/Glob Filter/Util/Call Hash/Util Hash/Util/FieldHash I18N/Langinfo IO IPC/SysV List/Util Math/BigInt/FastCalc MIME/Base64 mro Opcode PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via POSIX re SDBM_File Socket Storable Sys/Hostname Sys/Syslog threads threads/shared Time/HiRes Time/Piece Unicode/Collate Unicode/Normalize XS/APItest XS/Typemap Archive/Tar Attribute/Handlers autodie AutoLoader autouse base bignum Carp Config/Perl/V constant CPAN CPAN/Meta CPAN/Meta/Requirements CPAN/Meta/YAML Devel/SelfStubber Digest Dumpvalue encoding/warnings Env Errno experimental Exporter ExtUtils/CBuilder ExtUtils/Constant ExtUtils/Install ExtUtils/MakeMaker ExtUtils/Manifest ExtUtils/Miniperl ExtUtils/ParseXS ExtUtils/PL2Bat FileCache File/Fetch File/Find File/Path File/Temp Filter/Simple FindBin GDBM_File Getopt/Long HTTP/Tiny I18N/Collate I18N/LangTags if IO/Compress IO/Socket/IP IO/Zlib IPC/Cmd IPC/Open3 JSON/PP lib libnet Locale/Maketext Locale/Maketext/Simple Math/BigInt Math/BigRat Math/Complex Memoize Module/CoreList Module/Load Module/Load/Conditional Module/Loaded Module/Metadata Net/Ping NEXT Params/Check parent perlfaq PerlIO/via/QuotedPrint Perl/OSType Pod/Checker Pod/Escapes Pod/Functions Pod/Html podlators Pod/Perldoc Pod/Simple Pod/Usage Safe Search/Dict SelfLoader Term/ANSIColor Term/Cap Term/Complete Term/ReadLine Test Test/Harness Test/Simple Text/Abbrev Text/Balanced Text/ParseWords Text/Tabs Thread/Queue Thread/Semaphore Tie/File Tie/Hash/NamedCapture Tie/Memoize Tie/RefHash Time/Local version XSLoader'
+known_extensions='Amiga/ARexx Amiga/Exec Archive/Tar Attribute/Handlers attributes autodie AutoLoader autouse B base bignum Carp Compress/Raw/Bzip2 Compress/Raw/Zlib Config/Perl/V constant CPAN CPAN/Meta CPAN/Meta/Requirements CPAN/Meta/YAML Cwd Data/Dumper DB_File Devel/Peek Devel/PPPort Devel/SelfStubber Digest Digest/MD5 Digest/SHA Dumpvalue Encode encoding/warnings Env Errno experimental Exporter ExtUtils/CBuilder ExtUtils/Constant ExtUtils/Install ExtUtils/MakeMaker ExtUtils/Manifest ExtUtils/Miniperl ExtUtils/ParseXS ExtUtils/PL2Bat Fcntl FileCache File/DosGlob File/Fetch File/Find File/Glob File/Path File/Temp Filter/Simple Filter/Util/Call FindBin GDBM_File Getopt/Long Hash/Util Hash/Util/FieldHash HTTP/Tiny I18N/Collate I18N/Langinfo I18N/LangTags if IO IO/Compress IO/Socket/IP IO/Zlib IPC/Cmd IPC/Open3 IPC/SysV JSON/PP lib libnet List/Util Locale/Maketext Locale/Maketext/Simple Math/BigInt Math/BigInt/FastCalc Math/BigRat Math/Complex Memoize MIME/Base64 Module/CoreList Module/Load Module/Load/Conditional Module/Loaded Module/Metadata mro NDBM_File Net/Ping NEXT ODBM_File Opcode Params/Check parent perlfaq PerlIO/encoding PerlIO/mmap PerlIO/scalar PerlIO/via PerlIO/via/QuotedPrint Perl/OSType Pod/Checker Pod/Escapes Pod/Functions Pod/Html podlators Pod/Perldoc Pod/Simple Pod/Usage POSIX re Safe SDBM_File Search/Dict SelfLoader Socket Storable Sys/Hostname Sys/Syslog Term/ANSIColor Term/Cap Term/Complete Term/ReadLine Test Test/Harness Test/Simple Text/Abbrev Text/Balanced Text/ParseWords Text/Tabs Thread/Queue threads Thread/Semaphore threads/shared Tie/File Tie/Hash/NamedCapture Tie/Memoize Tie/RefHash Time/HiRes Time/Local Time/Piece Unicode/Collate Unicode/Normalize version VMS/DCLsym VMS/Filespec VMS/Stdio Win32 Win32API/File Win32CORE XS/APItest XSLoader XS/Typemap'
+nonxs_ext='Archive/Tar Attribute/Handlers autodie AutoLoader autouse base bignum Carp Config/Perl/V constant CPAN CPAN/Meta CPAN/Meta/Requirements CPAN/Meta/YAML Devel/SelfStubber Digest Dumpvalue encoding/warnings Env Errno experimental Exporter ExtUtils/CBuilder ExtUtils/Constant ExtUtils/Install ExtUtils/MakeMaker ExtUtils/Manifest ExtUtils/Miniperl ExtUtils/ParseXS ExtUtils/PL2Bat FileCache File/Fetch File/Find File/Path File/Temp Filter/Simple FindBin Getopt/Long HTTP/Tiny I18N/Collate I18N/LangTags if IO/Compress IO/Socket/IP IO/Zlib IPC/Cmd IPC/Open3 JSON/PP lib libnet Locale/Maketext Locale/Maketext/Simple Math/BigInt Math/BigRat Math/Complex Memoize Module/CoreList Module/Load Module/Load/Conditional Module/Loaded Module/Metadata Net/Ping NEXT Params/Check parent perlfaq PerlIO/via/QuotedPrint Perl/OSType Pod/Checker Pod/Escapes Pod/Functions Pod/Html podlators Pod/Perldoc Pod/Simple Pod/Usage Safe Search/Dict SelfLoader Term/ANSIColor Term/Cap Term/Complete Term/ReadLine Test Test/Harness Test/Simple Text/Abbrev Text/Balanced Text/ParseWords Text/Tabs Thread/Queue Thread/Semaphore Tie/File Tie/Hash/NamedCapture Tie/Memoize Tie/RefHash Time/Local version XSLoader'
# No need to change anything from here on
owrt:perllibpath="/usr/lib/perl5/$PERL_REVISION.$PERL_VERSION"
+++ /dev/null
---- a/hints/darwin.sh
-+++ b/hints/darwin.sh
-@@ -301,7 +301,7 @@ case "$osvers" in # Note: osvers is the
- # We now use MACOSX_DEPLOYMENT_TARGET, if set, as an override by
- # capturing its value and adding it to the flags.
- case "$MACOSX_DEPLOYMENT_TARGET" in
-- 10.*)
-+ [1-9][0-9].*)
- add_macosx_version_min ccflags $MACOSX_DEPLOYMENT_TARGET
- add_macosx_version_min ldflags $MACOSX_DEPLOYMENT_TARGET
- ;;
-@@ -313,7 +313,7 @@ case "$osvers" in # Note: osvers is the
-
- *** Unexpected MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET
- ***
--*** Please either set it to 10.something, or to empty.
-+*** Please either set it to a valid macOS version number (e.g., 10.15) or to empty.
-
- EOM
- exit 1
-@@ -327,7 +327,7 @@ EOM
- # "ProductVersion: 10.11" "10.11"
- prodvers=`sw_vers|awk '/^ProductVersion:/{print $2}'|awk -F. '{print $1"."$2}'`
- case "$prodvers" in
-- 10.*)
-+ [1-9][0-9].*)
- add_macosx_version_min ccflags $prodvers
- add_macosx_version_min ldflags $prodvers
- ;;
+++ /dev/null
-From 15f67d146cf1f32504e8a11de3faa2abc0f467cd Mon Sep 17 00:00:00 2001
-From: Tony Cook <tony@develop-help.com>
-Date: Mon, 25 Mar 2019 16:48:40 +1100
-Subject: [PATCH] (perl #133951) add Internals::getcwd
-
----
- MANIFEST | 1 +
- t/io/getcwd.t | 22 ++++++++++++++++++++++
- universal.c | 22 ++++++++++++++++++++++
- 3 files changed, 45 insertions(+)
- create mode 100644 t/io/getcwd.t
-
---- a/MANIFEST
-+++ b/MANIFEST
-@@ -5456,6 +5456,7 @@ t/io/errno.t See if $! is correctly se
- t/io/errnosig.t Test case for restoration $! when leaving signal handlers
- t/io/fflush.t See if auto-flush on fork/exec/system/qx works
- t/io/fs.t See if directory manipulations work
-+t/io/getcwd.t See if Internals::getcwd is sane
- t/io/inplace.t See if inplace editing works
- t/io/iofile.t See if we can load IO::File on demand
- t/io/iprefix.t See if inplace editing works with prefixes
---- /dev/null
-+++ b/t/io/getcwd.t
-@@ -0,0 +1,22 @@
-+#!./perl -w
-+
-+BEGIN {
-+ chdir 't' if -d 't';
-+ require "./test.pl";
-+ set_up_inc('../lib');
-+}
-+
-+use Config;
-+
-+$Config{d_getcwd}
-+ or plan skip_all => "no getcwd";
-+
-+my $cwd = Internals::getcwd();
-+ok(!defined $cwd || $cwd ne "",
-+ "Internals::getcwd() returned a reasonable result");
-+
-+if (defined $cwd) {
-+ ok(-d $cwd, "check a success result is a directory");
-+}
-+
-+done_testing();
---- a/universal.c
-+++ b/universal.c
-@@ -986,6 +986,25 @@ XS(XS_re_regexp_pattern)
- NOT_REACHED; /* NOTREACHED */
- }
-
-+#ifdef HAS_GETCWD
-+
-+XS(XS_Internals_getcwd)
-+{
-+ dXSARGS;
-+ SV *sv = sv_newmortal();
-+
-+ if (items != 0)
-+ croak_xs_usage(cv, "");
-+
-+ (void)getcwd_sv(sv);
-+
-+ SvTAINTED_on(sv);
-+ PUSHs(sv);
-+ XSRETURN(1);
-+}
-+
-+#endif
-+
- #include "vutil.h"
- #include "vxs.inc"
-
-@@ -1020,6 +1039,9 @@ static const struct xsub_details details
- {"re::regnames", XS_re_regnames, ";$"},
- {"re::regnames_count", XS_re_regnames_count, ""},
- {"re::regexp_pattern", XS_re_regexp_pattern, "$"},
-+#ifdef HAS_GETCWD
-+ {"Internals::getcwd", XS_Internals_getcwd, ""},
-+#endif
- };
-
- STATIC OP*
+++ /dev/null
---- a/dist/PathTools/Cwd.pm
-+++ b/dist/PathTools/Cwd.pm
-@@ -659,6 +659,10 @@ if (exists $METHOD_MAP{$^O}) {
- }
- }
-
-+# built-in from 5.30
-+*getcwd = \&Internals::getcwd
-+ if !defined &getcwd && defined &Internals::getcwd;
-+
- # In case the XS version doesn't load.
- *abs_path = \&_perl_abs_path unless defined &abs_path;
- *getcwd = \&_perl_getcwd unless defined &getcwd;
---- a/dist/PathTools/t/cwd.t
-+++ b/dist/PathTools/t/cwd.t
-@@ -10,6 +10,7 @@ chdir 't';
- use Config;
- use File::Spec;
- use File::Path;
-+use Errno qw(EACCES);
-
- use lib File::Spec->catdir('t', 'lib');
- use Test::More;
-@@ -208,7 +209,15 @@ SKIP: {
-
- like($abs_path, qr|$want$|i, "Cwd::abs_path produced $abs_path");
- like($fast_abs_path, qr|$want$|i, "Cwd::fast_abs_path produced $fast_abs_path");
-- like($pas, qr|$want$|i, "Cwd::_perl_abs_path produced $pas") if $EXTRA_ABSPATH_TESTS;
-+ if ($EXTRA_ABSPATH_TESTS) {
-+ # _perl_abs_path() can fail if some ancestor directory isn't readable
-+ if (defined $pas) {
-+ like($pas, qr|$want$|i, "Cwd::_perl_abs_path produced $pas");
-+ }
-+ else {
-+ is($!+0, EACCES, "check we got the expected error on failure");
-+ }
-+ }
-
- rmtree($test_dirs[0], 0, 0);
- 1 while unlink $file;
--- a/perl.c
+++ b/perl.c
-@@ -303,7 +303,7 @@ perl_construct(pTHXx)
+@@ -317,7 +317,7 @@ perl_construct(pTHXx)
PL_localpatches = local_patches; /* For possible -v */
#endif
+++ /dev/null
-From 682a4acb98783a7f9b5c286b308f12863599fec3 Mon Sep 17 00:00:00 2001
-From: Tony Cook <tony@develop-help.com>
-Date: Mon, 30 Jul 2018 21:00:52 +1000
-Subject: (perl #133411) don't try to load Storable with -Dusecrosscompile
-
----
- dist/Storable/Makefile.PL | 9 ++++++++-
- dist/Storable/stacksize | 10 +++++++---
- 2 files changed, 15 insertions(+), 4 deletions(-)
-
---- a/dist/Storable/Makefile.PL
-+++ b/dist/Storable/Makefile.PL
-@@ -90,12 +90,19 @@ sub depend {
- # blib.pm needs arch/lib
- $extra_deps = ' Storable.pm';
- }
-+ my $whichperl;
-+ if ($Config::Config{usecrosscompile}) {
-+ $whichperl = '$(PERLRUN)';
-+ }
-+ else {
-+ $whichperl = '$(FULLPERLRUNINST)';
-+ }
- my $linktype = uc($_[0]->{LINKTYPE});
- my $limit_pm = File::Spec->catfile('lib', 'Storable', 'Limit.pm');
- "
- $limit_pm : stacksize \$(INST_$linktype)$extra_deps
- \$(MKPATH) \$(INST_LIB)
-- \$(FULLPERLRUNINST) stacksize $options
-+ $whichperl stacksize $options
-
- release : dist
- git tag \$(VERSION)
---- a/dist/Storable/stacksize
-+++ b/dist/Storable/stacksize
-@@ -7,6 +7,9 @@ use Cwd;
- use File::Spec;
- use strict;
-
-+-d "lib" or mkdir "lib";
-+-d "lib/Storable" or mkdir "lib/Storable";
-+
- my $fn = "lib/Storable/Limit.pm";
- my $ptrsize = $Config{ptrsize};
- my ($bad1, $bad2) = (65001, 25000);
-@@ -29,6 +32,10 @@ sub is_miniperl {
- }
-
- if (is_miniperl()) {
-+ if ($Config{usecrosscompile}) {
-+ write_limits(500, 265);
-+ exit;
-+ }
- die "Should not run during miniperl\n";
- }
- my $prefix = "";
-@@ -68,9 +75,6 @@ if ($ENV{PERL_CORE}) {
- }
- }
-
---d "lib" or mkdir "lib";
---d "lib/Storable" or mkdir "lib/Storable";
--
- if ($^O eq "MSWin32") {
- require Win32;
- my ($str, $major, $minor) = Win32::GetOSVersion();
--- a/Makefile.SH
+++ b/Makefile.SH
-@@ -339,22 +339,11 @@ MANIFEST_SRT = MANIFEST.srt
-
- !GROK!THIS!
+@@ -360,22 +360,11 @@ PERL_EXE_LDFLAGS=$exeldflags
+ ;;
+ esac
-case "$usecrosscompile$perl" in
-define?*)
--- a/perl.c
+++ b/perl.c
-@@ -1987,16 +1987,6 @@ S_Internals_V(pTHX_ CV *cv)
+@@ -2098,16 +2098,6 @@ S_Internals_V(pTHX_ CV *cv)
PUSHs(Perl_newSVpvn_flags(aTHX_ non_bincompat_options,
- sizeof(non_bincompat_options) - 1, SVs_TEMP));
+ sizeof(non_bincompat_options) - 1, SVs_TEMP));
-#ifndef PERL_BUILD_DATE
-# ifdef __DATE__
-
#ifdef PERL_BUILD_DATE
PUSHs(Perl_newSVpvn_flags(aTHX_
- STR_WITH_LEN("Compiled at " PERL_BUILD_DATE),
+ STR_WITH_LEN("Compiled at " PERL_BUILD_DATE),
+++ /dev/null
---- a/cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_Unix.pm
-+++ b/cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_Unix.pm
-@@ -2738,14 +2738,14 @@ sub _find_static_libs {
-
- Called by a utility method of makeaperl. Checks whether a given file
- is an XS library by seeing whether it defines any symbols starting
--with C<boot_>.
-+with C<boot_> (with an optional leading underscore – needed on MacOS).
-
- =cut
-
- sub xs_static_lib_is_xs {
- my ($self, $libfile) = @_;
- my $devnull = File::Spec->devnull;
-- return `nm $libfile 2>$devnull` =~ /\bboot_/;
-+ return `nm $libfile 2>$devnull` =~ /\b_?boot_/;
- }
-
- =item makefile (o)
--- a/cpan/podlators/Makefile.PL
+++ b/cpan/podlators/Makefile.PL
-@@ -18,6 +18,19 @@ use Config;
- use ExtUtils::MakeMaker;
- use File::Spec;
+@@ -39,6 +39,19 @@ sub dist_version {
+ die "$0: cannot find version in lib/Pod/Man.pm\n";
+ }
+foreach (glob('scripts/pod*.PL')) {
+ # The various pod*.PL extractors change directory. Doing that with relative
# Generate full paths for scripts distributed in the bin directory. Appends
# the .com extension to scripts on VMS, unless they already have the .PL
# extension.
-@@ -28,7 +41,7 @@ use File::Spec;
+@@ -49,7 +62,7 @@ sub dist_version {
# (Scalar) Space-separated relative paths from top of distribution
sub scripts {
my (@scripts) = @_;
if ($^O eq 'VMS') {
@paths = map { m{ [.] PL \z }xms ? $_ : $_ . '.com' } @paths;
}
-@@ -77,8 +90,8 @@ my %metadata = (
+@@ -101,8 +114,8 @@ my %metadata = (
# Override the files that generate section 1 man pages.
MAN1PODS => {
--- a/Makefile.SH
+++ b/Makefile.SH
-@@ -275,6 +275,7 @@ LNS = $lns
+@@ -289,6 +289,7 @@ LNS = $lns
# NOTE: some systems don't grok "cp -f". XXX Configure test needed?
CPS = $cp
RMS = rm -f
+RMS_R = rm -rf
ranlib = $ranlib
+ ECHO = $echo
- # The following are mentioned only to make metaconfig include the
-@@ -736,7 +737,7 @@ bitcount.h: generate_uudmap$(HOST_EXE_EX
+@@ -786,7 +787,7 @@ bitcount.h: generate_uudmap$(HOST_EXE_EX
./generate_uudmap$(HOST_EXE_EXT) $(generated_headers)
generate_uudmap$(HOST_EXE_EXT): generate_uudmap$(OBJ_EXT)
$(LNS) $(HOST_GENERATE) generate_uudmap$(HOST_EXE_EXT)
!NO!SUBS!
-@@ -876,26 +877,26 @@ mydtrace.h: $(DTRACE_H)
+@@ -891,26 +892,26 @@ mydtrace.h: $(DTRACE_H)
define)
$spitshell >>$Makefile <<'!NO!SUBS!'
$(DTRACE_MINI_O): perldtrace.d $(miniperl_objs_nodt)
!NO!SUBS!
;;
-@@ -906,13 +907,13 @@ $(LIBPERL): $& $(perllib_dep) $(DYNALOAD
+@@ -921,13 +922,13 @@ $(LIBPERL): $& $(perllib_dep) $(DYNALOAD
case "$useshrplib" in
true)
$spitshell >>$Makefile <<'!NO!SUBS!'
mv $@ libperl$(OBJ_EXT)
$(AR) qv $(LIBPERL) libperl$(OBJ_EXT)
!NO!SUBS!
-@@ -921,7 +922,7 @@ $(LIBPERL): $& $(perllib_dep) $(DYNALOAD
+@@ -936,7 +937,7 @@ $(LIBPERL): $& $(perllib_dep) $(DYNALOAD
;;
*)
$spitshell >>$Makefile <<'!NO!SUBS!'
$(AR) rc $(LIBPERL) $(perllib_objs) $(DYNALOADER)
@$(ranlib) $(LIBPERL)
!NO!SUBS!
-@@ -954,7 +955,7 @@ $(MINIPERL_EXE): lib/buildcustomize.pl
+@@ -970,7 +971,7 @@ $(MINIPERL_EXE): lib/buildcustomize.pl
amigaos*)
$spitshell >>$Makefile <<'!NO!SUBS!'
lib/buildcustomize.pl: $& $(miniperl_objs) write_buildcustomize.pl
+ @$(RMS) miniperl.xok
!NO!SUBS!
- case $osname in
-@@ -1119,8 +1120,8 @@ pod/perl5281delta.pod: pod/perldelta.pod
- $(LNS) perldelta.pod pod/perl5281delta.pod
+ case "$osname" in
+@@ -1133,8 +1134,8 @@ pod/perl5382delta.pod: pod/perldelta.pod
+ $(LNS) perldelta.pod pod/perl5382delta.pod
extra.pods: $(MINIPERL_EXE)
- -@test ! -f extra.pods || rm -f `cat extra.pods`
-@for x in `grep -l '^=[a-z]' README.* | grep -v README.vms` ; do \
nx=`echo $$x | sed -e "s/README\.//"`; \
$(LNS) ../$$x "pod/perl"$$nx".pod" ; \
-@@ -1340,11 +1341,11 @@ realclean: _realcleaner _mopup
+@@ -1334,11 +1335,11 @@ realclean: _realcleaner _mopup
@echo "Note that '$(MAKE) realclean' does not delete config.sh or Policy.sh"
_clobber:
clobber: _realcleaner _mopup _clobber
-@@ -1352,23 +1353,23 @@ distclean: clobber
+@@ -1346,24 +1347,24 @@ distclean: clobber
# Like distclean but also removes emacs backups and *.orig.
veryclean: _verycleaner _mopup _clobber
- -@rm -f Obsolete Wanted
-+ $(RMS) Obsolete Wanted
++ @$(RMS) Obsolete Wanted
# Do not 'make _mopup' directly.
_mopup:
-- rm -f *$(OBJ_EXT) *$(LIB_EXT) all perlmain.c opmini.c perlmini.c generate_uudmap$(EXE_EXT) $(generated_headers)
-+ $(RMS) *$(OBJ_EXT) *$(LIB_EXT) all perlmain.c opmini.c perlmini.c generate_uudmap$(EXE_EXT) $(generated_headers)
+- rm -f *$(OBJ_EXT) *$(LIB_EXT) all perlmain.c $(mini_only_src) generate_uudmap$(EXE_EXT) $(generated_headers)
++ $(RMS) *$(OBJ_EXT) *$(LIB_EXT) all perlmain.c $(mini_only_src) generate_uudmap$(EXE_EXT) $(generated_headers)
-rmdir .depending
+ -rm *.depends makedepend_file
- -@test -f extra.pods && rm -f `cat extra.pods`
- -@test -f vms/README_vms.pod && rm -f vms/README_vms.pod
-- -rm -f perl.exp ext.libs $(generated_pods) uni.data opmini.o perlmini.o pod/roffitall
+- -rm -f perl.exp ext.libs $(generated_pods) uni.data $(mini_only_objs) pod/roffitall
- -rm -f perl.export perl.dll perl.libexp perl.map perl.def
- -rm -f *perl.xok
- -rm -f cygwin.c libperl*.def libperl*.dll cygperl*.dll *.exe.stackdump
- -rm -f config.arch config.over $(DTRACE_H)
+ -@test -f extra.pods && $(RMS) `cat extra.pods`
+ -@test -f vms/README_vms.pod && $(RMS) vms/README_vms.pod
-+ $(RMS) perl.exp ext.libs $(generated_pods) uni.data opmini.o perlmini.o pod/roffitall
++ $(RMS) perl.exp ext.libs $(generated_pods) uni.data $(mini_only_objs) pod/roffitall
+ $(RMS) perl.export perl.dll perl.libexp perl.map perl.def
+ $(RMS) *perl.xok
+ $(RMS) cygwin.c libperl*.def libperl*.dll cygperl*.dll *.exe.stackdump
-cd pod; $(LDLIBPTH) $(MAKE) $(CLEAN)
-cd utils; $(LDLIBPTH) $(MAKE) $(CLEAN)
-@if test -f $(MINIPERL_EXE) ; then \
-@@ -1378,31 +1379,31 @@ _cleaner1:
+@@ -1373,8 +1374,8 @@ _cleaner1:
else \
sh $(CLEAN).sh ; \
fi
+ $(RMS) `grep -v ^# mkppport.lst | grep . | sed -e 's/$$/\/ppport.h/'`
# Dear POSIX, thanks for making the default to xargs to be
- # run once if nothhing is passed in. It is such a great help.
-
- # Some systems do not support "?", so keep these files separate.
+ # run once if nothing is passed in. It is such a great help.
+@@ -1389,24 +1390,24 @@ _cleaner1:
+ # Add new rules before that line - the next line (rm -f so_locations ...) is
+ # used as a placeholder by a regen script.
_cleaner2:
- -rm -f core.*perl.*.? t/core.perl.*.? .?*.c
- rm -f core *perl.core t/core t/*perl.core core.* t/core.*
+ $(RMS) pod2htmd.tmp
+ $(RMS_R) pod/perlfunc pod/perlipc
-rmdir ext/B/lib
-- rm -f so_locations $(LIBPERL_NONSHR) $(MINIPERL_NONSHR)
-+ $(RMS) so_locations $(LIBPERL_NONSHR) $(MINIPERL_NONSHR)
+- -rm -f dist/Time-HiRes/xdefine
+- rm -f so_locations $(LIBPERL_NONSHR)
++ $(RMS) dist/Time-HiRes/xdefine
++ $(RMS) so_locations $(LIBPERL_NONSHR)
-rmdir lib/version lib/threads lib/inc/ExtUtils lib/inc lib/encoding
-rmdir lib/autodie/exception lib/autodie/Scope lib/autodie lib/XS
-rmdir lib/Win32API lib/VMS lib/Unicode/Collate/Locale
-@@ -1452,11 +1453,11 @@ _realcleaner:
+@@ -1457,11 +1458,11 @@ _realcleaner:
_verycleaner:
@$(LDLIBPTH) $(MAKE) _cleaner1 CLEAN=veryclean
@$(LDLIBPTH) $(MAKE) _cleaner2
lint $(lintflags) -DPERL_CORE -D_REENTRANT -DDEBUGGING -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(c)
cscopeflags = -Rb # Recursive, build-only.
-@@ -1514,7 +1515,7 @@ case "$targethost" in
+@@ -1522,7 +1523,7 @@ case "$targethost" in
'') $spitshell >>$Makefile <<'!NO!SUBS!'
test_prep test-prep: test_prep_pre $(MINIPERL_EXE) $(unidatafiles) $(PERL_EXE) \
$(dynamic_ext) $(TEST_PERL_DLL) runtests $(generated_pods) common_build
!NO!SUBS!
;;
-@@ -1564,7 +1565,7 @@ test_prep test-prep: test_prep_pre \$(MI
+@@ -1572,7 +1573,7 @@ test_prep test-prep: test_prep_pre \$(MI
$to config.sh
# --- For lib/diagnostics.t with -Duseshrplib
$to \$(PERL_EXE)
$to t/\$(PERL_EXE)
!GROK!THIS!
-@@ -1574,7 +1575,7 @@ esac
+@@ -1582,7 +1583,7 @@ esac
$spitshell >>$Makefile <<'!NO!SUBS!'
test_prep_reonly: $(MINIPERL_EXE) $(PERL_EXE) $(dynamic_ext_re) $(TEST_PERL_DLL)
$(MINIPERL) make_ext.pl $(dynamic_ext_re) MAKE="$(MAKE)" LIBPERL_A=$(LIBPERL) LINKTYPE=dynamic
!NO!SUBS!
case "$targethost" in
-@@ -1629,7 +1630,7 @@ minitest_prep:
+@@ -1637,7 +1638,7 @@ minitest_prep: $(MINIPERL_EXE)
@echo "You may see some irrelevant test failures if you have been unable"
@echo "to build lib/Config.pm, or the Unicode data files."
@echo " "
-- - cd t && (rm -f $(PERL_EXE); $(LNS) ../$(MINIPERL_EXE) $(PERL_EXE))
-+ - cd t && ($(RMS) $(PERL_EXE); $(LNS) ../$(MINIPERL_EXE) $(PERL_EXE))
+- cd t && (rm -f $(PERL_EXE); $(LNS) ../$(MINIPERL_EXE) $(PERL_EXE))
++ cd t && ($(RMS) $(PERL_EXE); $(LNS) ../$(MINIPERL_EXE) $(PERL_EXE))
MINITEST_TESTS = base/*.t comp/*.t cmd/*.t run/*.t io/*.t re/*.t opbasic/*.t op/*.t uni/*.t perf/*.t
--- a/Makefile.SH
+++ b/Makefile.SH
-@@ -333,7 +333,7 @@ PATH_SEP = $p_
+@@ -346,7 +346,7 @@ OBJ_EXT = $_o
# Macros to invoke a copy of miniperl during the build. Targets which
# are built using these macros should depend on \$(MINIPERL_EXE)
MINIPERL_EXE = miniperl\$(EXE_EXT)
+++ /dev/null
-commit d36adde059ed1c4f7af210b4f9fc3a7bd2d7d343
-Author: Karl Williamson <khw@cpan.org>
-Date: Wed May 23 15:32:47 2018 -0600
-
- Fix to compile under -DNO_LOCALE
-
- Several problems with this compile option were not caught before 5.28
- was frozen.
-
---- a/embed.fnc
-+++ b/embed.fnc
-@@ -2793,9 +2793,11 @@ s |bool |isa_lookup |NN HV *stash|NN con
- #endif
-
- #if defined(PERL_IN_LOCALE_C)
-+# ifdef USE_LOCALE
- sn |const char*|category_name |const int category
- s |const char*|switch_category_locale_to_template|const int switch_category|const int template_category|NULLOK const char * template_locale
- s |void |restore_switched_locale|const int category|NULLOK const char * const original_locale
-+# endif
- # ifdef HAS_NL_LANGINFO
- sn |const char*|my_nl_langinfo|const nl_item item|bool toggle
- # else
---- a/embed.h
-+++ b/embed.h
-@@ -1796,16 +1796,16 @@
- #define unshare_hek_or_pvn(a,b,c,d) S_unshare_hek_or_pvn(aTHX_ a,b,c,d)
- # endif
- # if defined(PERL_IN_LOCALE_C)
--#define category_name S_category_name
--#define restore_switched_locale(a,b) S_restore_switched_locale(aTHX_ a,b)
- #define save_to_buffer S_save_to_buffer
--#define switch_category_locale_to_template(a,b,c) S_switch_category_locale_to_template(aTHX_ a,b,c)
- # if defined(USE_LOCALE)
-+#define category_name S_category_name
- #define new_collate(a) S_new_collate(aTHX_ a)
- #define new_ctype(a) S_new_ctype(aTHX_ a)
- #define new_numeric(a) S_new_numeric(aTHX_ a)
-+#define restore_switched_locale(a,b) S_restore_switched_locale(aTHX_ a,b)
- #define set_numeric_radix(a) S_set_numeric_radix(aTHX_ a)
- #define stdize_locale(a) S_stdize_locale(aTHX_ a)
-+#define switch_category_locale_to_template(a,b,c) S_switch_category_locale_to_template(aTHX_ a,b,c)
- # if defined(USE_POSIX_2008_LOCALE)
- #define emulate_setlocale S_emulate_setlocale
- # endif
---- a/locale.c
-+++ b/locale.c
-@@ -1264,6 +1264,7 @@ S_locking_setlocale(pTHX_
- }
-
- #endif
-+#ifdef USE_LOCALE
-
- STATIC void
- S_set_numeric_radix(pTHX_ const bool use_locale)
-@@ -1299,6 +1300,10 @@ S_set_numeric_radix(pTHX_ const bool use
- }
-
- # endif
-+#else
-+
-+ PERL_UNUSED_ARG(use_locale);
-+
- #endif /* USE_LOCALE_NUMERIC and can find the radix char */
-
- }
-@@ -1481,7 +1486,6 @@ S_new_ctype(pTHX_ const char *newctype)
-
- #ifndef USE_LOCALE_CTYPE
-
-- PERL_ARGS_ASSERT_NEW_CTYPE;
- PERL_UNUSED_ARG(newctype);
- PERL_UNUSED_CONTEXT;
-
-@@ -1994,6 +1998,8 @@ S_new_collate(pTHX_ const char *newcoll)
-
- }
-
-+#endif
-+
- #ifdef WIN32
-
- STATIC char *
-@@ -2139,11 +2145,20 @@ Perl_setlocale(const int category, const
- {
- /* This wraps POSIX::setlocale() */
-
-+#ifdef NO_LOCALE
-+
-+ PERL_UNUSED_ARG(category);
-+ PERL_UNUSED_ARG(locale);
-+
-+ return "C";
-+
-+#else
-+
- const char * retval;
- const char * newlocale;
- dSAVEDERRNO;
-- DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
- dTHX;
-+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
-
- #ifdef USE_LOCALE_NUMERIC
-
-@@ -2262,6 +2277,8 @@ Perl_setlocale(const int category, const
-
- return retval;
-
-+#endif
-+
- }
-
- PERL_STATIC_INLINE const char *
-@@ -2414,13 +2431,16 @@ S_my_nl_langinfo(const int item, bool to
- dTHX;
- const char * retval;
-
-+#ifdef USE_LOCALE_NUMERIC
-+
- /* We only need to toggle into the underlying LC_NUMERIC locale for these
- * two items, and only if not already there */
- if (toggle && (( item != RADIXCHAR && item != THOUSEP)
- || PL_numeric_underlying))
-- {
-+
-+#endif /* No toggling needed if not using LC_NUMERIC */
-+
- toggle = FALSE;
-- }
-
- #if defined(HAS_NL_LANGINFO) /* nl_langinfo() is available. */
- # if ! defined(HAS_THREAD_SAFE_NL_LANGINFO_L) \
-@@ -2468,6 +2488,8 @@ S_my_nl_langinfo(const int item, bool to
- do_free = TRUE;
- }
-
-+# ifdef USE_LOCALE_NUMERIC
-+
- if (toggle) {
- if (PL_underlying_numeric_obj) {
- cur = PL_underlying_numeric_obj;
-@@ -2478,6 +2500,8 @@ S_my_nl_langinfo(const int item, bool to
- }
- }
-
-+# endif
-+
- /* We have to save it to a buffer, because the freelocale() just below
- * can invalidate the internal one */
- retval = save_to_buffer(nl_langinfo_l(item, cur),
-@@ -5169,9 +5193,7 @@ Perl_my_strerror(pTHX_ const int errnum)
- LOCALE_UNLOCK;
-
- # endif /* End of doesn't have strerror_l */
--#endif /* End of does have locale messages */
--
--#ifdef DEBUGGING
-+# ifdef DEBUGGING
-
- if (DEBUG_Lv_TEST) {
- PerlIO_printf(Perl_debug_log, "Strerror returned; saving a copy: '");
-@@ -5179,7 +5201,8 @@ Perl_my_strerror(pTHX_ const int errnum)
- PerlIO_printf(Perl_debug_log, "'\n");
- }
-
--#endif
-+# endif
-+#endif /* End of does have locale messages */
-
- SAVEFREEPV(errstr);
- return errstr;
-@@ -5301,10 +5324,17 @@ L<C<Perl_switch_to_global_locale>|perlap
- bool
- Perl_sync_locale()
- {
-+
-+#ifndef USE_LOCALE
-+
-+ return TRUE;
-+
-+#else
-+
- const char * newlocale;
- dTHX;
-
--#ifdef USE_POSIX_2008_LOCALE
-+# ifdef USE_POSIX_2008_LOCALE
-
- bool was_in_global_locale = FALSE;
- locale_t cur_obj = uselocale((locale_t) 0);
-@@ -5316,11 +5346,11 @@ Perl_sync_locale()
- * will affect the */
- if (cur_obj == LC_GLOBAL_LOCALE) {
-
--# ifdef HAS_QUERY_LOCALE
-+# ifdef HAS_QUERY_LOCALE
-
- do_setlocale_c(LC_ALL, setlocale(LC_ALL, NULL));
-
--# else
-+# else
-
- unsigned int i;
-
-@@ -5330,17 +5360,17 @@ Perl_sync_locale()
- do_setlocale_r(categories[i], setlocale(categories[i], NULL));
- }
-
--# endif
-+# endif
-
- was_in_global_locale = TRUE;
- }
-
--#else
-+# else
-
- bool was_in_global_locale = TRUE;
-
--#endif
--#ifdef USE_LOCALE_CTYPE
-+# endif
-+# ifdef USE_LOCALE_CTYPE
-
- newlocale = savepv(do_setlocale_c(LC_CTYPE, NULL));
- DEBUG_Lv(PerlIO_printf(Perl_debug_log,
-@@ -5349,8 +5379,8 @@ Perl_sync_locale()
- new_ctype(newlocale);
- Safefree(newlocale);
-
--#endif /* USE_LOCALE_CTYPE */
--#ifdef USE_LOCALE_COLLATE
-+# endif /* USE_LOCALE_CTYPE */
-+# ifdef USE_LOCALE_COLLATE
-
- newlocale = savepv(do_setlocale_c(LC_COLLATE, NULL));
- DEBUG_Lv(PerlIO_printf(Perl_debug_log,
-@@ -5359,8 +5389,8 @@ Perl_sync_locale()
- new_collate(newlocale);
- Safefree(newlocale);
-
--#endif
--#ifdef USE_LOCALE_NUMERIC
-+# endif
-+# ifdef USE_LOCALE_NUMERIC
-
- newlocale = savepv(do_setlocale_c(LC_NUMERIC, NULL));
- DEBUG_Lv(PerlIO_printf(Perl_debug_log,
-@@ -5369,9 +5399,12 @@ Perl_sync_locale()
- new_numeric(newlocale);
- Safefree(newlocale);
-
--#endif /* USE_LOCALE_NUMERIC */
-+# endif /* USE_LOCALE_NUMERIC */
-
- return was_in_global_locale;
-+
-+#endif
-+
- }
-
- #if defined(DEBUGGING) && defined(USE_LOCALE)
---- a/makedef.pl
-+++ b/makedef.pl
-@@ -574,6 +574,9 @@ unless ($define{USE_LOCALE_COLLATE}) {
- PL_collxfrm_mult
- Perl_sv_collxfrm
- Perl_sv_collxfrm_flags
-+ PL_strxfrm_NUL_replacement
-+ PL_strxfrm_is_behaved
-+ PL_strxfrm_max_cp
- );
- }
-
-@@ -583,6 +586,9 @@ unless ($define{USE_LOCALE_NUMERIC}) {
- PL_numeric_name
- PL_numeric_radix_sv
- PL_numeric_standard
-+ PL_numeric_underlying
-+ PL_numeric_underlying_is_standard
-+ PL_underlying_numeric_obj
- );
- }
-
---- a/perl.h
-+++ b/perl.h
-@@ -5656,6 +5656,9 @@ typedef struct am_table_short AMTS;
- # define IN_LC_COMPILETIME(category) 0
- # define IN_LC_RUNTIME(category) 0
- # define IN_LC(category) 0
-+# define _CHECK_AND_WARN_PROBLEMATIC_LOCALE
-+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG(s, send)
-+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_CP_MSG(c)
- #endif
-
-
---- a/proto.h
-+++ b/proto.h
-@@ -4886,8 +4886,6 @@ PERL_CALLCONV SV* Perl_hfree_next_entry(
- assert(hv); assert(indexp)
- #endif
- #if defined(PERL_IN_LOCALE_C)
--STATIC const char* S_category_name(const int category);
--STATIC void S_restore_switched_locale(pTHX_ const int category, const char * const original_locale);
- #ifndef PERL_NO_INLINE_FUNCTIONS
- PERL_STATIC_INLINE const char * S_save_to_buffer(const char * string, char **buf, Size_t *buf_size, const Size_t offset)
- __attribute__warn_unused_result__;
-@@ -4895,17 +4893,19 @@ PERL_STATIC_INLINE const char * S_save_t
- assert(buf_size)
- #endif
-
--STATIC const char* S_switch_category_locale_to_template(pTHX_ const int switch_category, const int template_category, const char * template_locale);
- # if defined(USE_LOCALE)
-+STATIC const char* S_category_name(const int category);
- STATIC void S_new_collate(pTHX_ const char* newcoll);
- STATIC void S_new_ctype(pTHX_ const char* newctype);
- #define PERL_ARGS_ASSERT_NEW_CTYPE \
- assert(newctype)
- STATIC void S_new_numeric(pTHX_ const char* newnum);
-+STATIC void S_restore_switched_locale(pTHX_ const int category, const char * const original_locale);
- STATIC void S_set_numeric_radix(pTHX_ const bool use_locale);
- STATIC char* S_stdize_locale(pTHX_ char* locs);
- #define PERL_ARGS_ASSERT_STDIZE_LOCALE \
- assert(locs)
-+STATIC const char* S_switch_category_locale_to_template(pTHX_ const int switch_category, const int template_category, const char * template_locale);
- # if defined(USE_POSIX_2008_LOCALE)
- STATIC const char* S_emulate_setlocale(const int category, const char* locale, unsigned int index, const bool is_index_valid);
- # endif
---- a/sv.c
-+++ b/sv.c
-@@ -13330,10 +13330,15 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const s
-
- SvTAINT(sv);
-
-+#ifdef USE_LOCALE_NUMERIC
-+
- if (lc_numeric_set) {
- RESTORE_LC_NUMERIC(); /* Done outside loop, so don't have to
- save/restore each iteration. */
- }
-+
-+#endif
-+
- }
-
- /* =========================================================================
---- a/t/lib/warnings/regexec
-+++ b/t/lib/warnings/regexec
-@@ -215,6 +215,10 @@ Use of \b{} or \B{} for non-UTF-8 locale
- Use of \b{} or \B{} for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 17.
- ########
- # NAME (?[ ]) in non-UTF-8 locale
-+require '../loc_tools.pl';
-+unless (locales_enabled()) {
-+ print("SKIPPED\n# locales not available\n"),exit;
-+}
- eval { require POSIX; POSIX->import("locale_h") };
- if ($@) {
- print("SKIPPED\n# no POSIX\n"),exit;
-@@ -229,14 +233,14 @@ setlocale(&POSIX::LC_CTYPE, "C");
- ":" =~ /(?[ \: ])/;
- no warnings 'locale';
- EXPECT
--Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 9.
--Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 9.
--Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 10.
--Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 10.
--Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 11.
--Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 11.
--Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 12.
--Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 12.
-+Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 13.
-+Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 13.
-+Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 14.
-+Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 14.
-+Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 15.
-+Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 15.
-+Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 16.
-+Use of (?[ ]) for non-UTF-8 locale is wrong. Assuming a UTF-8 locale at - line 16.
- ########
- # NAME (?[ ]) in UTF-8 locale
- require '../loc_tools.pl';
--- a/ext/Errno/Errno_pm.PL
+++ b/ext/Errno/Errno_pm.PL
-@@ -133,7 +133,7 @@ sub get_files {
+@@ -115,7 +115,7 @@ sub get_files {
# Some Linuxes have weird errno.hs which generate
# no #file or #line directives
- my ($linux_errno_h) = grep { -e $_ } map { "$_/errno.h" }
+ ($linux_errno_h) = grep { -e $_ } map { "$_/errno.h" }
- "$sysroot/usr/include", "$sysroot/usr/local/include",
+ "$sysroot/usr/include", "$sysroot/usr/local/include", "$sysroot/include",
- split / / => $Config{locincpth} or
- die "Cannot find errno.h";
- $file{$linux_errno_h} = 1;
+ split / / => $Config{locincpth};
+ }
+
+++ /dev/null
-From 6bd6308fcea3541e505651bf8e8127a4a03d22cd Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
-Date: Tue, 12 Nov 2019 09:19:18 +0100
-Subject: [PATCH] Adapt Configure to GCC version 10
-
-I got a notice from Jeff Law <law@redhat.com>:
-
- Your particular package fails its testsuite. This was ultimately
- tracked down to a Configure problem. The perl configure script treated
- gcc-10 as gcc-1 and turned on -fpcc-struct-return. This is an ABI
- changing flag and caused Perl to not be able to interact properly with
- the dbm libraries on the system leading to a segfault.
-
-His proposed patch corrected only this one instance of the version
-mismatch. Reading the Configure script revealed more issues. This
-patch fixes all of them I found.
-
----
- Configure | 14 +++++++-------
- cflags.SH | 2 +-
- 2 files changed, 8 insertions(+), 8 deletions(-)
-
---- a/Configure
-+++ b/Configure
-@@ -4689,7 +4689,7 @@ else
- fi
- $rm -f try try.*
- case "$gccversion" in
--1*) cpp=`./loc gcc-cpp $cpp $pth` ;;
-+1.*) cpp=`./loc gcc-cpp $cpp $pth` ;;
- esac
- case "$gccversion" in
- '') gccosandvers='' ;;
-@@ -4729,7 +4729,7 @@ esac
- # gcc 3.* complain about adding -Idirectories that they already know about,
- # so we will take those off from locincpth.
- case "$gccversion" in
--3*)
-+3.*)
- echo "main(){}">try.c
- for incdir in $locincpth; do
- warn=`$cc $ccflags -I$incdir -c try.c 2>&1 | \
-@@ -5455,13 +5455,13 @@ fi
- case "$hint" in
- default|recommended)
- case "$gccversion" in
-- 1*) dflt="$dflt -fpcc-struct-return" ;;
-+ 1.*) dflt="$dflt -fpcc-struct-return" ;;
- esac
- case "$optimize:$DEBUGGING" in
- *-g*:old) dflt="$dflt -DDEBUGGING";;
- esac
- case "$gccversion" in
-- 2*) if $test -d /etc/conf/kconfig.d &&
-+ 2.*) if $test -d /etc/conf/kconfig.d &&
- $contains _POSIX_VERSION $usrinc/sys/unistd.h >/dev/null 2>&1
- then
- # Interactive Systems (ISC) POSIX mode.
-@@ -5470,7 +5470,7 @@ default|recommended)
- ;;
- esac
- case "$gccversion" in
-- 1*) ;;
-+ 1.*) ;;
- 2.[0-8]*) ;;
- ?*) set strict-aliasing -fno-strict-aliasing
- eval $checkccflag
-@@ -5588,7 +5588,7 @@ case "$cppflags" in
- ;;
- esac
- case "$gccversion" in
--1*) cppflags="$cppflags -D__GNUC__"
-+1.*) cppflags="$cppflags -D__GNUC__"
- esac
- case "$mips_type" in
- '');;
-@@ -22957,7 +22957,7 @@ fi
-
- : add -D_FORTIFY_SOURCE if feasible and not already there
- case "$gccversion" in
--[4567].*) case "$optimize$ccflags" in
-+[456789].*|[1-9][0-9]*) case "$optimize$ccflags" in
- *-O*) case "$ccflags$cppsymbols" in
- *_FORTIFY_SOURCE=*) # Don't add it again.
- echo "You seem to have -D_FORTIFY_SOURCE already, not adding it." >&4
---- a/cflags.SH
-+++ b/cflags.SH
-@@ -156,7 +156,7 @@ esac
-
- case "$gccversion" in
- '') ;;
--[12]*) ;; # gcc versions 1 (gasp!) and 2 are not good for this.
-+[12].*) ;; # gcc versions 1 (gasp!) and 2 are not good for this.
- Intel*) ;; # # Is that you, Intel C++?
- #
- # NOTE 1: the -std=c89 without -pedantic is a bit pointless.
--- /dev/null
+From ba6e2c38aafc23cf114f3ba0d0ff3baead34328b Mon Sep 17 00:00:00 2001
+From: Yves Orton <demerphq@gmail.com>
+Date: Tue, 1 Aug 2023 23:12:46 +0200
+Subject: [PATCH] regcomp*.c, regexec.c - fixup regex engine build under
+ -Uusedl
+
+The regex engine is built a bit different from most of the perl
+codebase. It is compiled as part of the main libperl.so and it is
+also compiled (with DEBUGGING enabled) as part of the re extension.
+When perl itself is compiled with DEBUGGING enabled then the code
+in the re.so extension and the code in libperl.so is the same.
+
+This all works fine and dandy until you have a static build where the
+re.so is linked into libperl.so, which results in duplicate symbols
+being defined. These symbols come in two flaviours: "auxiliary" and
+"debugging" related symbols.
+
+We have basically three cases:
+
+1. USE_DYNAMIC_LOADING is defined. In this case we are doing a dynamic
+ build and re.so will be separate from libperl.so, so it even if this
+ is a DEBUGGING enabled build debug and auxiliary functions can be
+ compiled into *both* re.so and libperl.so. This is basically the
+ "standard build".
+
+2. USE_DYNAMIC_LOADING is not defined, and DEBUGGING is not defined
+ either. In this case auxiliary functions should only be compiled in
+ libperl.so, and the debug functions should only be compiled into
+ re.so
+
+3. USE_DYNAMIC_LOADING is not defined, and DEBUGGING *is* defined. In
+ this case auxiliary functions AND debug functions should only be
+ compiled into libperl.so
+
+It is possible to detect the different build options by looking at the
+defines 'USE_DYNAMIC_LOADING', 'PERL_EXT_RE_DEBUG' and
+'DEBUGGING_RE_ONLY'. 'USE_DYNAMIC_LOADING' is NOT defined when we are
+building a static perl. 'PERL_EXT_RE_DEBUG' is defined only when we are
+building re.so, and 'DEBUGGING_RE_ONLY' is defined only when we are
+building re.so in a perl that is not itself already a DEBUGGING enabled
+perl. The file ext/re/re_top.h responsible for setting up
+DEBUGGING_RE_ONLY.
+
+This patch uses 'PERL_EXT_RE_DEBUG', 'DEBUGGING_RE_ONLY' and
+'USE_DYNAMIC_LOADING' to define in regcomp.h two further define flags
+'PERL_RE_BUILD_DEBUG' and 'PERL_RE_BUILD_AUX'.
+
+The 'PERL_RE_BUILD_DEBUG' flag determines if the debugging functions
+should be compiled into libperl.so or re.so or both. The
+'PERL_RE_BUILD_AUX' flag determines if the auxiliary functions should be
+compiled into just libperl.so or into it and re.so. We then use these
+flags to guard the different types of functions so that we can build in
+all three modes without duplicate symbols.
+---
+ regcomp.c | 13 +-
+ regcomp.h | 14 ++-
+ regcomp_debug.c | 308 +++++++++++++++++++++++-----------------------
+ regcomp_invlist.c | 3 +-
+ regexec.c | 3 +-
+ 5 files changed, 181 insertions(+), 160 deletions(-)
+
+--- a/regcomp.c
++++ b/regcomp.c
+@@ -290,6 +290,7 @@ S_edit_distance(const UV* src,
+ /* END of edit_distance() stuff
+ * ========================================================= */
+
++#ifdef PERL_RE_BUILD_AUX
+ /* add a data member to the struct reg_data attached to this regex, it should
+ * always return a non-zero return. the 's' argument is the type of the items
+ * being added and the n is the number of items. The length of 's' should match
+@@ -340,6 +341,7 @@ Perl_reg_add_data(RExC_state_t* const pR
+ assert(count>0);
+ return count;
+ }
++#endif /* PERL_RE_BUILD_AUX */
+
+ /*XXX: todo make this not included in a non debugging perl, but appears to be
+ * used anyway there, in 'use re' */
+@@ -7443,6 +7445,7 @@ S_regatom(pTHX_ RExC_state_t *pRExC_stat
+ }
+
+
++#ifdef PERL_RE_BUILD_AUX
+ void
+ Perl_populate_anyof_bitmap_from_invlist(pTHX_ regnode *node, SV** invlist_ptr)
+ {
+@@ -7502,6 +7505,7 @@ Perl_populate_anyof_bitmap_from_invlist(
+ }
+ }
+ }
++#endif /* PERL_RE_BUILD_AUX */
+
+ /* Parse POSIX character classes: [[:foo:]], [[=foo=]], [[.foo.]].
+ Character classes ([:foo:]) can also be negated ([:^foo:]).
+@@ -9095,6 +9099,7 @@ S_dump_regex_sets_structures(pTHX_ RExC_
+ #undef IS_OPERATOR
+ #undef IS_OPERAND
+
++#ifdef PERL_RE_BUILD_AUX
+ void
+ Perl_add_above_Latin1_folds(pTHX_ RExC_state_t *pRExC_state, const U8 cp, SV** invlist)
+ {
+@@ -9182,6 +9187,8 @@ Perl_add_above_Latin1_folds(pTHX_ RExC_s
+ }
+ }
+ }
++#endif /* PERL_RE_BUILD_AUX */
++
+
+ STATIC void
+ S_output_posix_warnings(pTHX_ RExC_state_t *pRExC_state, AV* posix_warnings)
+@@ -12105,6 +12112,7 @@ S_optimize_regclass(pTHX_
+
+ #undef HAS_NONLOCALE_RUNTIME_PROPERTY_DEFINITION
+
++#ifdef PERL_RE_BUILD_AUX
+ void
+ Perl_set_ANYOF_arg(pTHX_ RExC_state_t* const pRExC_state,
+ regnode* const node,
+@@ -12261,6 +12269,7 @@ Perl_set_ANYOF_arg(pTHX_ RExC_state_t* c
+ RExC_rxi->data->data[n] = (void*)rv;
+ ARG1u_SET(node, n);
+ }
++#endif /* PERL_RE_BUILD_AUX */
+
+ SV *
+
+@@ -12999,6 +13008,8 @@ S_regtail_study(pTHX_ RExC_state_t *pREx
+ }
+ #endif
+
++
++#ifdef PERL_RE_BUILD_AUX
+ SV*
+ Perl_get_ANYOFM_contents(pTHX_ const regnode * n) {
+
+@@ -13047,7 +13058,7 @@ Perl_get_ANYOFHbbm_contents(pTHX_ const
+ UTF_CONTINUATION_MARK | 0));
+ return cp_list;
+ }
+-
++#endif /* PERL_RE_BUILD_AUX */
+
+
+ SV *
+--- a/regcomp.h
++++ b/regcomp.h
+@@ -1554,7 +1554,19 @@ typedef enum {
+ #define EVAL_OPTIMISTIC_FLAG 128
+ #define EVAL_FLAGS_MASK (EVAL_OPTIMISTIC_FLAG-1)
+
+-
++/* We define PERL_RE_BUILD_DEBUG if we are NOT compiling the re extension and
++ * we are under DEBUGGING, or if we are ARE compiling the re extension
++ * and this is not a DEBUGGING enabled build (identified by
++ * DEBUGGING_RE_ONLY being defined)
++ */
++#if ( defined(USE_DYNAMIC_LOADING) && defined(DEBUGGING)) || \
++ ( defined(PERL_EXT_RE_BUILD) && defined(DEBUGGING_RE_ONLY)) || \
++ (!defined(PERL_EXT_RE_BUILD) && defined(DEBUGGING))
++#define PERL_RE_BUILD_DEBUG
++#endif
++#if ( defined(USE_DYNAMIC_LOADING) || !defined(PERL_EXT_RE_BUILD) )
++#define PERL_RE_BUILD_AUX
++#endif
+
+ #endif /* PERL_REGCOMP_H_ */
+
+--- a/regcomp_debug.c
++++ b/regcomp_debug.c
+@@ -18,8 +18,7 @@
+ #include "unicode_constants.h"
+ #include "regcomp_internal.h"
+
+-#ifdef DEBUGGING
+-
++#ifdef PERL_RE_BUILD_DEBUG
+ int
+ Perl_re_printf(pTHX_ const char *fmt, ...)
+ {
+@@ -159,13 +158,160 @@ Perl_debug_peep(pTHX_ const char *str, c
+ });
+ }
+
+-#endif /* DEBUGGING */
++const regnode *
++Perl_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
++ const regnode *last, const regnode *plast,
++ SV* sv, I32 indent, U32 depth)
++{
++ const regnode *next;
++ const regnode *optstart= NULL;
++
++ RXi_GET_DECL(r, ri);
++ DECLARE_AND_GET_RE_DEBUG_FLAGS;
++
++ PERL_ARGS_ASSERT_DUMPUNTIL;
++
++#ifdef DEBUG_DUMPUNTIL
++ Perl_re_printf( aTHX_ "--- %d : %d - %d - %d\n", indent, node-start,
++ last ? last-start : 0, plast ? plast-start : 0);
++#endif
++
++ if (plast && plast < last)
++ last= plast;
++
++ while (node && (!last || node < last)) {
++ const U8 op = OP(node);
++
++ if (op == CLOSE || op == SRCLOSE || op == WHILEM)
++ indent--;
++ next = regnext((regnode *)node);
++ const regnode *after = regnode_after((regnode *)node,0);
++
++ /* Where, what. */
++ if (op == OPTIMIZED) {
++ if (!optstart && RE_DEBUG_FLAG(RE_DEBUG_COMPILE_OPTIMISE))
++ optstart = node;
++ else
++ goto after_print;
++ } else
++ CLEAR_OPTSTART;
++
++ regprop(r, sv, node, NULL, NULL);
++ Perl_re_printf( aTHX_ "%4" IVdf ":%*s%s", (IV)(node - start),
++ (int)(2*indent + 1), "", SvPVX_const(sv));
++
++ if (op != OPTIMIZED) {
++ if (next == NULL) /* Next ptr. */
++ Perl_re_printf( aTHX_ " (0)");
++ else if (REGNODE_TYPE(op) == BRANCH
++ && REGNODE_TYPE(OP(next)) != BRANCH )
++ Perl_re_printf( aTHX_ " (FAIL)");
++ else
++ Perl_re_printf( aTHX_ " (%" IVdf ")", (IV)(next - start));
++ Perl_re_printf( aTHX_ "\n");
++ }
++
++ after_print:
++ if (REGNODE_TYPE(op) == BRANCHJ) {
++ assert(next);
++ const regnode *nnode = (OP(next) == LONGJMP
++ ? regnext((regnode *)next)
++ : next);
++ if (last && nnode > last)
++ nnode = last;
++ DUMPUNTIL(after, nnode);
++ }
++ else if (REGNODE_TYPE(op) == BRANCH) {
++ assert(next);
++ DUMPUNTIL(after, next);
++ }
++ else if ( REGNODE_TYPE(op) == TRIE ) {
++ const regnode *this_trie = node;
++ const U32 n = ARG1u(node);
++ const reg_ac_data * const ac = op>=AHOCORASICK ?
++ (reg_ac_data *)ri->data->data[n] :
++ NULL;
++ const reg_trie_data * const trie =
++ (reg_trie_data*)ri->data->data[op<AHOCORASICK ? n : ac->trie];
++#ifdef DEBUGGING
++ AV *const trie_words
++ = MUTABLE_AV(ri->data->data[n + TRIE_WORDS_OFFSET]);
++#endif
++ const regnode *nextbranch= NULL;
++ I32 word_idx;
++ SvPVCLEAR(sv);
++ for (word_idx= 0; word_idx < (I32)trie->wordcount; word_idx++) {
++ SV ** const elem_ptr = av_fetch_simple(trie_words, word_idx, 0);
++
++ Perl_re_indentf( aTHX_ "%s ",
++ indent+3,
++ elem_ptr
++ ? pv_pretty(sv, SvPV_nolen_const(*elem_ptr),
++ SvCUR(*elem_ptr), PL_dump_re_max_len,
++ PL_colors[0], PL_colors[1],
++ (SvUTF8(*elem_ptr)
++ ? PERL_PV_ESCAPE_UNI
++ : 0)
++ | PERL_PV_PRETTY_ELLIPSES
++ | PERL_PV_PRETTY_LTGT
++ )
++ : "???"
++ );
++ if (trie->jump) {
++ U16 dist= trie->jump[word_idx+1];
++ Perl_re_printf( aTHX_ "(%" UVuf ")\n",
++ (UV)((dist ? this_trie + dist : next) - start));
++ if (dist) {
++ if (!nextbranch)
++ nextbranch= this_trie + trie->jump[0];
++ DUMPUNTIL(this_trie + dist, nextbranch);
++ }
++ if (nextbranch && REGNODE_TYPE(OP(nextbranch))==BRANCH)
++ nextbranch= regnext((regnode *)nextbranch);
++ } else {
++ Perl_re_printf( aTHX_ "\n");
++ }
++ }
++ if (last && next > last)
++ node= last;
++ else
++ node= next;
++ }
++ else if ( op == CURLY ) { /* "next" might be very big: optimizer */
++ DUMPUNTIL(after, after + 1); /* +1 is NOT a REGNODE_AFTER */
++ }
++ else if (REGNODE_TYPE(op) == CURLY && op != CURLYX) {
++ assert(next);
++ DUMPUNTIL(after, next);
++ }
++ else if ( op == PLUS || op == STAR) {
++ DUMPUNTIL(after, after + 1); /* +1 NOT a REGNODE_AFTER */
++ }
++ else if (REGNODE_TYPE(op) == EXACT || op == ANYOFHs) {
++ /* Literal string, where present. */
++ node = (const regnode *)REGNODE_AFTER_varies(node);
++ }
++ else {
++ node = REGNODE_AFTER_opcode(node,op);
++ }
++ if (op == CURLYX || op == OPEN || op == SROPEN)
++ indent++;
++ if (REGNODE_TYPE(op) == END)
++ break;
++ }
++ CLEAR_OPTSTART;
++#ifdef DEBUG_DUMPUNTIL
++ Perl_re_printf( aTHX_ "--- %d\n", (int)indent);
++#endif
++ return node;
++}
++
++#endif /* PERL_RE_BUILD_DEBUG */
+
+ /*
+ - regdump - dump a regexp onto Perl_debug_log in vaguely comprehensible form
+ */
+ #ifdef DEBUGGING
+-
+ static void
+ S_regdump_intflags(pTHX_ const char *lead, const U32 flags)
+ {
+@@ -907,8 +1053,8 @@ Perl_regprop(pTHX_ const regexp *prog, S
+ #endif /* DEBUGGING */
+ }
+
+-#ifdef DEBUGGING
+
++#ifdef DEBUGGING
+ STATIC void
+ S_put_code_point(pTHX_ SV *sv, UV c)
+ {
+@@ -1517,154 +1663,4 @@ S_put_charclass_bitmap_innards(pTHX_ SV
+
+ return did_output_something;
+ }
+-
+-
+-const regnode *
+-Perl_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
+- const regnode *last, const regnode *plast,
+- SV* sv, I32 indent, U32 depth)
+-{
+- const regnode *next;
+- const regnode *optstart= NULL;
+-
+- RXi_GET_DECL(r, ri);
+- DECLARE_AND_GET_RE_DEBUG_FLAGS;
+-
+- PERL_ARGS_ASSERT_DUMPUNTIL;
+-
+-#ifdef DEBUG_DUMPUNTIL
+- Perl_re_printf( aTHX_ "--- %d : %d - %d - %d\n", indent, node-start,
+- last ? last-start : 0, plast ? plast-start : 0);
+-#endif
+-
+- if (plast && plast < last)
+- last= plast;
+-
+- while (node && (!last || node < last)) {
+- const U8 op = OP(node);
+-
+- if (op == CLOSE || op == SRCLOSE || op == WHILEM)
+- indent--;
+- next = regnext((regnode *)node);
+- const regnode *after = regnode_after((regnode *)node,0);
+-
+- /* Where, what. */
+- if (op == OPTIMIZED) {
+- if (!optstart && RE_DEBUG_FLAG(RE_DEBUG_COMPILE_OPTIMISE))
+- optstart = node;
+- else
+- goto after_print;
+- } else
+- CLEAR_OPTSTART;
+-
+- regprop(r, sv, node, NULL, NULL);
+- Perl_re_printf( aTHX_ "%4" IVdf ":%*s%s", (IV)(node - start),
+- (int)(2*indent + 1), "", SvPVX_const(sv));
+-
+- if (op != OPTIMIZED) {
+- if (next == NULL) /* Next ptr. */
+- Perl_re_printf( aTHX_ " (0)");
+- else if (REGNODE_TYPE(op) == BRANCH
+- && REGNODE_TYPE(OP(next)) != BRANCH )
+- Perl_re_printf( aTHX_ " (FAIL)");
+- else
+- Perl_re_printf( aTHX_ " (%" IVdf ")", (IV)(next - start));
+- Perl_re_printf( aTHX_ "\n");
+- }
+-
+- after_print:
+- if (REGNODE_TYPE(op) == BRANCHJ) {
+- assert(next);
+- const regnode *nnode = (OP(next) == LONGJMP
+- ? regnext((regnode *)next)
+- : next);
+- if (last && nnode > last)
+- nnode = last;
+- DUMPUNTIL(after, nnode);
+- }
+- else if (REGNODE_TYPE(op) == BRANCH) {
+- assert(next);
+- DUMPUNTIL(after, next);
+- }
+- else if ( REGNODE_TYPE(op) == TRIE ) {
+- const regnode *this_trie = node;
+- const U32 n = ARG1u(node);
+- const reg_ac_data * const ac = op>=AHOCORASICK ?
+- (reg_ac_data *)ri->data->data[n] :
+- NULL;
+- const reg_trie_data * const trie =
+- (reg_trie_data*)ri->data->data[op<AHOCORASICK ? n : ac->trie];
+-#ifdef DEBUGGING
+- AV *const trie_words
+- = MUTABLE_AV(ri->data->data[n + TRIE_WORDS_OFFSET]);
+-#endif
+- const regnode *nextbranch= NULL;
+- I32 word_idx;
+- SvPVCLEAR(sv);
+- for (word_idx= 0; word_idx < (I32)trie->wordcount; word_idx++) {
+- SV ** const elem_ptr = av_fetch_simple(trie_words, word_idx, 0);
+-
+- Perl_re_indentf( aTHX_ "%s ",
+- indent+3,
+- elem_ptr
+- ? pv_pretty(sv, SvPV_nolen_const(*elem_ptr),
+- SvCUR(*elem_ptr), PL_dump_re_max_len,
+- PL_colors[0], PL_colors[1],
+- (SvUTF8(*elem_ptr)
+- ? PERL_PV_ESCAPE_UNI
+- : 0)
+- | PERL_PV_PRETTY_ELLIPSES
+- | PERL_PV_PRETTY_LTGT
+- )
+- : "???"
+- );
+- if (trie->jump) {
+- U16 dist= trie->jump[word_idx+1];
+- Perl_re_printf( aTHX_ "(%" UVuf ")\n",
+- (UV)((dist ? this_trie + dist : next) - start));
+- if (dist) {
+- if (!nextbranch)
+- nextbranch= this_trie + trie->jump[0];
+- DUMPUNTIL(this_trie + dist, nextbranch);
+- }
+- if (nextbranch && REGNODE_TYPE(OP(nextbranch))==BRANCH)
+- nextbranch= regnext((regnode *)nextbranch);
+- } else {
+- Perl_re_printf( aTHX_ "\n");
+- }
+- }
+- if (last && next > last)
+- node= last;
+- else
+- node= next;
+- }
+- else if ( op == CURLY ) { /* "next" might be very big: optimizer */
+- DUMPUNTIL(after, after + 1); /* +1 is NOT a REGNODE_AFTER */
+- }
+- else if (REGNODE_TYPE(op) == CURLY && op != CURLYX) {
+- assert(next);
+- DUMPUNTIL(after, next);
+- }
+- else if ( op == PLUS || op == STAR) {
+- DUMPUNTIL(after, after + 1); /* +1 NOT a REGNODE_AFTER */
+- }
+- else if (REGNODE_TYPE(op) == EXACT || op == ANYOFHs) {
+- /* Literal string, where present. */
+- node = (const regnode *)REGNODE_AFTER_varies(node);
+- }
+- else {
+- node = REGNODE_AFTER_opcode(node,op);
+- }
+- if (op == CURLYX || op == OPEN || op == SROPEN)
+- indent++;
+- if (REGNODE_TYPE(op) == END)
+- break;
+- }
+- CLEAR_OPTSTART;
+-#ifdef DEBUG_DUMPUNTIL
+- Perl_re_printf( aTHX_ "--- %d\n", (int)indent);
+-#endif
+- return node;
+-}
+-
+-#endif /* DEBUGGING */
++#endif /* DEBUGGING */
+--- a/regcomp_invlist.c
++++ b/regcomp_invlist.c
+@@ -18,7 +18,7 @@
+ #include "unicode_constants.h"
+ #include "regcomp_internal.h"
+
+-
++#ifdef PERL_RE_BUILD_AUX
+ void
+ Perl_populate_bitmap_from_invlist(pTHX_ SV * invlist, const UV offset, const U8 * bitmap, const Size_t len)
+ {
+@@ -70,6 +70,7 @@ Perl_populate_invlist_from_bitmap(pTHX_
+ }
+ }
+ }
++#endif /* PERL_RE_BUILD_AUX */
+
+ /* This section of code defines the inversion list object and its methods. The
+ * interfaces are highly subject to change, so as much as possible is static to
+--- a/regexec.c
++++ b/regexec.c
+@@ -4421,7 +4421,8 @@ S_regtry(pTHX_ regmatch_info *reginfo, c
+ */
+ #define REPORT_CODE_OFF 29
+ #define INDENT_CHARS(depth) ((int)(depth) % 20)
+-#ifdef DEBUGGING
++
++#ifdef PERL_RE_BUILD_DEBUG
+ int
+ Perl_re_exec_indentf(pTHX_ const char *fmt, U32 depth, ...)
+ {
$(eval $(call BuildPackage,perlbase-archive))
-define Package/perlbase-arybase
-$(call Package/perlbase-template)
-TITLE:=arybase perl module
-DEPENDS+=+perlbase-xsloader
-endef
-
-define Package/perlbase-arybase/install
-$(call perlmod/Install,$(1),arybase.pm auto/arybase,)
-$(call perlmod/InstallBaseTests,$(1),ext/arybase/t)
-endef
-
-$(eval $(call BuildPackage,perlbase-arybase))
-
-
define Package/perlbase-attribute
$(call Package/perlbase-template)
TITLE:=Attribute perl module
define Package/perlbase-b/install
$(call perlmod/Install,$(1),B B.pm auto/B,)
-$(call perlmod/InstallBaseTests,$(1),cpan/B-Debug/t ext/B/t lib/B/Deparse-core.t lib/B/Deparse-subclass.t lib/B/Deparse.t)
+$(call perlmod/InstallBaseTests,$(1),ext/B/t lib/B/Deparse-core.t lib/B/Deparse-subclass.t lib/B/Deparse.t)
endef
$(eval $(call BuildPackage,perlbase-b))
define Package/perlbase-digest/install
$(call perlmod/Install,$(1),Digest Digest.pm auto/Digest,)
$(call perlmod/InstallBaseTests,$(1),cpan/Digest-MD5/MD5.xs cpan/Digest-MD5/t cpan/Digest-SHA/t cpan/Digest/t)
- $(INSTALL_DIR) $(1)/$(PERL_TESTSDIR)/cpan/Digest-SHA/src
endef
$(eval $(call BuildPackage,perlbase-digest))
endef
define Package/perlbase-essential/install
-$(call perlmod/Install,$(1),Carp Carp.pm Exporter Exporter.pm constant.pm deprecate.pm lib.pm locale.pm overload.pm overloading.pm parent.pm strict.pm subs.pm vars.pm warnings warnings.pm,)
+$(call perlmod/Install,$(1),Carp Carp.pm Exporter Exporter.pm constant.pm deprecate.pm lib.pm builtin.pm locale.pm overload.pm overloading.pm parent.pm strict.pm subs.pm vars.pm vmsish.pm warnings warnings.pm,)
$(call perlmod/Install/NoStrip,$(1),overload/numbers.pm,)
-$(call perlmod/InstallBaseTests,$(1),cpan/parent/t dist/Carp/t dist/Exporter/t dist/constant/t dist/lib/t lib/locale.t lib/overload.t lib/overload64.t lib/overloading.t lib/strict.t lib/subs.t lib/vars.t lib/vars_carp.t lib/warnings.t)
+$(call perlmod/InstallBaseTests,$(1),cpan/parent/t dist/Carp/t dist/Exporter/t dist/constant/t dist/lib/t lib/builtin.t lib/locale.t lib/overload.t lib/overload64.t lib/overloading.t lib/strict.t lib/subs.t lib/vars.t lib/vars_carp.t lib/vmsish.t lib/warnings.t)
endef
$(eval $(call BuildPackage,perlbase-essential))
endef
define Package/perlbase-experimental/install
-$(call perlmod/Install,$(1),experimental.pm,)
+$(call perlmod/Install,$(1),experimental.pm stable.pm,)
$(call perlmod/InstallBaseTests,$(1),cpan/experimental/t)
endef
define Package/perlbase-findbin/install
$(call perlmod/Install,$(1),FindBin.pm,)
-$(call perlmod/InstallBaseTests,$(1),lib/FindBin.t)
+$(call perlmod/InstallBaseTests,$(1),dist/FindBin/t)
endef
$(eval $(call BuildPackage,perlbase-findbin))
define Package/perlbase-locale/install
$(call perlmod/Install,$(1),Locale,Locale/Constants.pod Locale/Country.pod Locale/Currency.pod Locale/Language.pod Locale/Maketext.pod Locale/Maketext/TPJ13.pod Locale/Script.pod)
-$(call perlmod/InstallBaseTests,$(1),cpan/Locale-Codes/t cpan/Locale-Maketext-Simple/t dist/Locale-Maketext/t)
+$(call perlmod/InstallBaseTests,$(1),cpan/Locale-Maketext-Simple/t dist/Locale-Maketext/t)
endef
$(eval $(call BuildPackage,perlbase-locale))
define Package/perlbase-math/install
$(call perlmod/Install,$(1),Math auto/Math,)
-$(call perlmod/InstallBaseTests,$(1),cpan/Math-Complex/t cpan/Math-BigInt-FastCalc/t cpan/Math-BigInt/t cpan/Math-BigRat/t)
+$(call perlmod/InstallBaseTests,$(1),cpan/Math-BigInt-FastCalc/t cpan/Math-BigInt/t cpan/Math-BigRat/t)
endef
$(eval $(call BuildPackage,perlbase-math))
define Package/perlbase-pod/install
$(call perlmod/Install,$(1),Pod,Pod/Usage.pm)
$(call perlmod/Install/NoStrip,$(1),Pod/Usage.pm,)
-$(call perlmod/InstallBaseTests,$(1),cpan/Pod-Checker/t cpan/Pod-Escapes/t cpan/Pod-Parser/lib cpan/Pod-Parser/scripts cpan/Pod-Parser/t cpan/Pod-Perldoc/t cpan/Pod-Simple/t cpan/Pod-Usage/scripts cpan/Pod-Usage/t cpan/podlators/t ext/Pod-Functions/Functions.pm ext/Pod-Functions/t ext/Pod-Html/t lib/Pod/t)
+$(call perlmod/InstallBaseTests,$(1),cpan/Pod-Checker/t cpan/Pod-Escapes/t cpan/Pod-Perldoc/t cpan/Pod-Simple/t cpan/Pod-Usage/scripts cpan/Pod-Usage/t cpan/podlators/t ext/Pod-Functions/Functions.pm ext/Pod-Functions/t ext/Pod-Html/t lib/Pod/t)
$(INSTALL_DIR) $(1)/usr/bin
$(CP) $(PKG_INSTALL_DIR)/usr/bin/pod2man $(1)/usr/bin/
$(CP) $(PKG_INSTALL_DIR)/usr/bin/pod2text $(1)/usr/bin/
define Package/perlbase-scalar/install
$(call perlmod/Install,$(1),Scalar Sub,)
$(call perlmod/InstallBaseTests,$(1),cpan/Scalar-List-Utils/t)
- $(INSTALL_DIR) $(1)/$(PERL_TESTSDIR)/cpan/Scalar-List-Utils/blib
endef
$(eval $(call BuildPackage,perlbase-scalar))
endef
define Package/perlbase-test/install
-$(call perlmod/Install,$(1),Test Test.pm ok.pm,Test/Builder.pm Test/Harness/TAP.pod Test/More.pm Test/Tutorial.pod)
+$(call perlmod/Install,$(1),Test Test2 Test.pm Test2.pm ok.pm,Test/Builder.pm Test/More.pm Test/Tutorial.pod Test2/Transition.pod)
$(call perlmod/Install/NoStrip,$(1),Test/Builder.pm Test/More.pm,)
$(call perlmod/InstallBaseTests,$(1),cpan/Test-Harness/t cpan/Test-Simple/t dist/Test/t)
$(INSTALL_DIR) $(1)/usr/bin
endef
define Package/perlbase-tie/install
-$(call perlmod/Install,$(1),Tie auto/Tie,)
+$(call perlmod/Install,$(1),Tie,)
$(call perlmod/InstallBaseTests,$(1),cpan/Tie-RefHash/t dist/Tie-File/t ext/Tie-Hash-NamedCapture/t ext/Tie-Memoize/lib/Tie/Memoize.pm ext/Tie-Memoize/t lib/Tie/Array/push.t lib/Tie/Array/splice.t lib/Tie/Array/std.t lib/Tie/Array/stdpush.t lib/Tie/ExtraHash.t lib/Tie/Handle/stdhandle.t lib/Tie/Handle/stdhandle_from_handle.t lib/Tie/Hash.t lib/Tie/Scalar.t lib/Tie/SubstrHash.t)
endef
endef
define Package/perlbase-utf8/install
-$(call perlmod/Install,$(1),utf8.pm utf8_heavy.pl,)
+$(call perlmod/Install,$(1),utf8.pm,)
$(call perlmod/InstallBaseTests,$(1),lib/utf8.t)
endef
-PERL_VERSION:=5.28.1
+PERL_VERSION:=5.38.2
PERL_EXPLODE:=$(subst ., ,$(PERL_VERSION))
PECL_NAME:=pecl_http
PECL_LONGNAME:=Extended HTTP Support
-PKG_VERSION:=4.2.3
-PKG_RELEASE:=2
-PKG_HASH:=fa2ab558fc8f0928a10f35c0f566f7c4a1d32e727bd3a96579e4c28482ee9d6a
+PKG_VERSION:=4.2.4
+PKG_RELEASE:=1
+PKG_HASH:=fb1e10c2e5edfb011ff8dc2e473cdbd2bbe0127d1279dfce4d98570555ac6ded
PKG_NAME:=php8-pecl-http
PKG_SOURCE:=$(PECL_NAME)-$(PKG_VERSION).tgz
PECL_NAME:=redis
PECL_LONGNAME:=PHP extension for interfacing with Redis
-PKG_VERSION:=6.0.1
+PKG_VERSION:=6.0.2
PKG_RELEASE:=1
-PKG_HASH:=d39136e0ef9495f8e775ef7349a97658fb41c526d12d8e517f56274f149e1e4e
+PKG_HASH:=01aeccb0e14f897fe56f0509be6e6991ff0ad459f9d34e95e4556d02699b9a03
PKG_NAME:=php8-pecl-redis
PKG_SOURCE:=$(PECL_NAME)-$(PKG_VERSION).tgz
PECL_NAME:=xdebug
PECL_LONGNAME:=Xdebug extension
-PKG_VERSION:=3.2.1
+PKG_VERSION:=3.2.2
PKG_RELEASE:=1
-PKG_HASH:=ef4cb3c228192798874e4530cccceee76840cc80821909740088a1e1a8f00445
+PKG_HASH:=f48777371f90cbb315ea4ea082a1ede6765bcfb35d7d6356ab8f71fd6dfcc157
PKG_NAME:=php8-pecl-xdebug
PKG_SOURCE:=$(PECL_NAME)-$(PKG_VERSION).tgz
include $(TOPDIR)/rules.mk
PKG_NAME:=php
-PKG_VERSION:=8.2.11
+PKG_VERSION:=8.2.12
PKG_RELEASE:=1
PKG_MAINTAINER:=Michael Heimpold <mhei@heimpold.de>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://www.php.net/distributions/
-PKG_HASH:=29af82e4f7509831490552918aad502697453f0869a579ee1b80b08f9112c5b8
+PKG_HASH:=e1526e400bce9f9f9f774603cfac6b72b5e8f89fa66971ebc3cc4e5964083132
PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=no-mips16
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/micropython/micropython-lib.git
-PKG_SOURCE_VERSION:=7128d423c2e7c0309ac17a1e6ba873b909b24fcc
-PKG_SOURCE_DATE:=20230522
-PKG_MIRROR_HASH:=1f094aac257d2094ee91b457164f845f6461df1cf1d0ed7ee556c98f273f5afb
+PKG_SOURCE_VERSION:=d8e163bb5f3ef45e71e145c27bc4f207beaad70f
+PKG_SOURCE_DATE:=20231031
+PKG_MIRROR_HASH:=6abb0a1460984c6fde99986971517121ac0207dabeb43cfb1855f6d7d1fd9ae5
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=MIT Python-2.0.1
PKG_BUILD_DEPENDS:=python3/host
PKG_BUILD_PARALLEL:=1
-# keep in sync with micropython
-MP_VERSION:=1.20.0
-MP_MPY_FILE_VERSION:=6
+# keep in sync with micropython (MPY_VERSION in py/persistentcode.h)
+MICROPYTHON_MPY_VERSION:=6
include $(INCLUDE_DIR)/package.mk
define Package/micropython-lib-unix
$(call Package/micropython-lib/Default)
TITLE+= - Unix port packages
- DEPENDS:=+micropython +libpcre +librt +libsqlite3
+ DEPENDS:=+micropython +libpcre2 +librt +libsqlite3
endef
define Package/micropython-lib-unix-src
port.
endef
-MP_INSTALLDEV_PATH:=$(STAGING_DIR)/host/lib/micropython-$(MP_VERSION)
+MP_INSTALLDEV_PATH:=$(STAGING_DIR)/host/lib/micropython
define MicroPythonLib/Compile
cd "$(PKG_BUILD_DIR)" && python3 tools/build.py \
endef
define Package/micropython-lib/install
- $(call MicroPythonLib/Install,,$(MP_MPY_FILE_VERSION),$(1)/usr/lib/micropython)
+ $(call MicroPythonLib/Install,,$(MICROPYTHON_MPY_VERSION),$(1)/usr/lib/micropython)
endef
define Package/micropython-lib-src/install
endef
define Package/micropython-lib-unix/install
- $(call MicroPythonLib/Install,unix-ffi-index,$(MP_MPY_FILE_VERSION),$(1)/usr/lib/micropython/unix)
+ $(call MicroPythonLib/Install,unix-ffi-index,$(MICROPYTHON_MPY_VERSION),$(1)/usr/lib/micropython/unix)
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) ./files/micropython-unix $(1)/usr/bin/
+++ /dev/null
-#
-# Copyright (C) 2023 Jeffery To
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=micropython-mpremote
-PKG_VERSION:=1.20.0
-PKG_RELEASE:=1
-
-PYPI_NAME:=mpremote
-PKG_HASH:=5c342762a04791309dd49bce63c70a075aa7c548b1c0076262b96f9ccc398ca2
-
-PKG_LICENSE:=MIT
-PKG_LICENSE_FILES:=LICENSE
-PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
-
-PKG_BUILD_DEPENDS:=python-hatchling/host python-hatch-requirements-txt/host python-hatch-vcs/host
-
-include ../pypi.mk
-include $(INCLUDE_DIR)/package.mk
-include ../python3-package.mk
-
-define Package/micropython-mpremote
- SECTION:=lang
- CATEGORY:=Languages
- SUBMENU:=Python
- TITLE:=Interacting remotely with MicroPython devices
- URL:=https://github.com/micropython/micropython
- DEPENDS:=+python3-light +python3-urllib +python3-pyserial
-endef
-
-define Package/micropython-mpremote/description
-This CLI tool provides an integrated set of utilities to remotely
-interact with and automate a MicroPython device over a serial
-connection.
-endef
-
-$(eval $(call Py3Package,micropython-mpremote))
-$(eval $(call BuildPackage,micropython-mpremote))
-$(eval $(call BuildPackage,micropython-mpremote-src))
+++ /dev/null
---- a/requirements.txt
-+++ b/requirements.txt
-@@ -1,2 +1 @@
- pyserial >= 3.3
--importlib_metadata >= 1.4
include $(TOPDIR)/rules.mk
PKG_NAME:=micropython
-PKG_VERSION:=1.20.0
+PKG_VERSION:=1.21.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/micropython/micropython/releases/download/v$(PKG_VERSION)
-PKG_HASH:=098ef8e40abdc62551b5460d0ffe9489074240c0cb5589ca3c3a425551beb9bf
+PKG_HASH:=abd2152613559d3f44728668346e78be9d93458133a03b700baf222c322fd4d5
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=MIT
This version is built without TLS and mip.
endef
-MAKE_FLAGS += BUILD_VERBOSE=1
+MAKE_FLAGS += BUILD_VERBOSE=1 STRIP=
ifneq ($(CONFIG_DEBUG),)
MAKE_FLAGS += DEBUG=1
endif
ifeq ($(BUILD_VARIANT),nossl)
- MAKE_FLAGS += MICROPY_PY_USSL=0 FROZEN_MANIFEST=variants/standard/manifest-nossl.py
+ MAKE_FLAGS += MICROPY_PY_SSL=0 FROZEN_MANIFEST=variants/standard/manifest-nossl.py
+endif
+
+# Work around "variable might be clobbered" warning leading to build error
+# https://github.com/micropython/micropython/issues/12838
+ifeq ($(ARCH),riscv64)
+ MAKE_FLAGS += CFLAGS_EXTRA=-Wno-error=clobbered
endif
MAKE_PATH = ports/unix
endef
define Build/InstallDev
- $(INSTALL_DIR) $(2)/lib/micropython-$(PKG_VERSION)/mpy-cross
+ $(INSTALL_DIR) $(2)/lib/micropython/mpy-cross
$(CP) \
$(PKG_BUILD_DIR)/mpy-cross/mpy_cross \
- $(2)/lib/micropython-$(PKG_VERSION)/mpy-cross/
+ $(2)/lib/micropython/mpy-cross/
- $(INSTALL_DIR) $(2)/lib/micropython-$(PKG_VERSION)/mpy-cross/build
+ $(INSTALL_DIR) $(2)/lib/micropython/mpy-cross/build
$(INSTALL_BIN) \
$(PKG_BUILD_DIR)/mpy-cross/build/mpy-cross \
- $(2)/lib/micropython-$(PKG_VERSION)/mpy-cross/build/
+ $(2)/lib/micropython/mpy-cross/build/
- $(INSTALL_DIR) $(2)/lib/micropython-$(PKG_VERSION)/tools
+ $(INSTALL_DIR) $(2)/lib/micropython/tools
$(INSTALL_DATA) \
$(PKG_BUILD_DIR)/tools/manifestfile.py \
- $(2)/lib/micropython-$(PKG_VERSION)/tools/
+ $(2)/lib/micropython/tools/
endef
define Package/micropython/Default/install
--- a/ports/unix/Makefile
+++ b/ports/unix/Makefile
-@@ -31,7 +31,7 @@ QSTR_DEFS = qstrdefsport.h
- QSTR_GLOBAL_DEPENDENCIES = $(VARIANT_DIR)/mpconfigvariant.h
+@@ -31,7 +31,7 @@ QSTR_DEFS += qstrdefsport.h
+ QSTR_GLOBAL_DEPENDENCIES += $(VARIANT_DIR)/mpconfigvariant.h
# OS name, for simple autoconfig
-UNAME_S := $(shell uname -s)
--- a/extmod/extmod.mk
+++ b/extmod/extmod.mk
-@@ -131,84 +131,8 @@ SRC_THIRDPARTY_C += $(addprefix $(AXTLS_
+@@ -131,85 +131,8 @@ SRC_THIRDPARTY_C += $(addprefix $(AXTLS_
crypto/sha1.c \
)
else ifeq ($(MICROPY_SSL_MBEDTLS),1)
- md4.c \
- md5.c \
- md.c \
-- md_wrap.c \
- oid.c \
- padlock.c \
- pem.c \
- ssl_cli.c \
- ssl_cookie.c \
- ssl_srv.c \
+- ssl_msg.c \
- ssl_ticket.c \
- ssl_tls.c \
- timing.c \
+- constant_time.c \
- x509.c \
- x509_create.c \
- x509_crl.c \
+++ /dev/null
-From f1c6cb7725960487195daa5c5c196fd8d3563811 Mon Sep 17 00:00:00 2001
-From: Damien George <damien@micropython.org>
-Date: Wed, 3 May 2023 15:23:24 +1000
-Subject: [PATCH] py/stackctrl: Add gcc pragmas to ignore dangling-pointer
- warning.
-
-This warning became apparent in gcc 13.
-
-Signed-off-by: Damien George <damien@micropython.org>
----
- py/stackctrl.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/py/stackctrl.c
-+++ b/py/stackctrl.c
-@@ -28,8 +28,15 @@
- #include "py/stackctrl.h"
-
- void mp_stack_ctrl_init(void) {
-+ #if __GNUC__ >= 13
-+ #pragma GCC diagnostic push
-+ #pragma GCC diagnostic ignored "-Wdangling-pointer"
-+ #endif
- volatile int stack_dummy;
- MP_STATE_THREAD(stack_top) = (char *)&stack_dummy;
-+ #if __GNUC__ >= 13
-+ #pragma GCC diagnostic pop
-+ #endif
- }
-
- void mp_stack_set_top(void *top) {
-include("$(MPY_DIR)/extmod/uasyncio")
+include("$(MPY_DIR)/extmod/asyncio")
--- /dev/null
+#!/bin/sh
+
+nl="
+"
+
+micropython -c "import sys${nl}print(sys.version)" | grep -F " MicroPython v${PKG_VERSION} "
include $(TOPDIR)/rules.mk
PKG_NAME:=pillow
-PKG_VERSION:=10.0.0
+PKG_VERSION:=10.1.0
PKG_RELEASE:=1
PYPI_NAME:=Pillow
-PKG_HASH:=9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396
+PKG_HASH:=e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38
PKG_BUILD_DEPENDS:=python-setuptools-scm/host
requires = [
- "setuptools>=67.8",
+ "setuptools",
- "wheel",
]
backend-path = [
+ "_custom_build",
--- /dev/null
+#!/bin/sh
+
+[ "$1" = "python3-pillow" ] || exit 0
+
+python3 - << EOF
+import sys
+from PIL import Image, ImageDraw
+
+if (Image.__version__ != "$2"):
+ print("Wrong version: " + Image.__version__)
+ sys.exit(1)
+
+from PIL import Image, ImageDraw
+img = Image.new('RGB', (100, 30), color = (73, 109, 137))
+d = ImageDraw.Draw(img)
+d.text((10,10), "Hello World", fill=(255,255,0))
+
+# Getting here means we did not get exceptions
+sys.exit(0)
+EOF
--- /dev/null
+#
+# Copyright (C) 2023 Jeffery To
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=pipx
+PKG_VERSION:=1.3.3
+PKG_RELEASE:=1
+
+PYPI_NAME:=pipx
+PKG_HASH:=6d5474e71e78c28d83570443e5418c56599aa8319a950ccf5984c5cb0a35f0a7
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-hatchling/host python-hatch-vcs/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/pipx
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Install/Run Python Applications in Isolated Environments
+ URL:=https://pipx.pypa.io/
+ DEPENDS:= \
+ +python3-light \
+ +python3-logging \
+ +python3-urllib \
+ +python3-venv \
+ +python3-argcomplete \
+ +python3-packaging \
+ +python3-platformdirs \
+ +python3-userpath
+endef
+
+define Package/pipx/description
+pipx is a tool to help you install and run end-user applications written
+in Python. It's roughly similar to macOS's brew, JavaScript's npx, and
+Linux's apt.
+
+It's closely related to pip. In fact, it uses pip, but is focused on
+installing and managing Python packages that can be run from the command
+line directly as applications.
+endef
+
+$(eval $(call Py3Package,pipx))
+$(eval $(call BuildPackage,pipx))
+$(eval $(call BuildPackage,pipx-src))
--- /dev/null
+#!/bin/sh
+
+[ "$1" = pipx ] || exit 0
+
+pipx --version | grep -Fx "$PKG_VERSION"
+++ /dev/null
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=pyodbc
-PKG_VERSION:=4.0.39
-PKG_RELEASE:=1
-
-PYPI_NAME:=$(PKG_NAME)
-PKG_HASH:=e528bb70dd6d6299ee429868925df0866e3e919c772b9eff79c8e17920d8f116
-
-PKG_LICENSE:=MIT
-PKG_LICENSE_FILES:=LICENSE.txt
-PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
-
-PKG_BUILD_DEPENDS:=unixodbc/host
-
-include ../pypi.mk
-include $(INCLUDE_DIR)/package.mk
-include ../python3-package.mk
-
-define Package/python3-pyodbc
- SECTION:=lang
- CATEGORY:=Languages
- SUBMENU:=Python
- TITLE:=python3-pyodbc
- URL:=https://github.com/mkleehammer/pyodbc
- DEPENDS:=+unixodbc +python3-light +libstdcpp
-endef
-
-define Package/python3-pyodbc/description
-DB API Module for ODBC
-
-A Python DB API 2 module for ODBC. This project provides an up-to-date,
-convenient interface to ODBC using native data types like datetime and decimal.
-endef
-
-$(eval $(call Py3Package,python3-pyodbc))
-$(eval $(call BuildPackage,python3-pyodbc))
--- /dev/null
+#
+# Copyright (C) 2023 Jeffery To
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-argcomplete
+PKG_VERSION:=3.2.1
+PKG_RELEASE:=1
+
+PYPI_NAME:=argcomplete
+PKG_HASH:=437f67fb9b058da5a090df505ef9be0297c4883993f3f56cb186ff087778cfb4
+
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE.rst
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-setuptools-scm/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-argcomplete
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Bash tab completion for argparse
+ URL:=https://github.com/kislyuk/argcomplete
+ DEPENDS:=+python3-light
+endef
+
+define Package/python3-argcomplete/description
+Argcomplete provides easy, extensible command line tab completion of
+arguments for your Python application.
+endef
+
+$(eval $(call Py3Package,python3-argcomplete))
+$(eval $(call BuildPackage,python3-argcomplete))
+$(eval $(call BuildPackage,python3-argcomplete-src))
--- /dev/null
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -1,5 +1,5 @@
+ [build-system]
+-requires = ["setuptools>=67.7.2", "setuptools_scm[toml]>=6.2"]
++requires = ["setuptools", "setuptools_scm[toml]>=6.2"]
+ build-backend = "setuptools.build_meta"
+
+ [project]
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-argcomplete ] || exit 0
+
+python3 -c 'import argcomplete'
include $(TOPDIR)/rules.mk
PKG_NAME:=python-bcrypt
-PKG_VERSION:=4.0.1
+PKG_VERSION:=4.1.1
PKG_RELEASE:=1
PYPI_NAME:=bcrypt
-PKG_HASH:=27d375903ac8261cfe4047f6709d16f7d18d39b1ec92aaf72af989552a650ebd
+PKG_HASH:=df37f5418d4f1cdcff845f60e747a015389fa4e63703c918330865e06ad80007
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
[ "$1" = python3-bcrypt ] || exit 0
-python3 - << EOF
-import sys
+python3 - << 'EOF'
+
import bcrypt
password = b"super secret password"
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
-sys.exit(0 if bcrypt.checkpw(password, hashed) else 1)
+assert bcrypt.checkpw(password, hashed)
+
EOF
include $(TOPDIR)/rules.mk
PKG_NAME:=python-charset-normalizer
-PKG_VERSION:=3.3.0
+PKG_VERSION:=3.3.2
PKG_RELEASE:=1
PYPI_NAME:=charset-normalizer
-PKG_HASH:=63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6
+PKG_HASH:=f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
[ "$1" = python3-charset-normalizer ] || exit 0
-python3 - << EOF
-import sys
+python3 - << 'EOF'
+
from charset_normalizer import from_bytes
s = 'Bсеки човек има право на образование.'
byte_str = s.encode('cp1251')
result = from_bytes(byte_str).best()
-sys.exit(0 if str(result) == s else 1)
+assert str(result) == s
+
EOF
#
-# Copyright (C) 2018 OpenWrt.org
+# Copyright (C) 2018, 2023 Jeffery To
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
include $(TOPDIR)/rules.mk
PKG_NAME:=python-constantly
-PKG_VERSION:=15.1.0
-PKG_RELEASE:=2
+PKG_VERSION:=23.10.4
+PKG_RELEASE:=1
PYPI_NAME:=constantly
-PKG_HASH:=586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35
+PKG_HASH:=aa92b70a33e2ac0bb33cd745eb61776594dc48764b06c35e0efd050b7f1c7cbd
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+PKG_BUILD_DEPENDS:=python-versioneer/host
+
include ../pypi.mk
include $(INCLUDE_DIR)/package.mk
include ../python3-package.mk
--- /dev/null
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -1,5 +1,5 @@
+ [build-system]
+-requires = ["setuptools>=68.2", "versioneer[toml]==0.29"]
++requires = ["setuptools", "versioneer[toml]==0.29"]
+ build-backend = "setuptools.build_meta"
+
+ [project]
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-constantly ] || exit 0
+
+python3 - << 'EOF'
+
+from constantly import NamedConstant, Names
+class Letters(Names):
+ a = NamedConstant()
+ b = NamedConstant()
+ c = NamedConstant()
+
+assert Letters.lookupByName('a') is Letters.a
+assert Letters.a < Letters.b
+assert Letters.b < Letters.c
+assert Letters.a < Letters.c
+
+from constantly import ValueConstant, Values
+class STATUS(Values):
+ OK = ValueConstant('200')
+ FOUND = ValueConstant('302')
+ NOT_FOUND = ValueConstant('404')
+
+assert STATUS.OK.value == '200'
+assert STATUS.lookupByValue('404') == STATUS.NOT_FOUND
+
+EOF
include $(TOPDIR)/rules.mk
PKG_NAME:=python-cryptography
-PKG_VERSION:=41.0.4
+PKG_VERSION:=41.0.7
PKG_RELEASE:=1
PYPI_NAME:=cryptography
-PKG_HASH:=7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a
+PKG_HASH:=13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc
PKG_LICENSE:=Apache-2.0 BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE.APACHE LICENSE.BSD
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+PKG_CPE_ID:=cpe:/a:cryptography_project:cryptography
PKG_BUILD_DEPENDS:=libffi/host python-cffi/host python-setuptools-rust/host
[ "$1" = python3-cryptography ] || exit 0
-python3 - << EOF
-import sys
+python3 - << 'EOF'
+
from cryptography.fernet import Fernet
key = Fernet.generate_key()
f = Fernet(key)
-token = f.encrypt(b"my deep dark secret")
-sys.exit(0 if f.decrypt(token) == b"my deep dark secret" else 1)
+msg = b"my deep dark secret"
+token = f.encrypt(msg)
+assert f.decrypt(token) == msg
+
EOF
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-fnv-hash-fast
+PKG_VERSION:=0.5.0
+PKG_RELEASE:=1
+
+PYPI_NAME:=fnv-hash-fast
+PYPI_SOURCE_NAME:=fnv_hash_fast
+PKG_HASH:=a84d658952776a186418f4158fc8e55ff3c576ac32cc9ef7f8077efdf2d0b89f
+
+PKG_MAINTAINER:=Timothy Ace <openwrt@timothyace.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DEPENDS:=python-cython/host python-poetry-core/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-fnv-hash-fast
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=A fast version of fnv1a
+ URL:=https://github.com/bdraco/fnv-hash-fast
+ DEPENDS:=+libstdcpp +python3-light +python3-fnvhash
+endef
+
+define Package/python3-fnv-hash-fast/description
+A fast version of fnv1a. This library will use a CPP implementation of fnv1a
+(32) if cython is available, and will fallback to pure python from the fnvhash
+package if it is not.
+endef
+
+$(eval $(call Py3Package,python3-fnv-hash-fast))
+$(eval $(call BuildPackage,python3-fnv-hash-fast))
+$(eval $(call BuildPackage,python3-fnv-hash-fast-src))
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-fnvhash
+PKG_VERSION:=0.1.0
+PKG_RELEASE:=1
+
+PYPI_NAME:=fnvhash
+PKG_HASH:=3e82d505054f9f3987b2b5b649f7e7b6f48349f6af8a1b8e4d66779699c85a8e
+
+PKG_MAINTAINER:=Timothy Ace <openwrt@timothyace.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-fnvhash
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Pure Python FNV hash implementation
+ URL:=https://github.com/znerol/py-fnvhash
+ DEPENDS:=+python3-light
+endef
+
+define Package/python3-fnvhash/description
+Pure Python implementation of the FNV hash family with 100% test coverage.
+endef
+
+$(eval $(call Py3Package,python3-fnvhash))
+$(eval $(call BuildPackage,python3-fnvhash))
+$(eval $(call BuildPackage,python3-fnvhash-src))
include $(TOPDIR)/rules.mk
PKG_NAME:=python-hatch-vcs
-PKG_VERSION:=0.3.0
+PKG_VERSION:=0.4.0
PKG_RELEASE:=1
PYPI_NAME:=hatch-vcs
PYPI_SOURCE_NAME:=hatch_vcs
-PKG_HASH:=cec5107cfce482c67f8bc96f18bbc320c9aa0d068180e14ad317bbee5a153fee
+PKG_HASH:=093810748fe01db0d451fabcf2c1ac2688caefd232d4ede967090b1c1b07d9f7
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE.txt
include $(TOPDIR)/rules.mk
PKG_NAME:=python-idna
-PKG_VERSION:=3.4
+PKG_VERSION:=3.6
PKG_RELEASE:=1
PYPI_NAME:=idna
-PKG_HASH:=814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4
+PKG_HASH:=9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca
PKG_LICENSE:=BSD-3-Clause
-PKG_LICENSE_FILES:=LICENSE.rst
+PKG_LICENSE_FILES:=LICENSE.md
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
PKG_BUILD_DEPENDS:=python-flit-core/host
SUBMENU:=Python
TITLE:=IDNA library
URL:=https://github.com/kjd/idna
- DEPENDS:= \
- +python3-light \
- +python3-codecs
+ DEPENDS:=+python3-light +python3-codecs
endef
define Package/python3-idna/description
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-idna ] || exit 0
+
+python3 - << 'EOF'
+
+import idna
+import idna.codec
+
+assert idna.encode('ドメイン.テスト') == b'xn--eckwd4c7c.xn--zckzah'
+assert idna.decode('xn--eckwd4c7c.xn--zckzah') == 'ドメイン.テスト'
+
+assert 'домен.испытание'.encode('idna2008') == b'xn--d1acufc.xn--80akhbyknj4f'
+assert b'xn--d1acufc.xn--80akhbyknj4f'.decode('idna2008') == 'домен.испытание'
+
+assert idna.alabel('测试') == b'xn--0zwm56d'
+
+assert idna.encode('Königsgäßchen', uts46=True) == b'xn--knigsgchen-b4a3dun'
+assert idna.decode('xn--knigsgchen-b4a3dun') == 'königsgäßchen'
+
+assert idna.encode('Königsgäßchen', uts46=True, transitional=True) == b'xn--knigsgsschen-lcb0w'
+
+EOF
--- /dev/null
+#
+# Copyright (C) 2023 Jeffery To
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-jsonschema-specifications
+PKG_VERSION:=2023.11.2
+PKG_RELEASE:=1
+
+PYPI_NAME:=jsonschema-specifications
+PYPI_SOURCE_NAME:=jsonschema_specifications
+PKG_HASH:=9472fc4fea474cd74bea4a2b190daeccb5a9e4db2ea80efcf7a1b582fc9a81b8
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-hatchling/host python-hatch-vcs/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-jsonschema-specifications
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=JSON Schema meta-schemas and vocabularies
+ URL:=https://github.com/python-jsonschema/jsonschema-specifications
+ DEPENDS:=+python3-light +python3-referencing
+endef
+
+define Package/python3-jsonschema-specifications/description
+JSON support files from the JSON Schema Specifications (metaschemas,
+vocabularies, etc.), packaged for runtime access from Python as a
+referencing-based Schema Registry.
+endef
+
+$(eval $(call Py3Package,python3-jsonschema-specifications))
+$(eval $(call BuildPackage,python3-jsonschema-specifications))
+$(eval $(call BuildPackage,python3-jsonschema-specifications-src))
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-jsonschema-specifications ] || exit 0
+
+python3 - << 'EOF'
+
+from jsonschema_specifications import REGISTRY as SPECIFICATIONS
+
+DRAFT202012_DIALECT_URI = "https://json-schema.org/draft/2020-12/schema"
+assert SPECIFICATIONS.contents(DRAFT202012_DIALECT_URI) != ""
+
+EOF
include $(TOPDIR)/rules.mk
PKG_NAME:=python-jsonschema
-PKG_VERSION:=4.17.3
-PKG_RELEASE:=3
+PKG_VERSION:=4.20.0
+PKG_RELEASE:=1
PYPI_NAME:=jsonschema
-PKG_HASH:=0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d
+PKG_HASH:=4f614fd46d8d61258610998997743ec5492a648b33cf478c1ddc23ed4598a5fa
PKG_MAINTAINER:=Javier Marcet <javier@marcet.info>
PKG_LICENSE:=MIT
CATEGORY:=Languages
SUBMENU:=Python
TITLE:=An implementation of JSON Schema validation
- URL:=https://github.com/Julian/jsonschema
- DEPENDS:=+python3-light +python3-attrs +python3-urllib \
- +python3-six +python3-pyrsistent +python3-setuptools
+ URL:=https://github.com/python-jsonschema/jsonschema
+ DEPENDS:= \
+ +python3-light \
+ +python3-decimal \
+ +python3-urllib \
+ +python3-uuid \
+ +python3-attrs \
+ +python3-jsonschema-specifications \
+ +python3-referencing \
+ +python3-rpds-py
endef
define Package/python3-jsonschema/description
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-jsonschema ] || exit 0
+
+python3 - << 'EOF'
+
+from jsonschema import validate
+
+# A sample schema, like what we'd get from json.load()
+schema = {
+ "type" : "object",
+ "properties" : {
+ "price" : {"type" : "number"},
+ "name" : {"type" : "string"},
+ },
+}
+
+# If no exception is raised by validate(), the instance is valid.
+validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema)
+
+EOF
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-lru-dict
+PKG_VERSION:=1.3.0
+PKG_RELEASE:=1
+
+PYPI_NAME:=lru-dict
+PKG_HASH:=54fd1966d6bd1fcde781596cb86068214edeebff1db13a2cea11079e3fd07b6b
+
+PKG_MAINTAINER:=Timothy Ace <openwrt@timothyace.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-lru-dict
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=An Dict like LRU container
+ URL:=https://github.com/amitdev/lru-dict
+ DEPENDS:=+python3-light
+endef
+
+define Package/python3-lru-dict/description
+A fixed size dict like container which evicts Least Recently Used (LRU) items
+once size limit is exceeded. There are many python implementations available
+which does similar things. This is a fast and efficient C implementation. LRU
+maximum capacity can be modified at run-time. If you are looking for pure
+python version, look elsewhere.
+endef
+
+$(eval $(call Py3Package,python3-lru-dict))
+$(eval $(call BuildPackage,python3-lru-dict))
+$(eval $(call BuildPackage,python3-lru-dict-src))
include $(TOPDIR)/rules.mk
PKG_NAME:=python-mako
-PKG_VERSION:=1.2.4
+PKG_VERSION:=1.3.0
PKG_RELEASE:=1
PYPI_NAME:=Mako
-PKG_HASH:=d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34
+PKG_HASH:=e3a9d388fd00e87043edbe8792f45880ac0114e9c4adc69f6e9bfb2c55e3b11b
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=MIT
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2023 Luca Barbato
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-maturin
+PKG_VERSION:=1.3.0
+PKG_RELEASE:=1
+
+PYPI_NAME:=maturin
+PKG_HASH:=f6c69bc7ae147a5effd55587447b35cab1ceb726ba244d08698bc7518b8688ac
+
+PKG_MAINTAINER:=Luca Barbato <lu_zero@luminem.org>
+PKG_LICENSE:=Apache-2.0 MIT
+PKG_LICENSE_FILES:=license-apache license-mit
+
+HOST_BUILD_DEPENDS:= \
+ python3/host \
+ python-build/host \
+ python-installer/host \
+ python-wheel/host \
+ python-setuptools-rust/host
+HOST_BUILD_PARALLEL:=1
+PKG_HOST_ONLY:=1
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+include ../python3-host-build.mk
+
+define Package/python3-maturin
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Build and publish crates as python packages
+ DEPENDS:=$(RUST_ARCH_DEPENDS)
+ URL:=https://maturin.rs
+ BUILDONLY:=1
+endef
+
+define Package/python3-maturin/description
+ Build and publish crates with pyo3, rust-cpython, cffi and uniffi
+ bindings as well as rust binaries as python packages.
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call Py3Package,python3-maturin))
+$(eval $(call BuildPackage,python3-maturin))
+$(eval $(call BuildPackage,python3-maturin-src))
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-orjson
+PKG_VERSION:=3.9.10
+PKG_RELEASE:=1
+
+PYPI_NAME:=orjson
+PKG_HASH:=9ebbdbd6a046c304b1845e96fbcc5559cd296b4dfd3ad2509e33c4d9ce07d6a1
+
+PKG_MAINTAINER:=Timothy Ace <openwrt@timothyace.com>
+PKG_LICENSE:=Apache-2.0 MIT
+PKG_LICENSE_FILES:=LICENSE-APACHE LICENSE-MIT
+
+PKG_BUILD_DEPENDS:=python-maturin/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-orjson
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Fast, correct Python JSON library
+ URL:=https://github.com/ijl/orjson
+ DEPENDS:= \
+ +python3-light \
+ $(RUST_ARCH_DEPENDS)
+endef
+
+define Package/python3-orjson/description
+Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy
+endef
+
+$(eval $(call Py3Package,python3-orjson))
+$(eval $(call BuildPackage,python3-orjson))
+$(eval $(call BuildPackage,python3-orjson-src))
include $(TOPDIR)/rules.mk
PKG_NAME:=python-pathspec
-PKG_VERSION:=0.11.2
+PKG_VERSION:=0.12.1
PKG_RELEASE:=1
PYPI_NAME:=pathspec
-PKG_HASH:=e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3
+PKG_HASH:=a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712
PKG_LICENSE:=MPL-2.0
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=python-pip
-PKG_VERSION:=23.2.1
+PKG_VERSION:=23.3.1
PKG_RELEASE:=1
PYPI_NAME:=pip
-PKG_HASH:=fb0bd5435b3200c602b5bf61d2d43c2f13c02e29c1707567ae7fbc514eb9faf2
+PKG_HASH:=1fcaa041308d01f14575f6d0d2ea4b75a3e2871fe4f9c694976f908768e14174
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE.txt
--- a/src/pip/_vendor/pyproject_hooks/_in_process/__init__.py
+++ b/src/pip/_vendor/pyproject_hooks/_in_process/__init__.py
-@@ -11,8 +11,8 @@ try:
+@@ -11,8 +11,14 @@ try:
except AttributeError:
# Python 3.8 compatibility
def _in_proc_script_path():
- return resources.path(__package__, '_in_process.py')
-+ return resources.path(__package__, '_in_process.pyc')
++ filename = '_in_process.pyc'
++ if resources.is_resource(__package__, '_in_process.py'):
++ filename = '_in_process.py'
++ return resources.path(__package__, filename)
else:
def _in_proc_script_path():
++ filename = '_in_process.pyc'
++ if resources.files(__package__).joinpath('_in_process.py').is_file():
++ filename = '_in_process.py'
return resources.as_file(
- resources.files(__package__).joinpath('_in_process.py'))
-+ resources.files(__package__).joinpath('_in_process.pyc'))
++ resources.files(__package__).joinpath(filename))
--- a/src/pip/_internal/build_env.py
+++ b/src/pip/_internal/build_env.py
-@@ -54,7 +54,7 @@ def get_runnable_pip() -> str:
+@@ -54,7 +54,11 @@ def get_runnable_pip() -> str:
# case, we can use that directly.
return str(source)
- return os.fsdecode(source / "__pip-runner__.py")
-+ return os.fsdecode(source / "__pip-runner__.pyc")
++ filename = "__pip-runner__.pyc"
++ py = source / "__pip-runner__.py"
++ if py.is_file():
++ filename = "__pip-runner__.py"
++ return os.fsdecode(source / filename)
def _get_system_sitepackages() -> Set[str]:
--- a/src/pip/_internal/cli/cmdoptions.py
+++ b/src/pip/_internal/cli/cmdoptions.py
-@@ -892,7 +892,7 @@ disable_pip_version_check: Callable[...,
+@@ -895,7 +895,7 @@ disable_pip_version_check: Callable[...,
"--disable-pip-version-check",
dest="disable_pip_version_check",
action="store_true",
--- /dev/null
+#
+# Copyright (C) 2023 Jeffery To
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-platformdirs
+PKG_VERSION:=4.1.0
+PKG_RELEASE:=1
+
+PYPI_NAME:=platformdirs
+PKG_HASH:=906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-hatchling/host python-hatch-vcs/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-platformdirs
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Determine appropriate platform-specific dirs
+ URL:=https://github.com/platformdirs/platformdirs
+ DEPENDS:=+python3-light +python3-urllib
+endef
+
+define Package/python3-platformdirs/description
+When writing desktop application, finding the right location to store
+user data and configuration varies per platform. Even for
+single-platform apps, there may by plenty of nuances in figuring out the
+right location.
+
+This kind of thing is what the platformdirs package is for.
+endef
+
+$(eval $(call Py3Package,python3-platformdirs))
+$(eval $(call BuildPackage,python3-platformdirs))
+$(eval $(call BuildPackage,python3-platformdirs-src))
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-platformdirs ] || exit 0
+
+python3 - << 'EOF'
+
+from platformdirs import *
+appname = "SuperApp"
+appauthor = "Acme"
+
+assert user_data_dir(appname, appauthor) == '/root/.local/share/SuperApp'
+assert user_cache_dir(appname, appauthor) == '/root/.cache/SuperApp'
+assert user_log_dir(appname, appauthor) == '/root/.local/state/SuperApp/log'
+assert user_config_dir(appname) == '/root/.config/SuperApp'
+assert user_documents_dir() == '/root/Documents'
+assert user_downloads_dir() == '/root/Downloads'
+assert user_pictures_dir() == '/root/Pictures'
+assert user_videos_dir() == '/root/Videos'
+assert user_music_dir() == '/root/Music'
+assert user_desktop_dir() == '/root/Desktop'
+assert user_runtime_dir(appname, appauthor) == '/run/user/0/SuperApp'
+
+assert site_data_dir(appname, appauthor) == '/usr/local/share/SuperApp'
+assert site_data_dir(appname, appauthor, multipath=True) == '/usr/local/share/SuperApp:/usr/share/SuperApp'
+
+assert site_config_dir(appname) == '/etc/xdg/SuperApp'
+
+import os
+os.environ["XDG_CONFIG_DIRS"] = "/etc:/usr/local/etc"
+
+assert site_config_dir(appname, multipath=True) == '/etc/SuperApp:/usr/local/etc/SuperApp'
+
+EOF
include $(TOPDIR)/rules.mk
PKG_NAME:=python-poetry-core
-PKG_VERSION:=1.7.0
+PKG_VERSION:=1.8.1
PKG_RELEASE:=1
PYPI_NAME:=poetry-core
PYPI_SOURCE_NAME:=poetry_core
-PKG_HASH:=8f679b83bd9c820082637beca1204124d5d2a786e4818da47ec8acefd0353b74
+PKG_HASH:=67a76c671da2a70e55047cddda83566035b701f7e463b32a2abfeac6e2a16376
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=python-pyasn1
-PKG_VERSION:=0.5.0
+PKG_VERSION:=0.5.1
PKG_RELEASE:=1
PYPI_NAME:=pyasn1
-PKG_HASH:=97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde
+PKG_HASH:=6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c
PKG_LICENSE:=BSD-2-Clause
PKG_LICENSE_FILES:=LICENSE.rst
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-pyasn1 ] || exit 0
+
+python3 - << 'EOF'
+
+from collections import OrderedDict
+
+from pyasn1.type import namedtype
+from pyasn1.type import tag
+from pyasn1.type import univ
+from pyasn1.codec.der.encoder import encode as derEncode
+from pyasn1.codec.der.decoder import decode as derDecode
+from pyasn1.codec.native.encoder import encode as nativeEncode
+from pyasn1.codec.native.decoder import decode as nativeDecode
+
+class Record(univ.Sequence):
+ componentType = namedtype.NamedTypes(
+ namedtype.NamedType('id', univ.Integer()),
+ namedtype.OptionalNamedType(
+ 'room', univ.Integer().subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
+ )
+ ),
+ namedtype.DefaultedNamedType(
+ 'house', univ.Integer(0).subtype(
+ implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)
+ )
+ )
+ )
+
+# encoding modifies the object (https://github.com/pyasn1/pyasn1/issues/53)
+# so test decoding before encoding
+
+record = Record()
+record['id'] = 123
+record['room'] = 321
+assert str(record) == 'Record:\n id=123\n room=321\n'
+
+substrate = b'0\x07\x02\x01{\x80\x02\x01A'
+
+received_record, _ = derDecode(substrate, asn1Spec=Record())
+assert received_record == record
+
+dict_record = nativeDecode({'id': 123, 'room': 321}, asn1Spec=Record())
+assert dict_record == record
+
+assert derEncode(record) == substrate
+assert nativeEncode(record) == OrderedDict([('id', 123), ('room', 321), ('house', 0)])
+
+EOF
include $(TOPDIR)/rules.mk
PKG_NAME:=python-pycares
-PKG_VERSION:=4.3.0
-PKG_RELEASE:=2
+PKG_VERSION:=4.4.0
+PKG_RELEASE:=1
PYPI_NAME:=pycares
-PKG_HASH:=c542696f6dac978e9d99192384745a65f80a7d9450501151e4a7563e06010d45
+PKG_HASH:=f47579d508f2f56eddd16ce72045782ad3b1b3b678098699e2b6a1b30733e1c2
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
--- /dev/null
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-pyodbc
+PKG_VERSION:=5.0.1
+PKG_RELEASE:=1
+
+PYPI_NAME:=pyodbc
+PKG_HASH:=03d7d0b04d5a9156099ce8d03e92f3956783746fa9234eb6f5b5cfc12b645011
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE.txt
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+# for odbc_config
+PKG_BUILD_DEPENDS:=unixodbc/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-pyodbc
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=DB API module for ODBC
+ URL:=https://github.com/mkleehammer/pyodbc
+ DEPENDS:=+python3-light +python3-decimal +python3-uuid +libodbc +libstdcpp
+endef
+
+define Package/python3-pyodbc/description
+pyodbc is an open source Python module that makes accessing ODBC
+databases simple. It implements the DB API 2.0 specification but is
+packed with even more Pythonic convenience.
+endef
+
+$(eval $(call Py3Package,python3-pyodbc))
+$(eval $(call BuildPackage,python3-pyodbc))
+# no src package - the module does not contain any Python code
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-pyodbc ] || exit 0
+
+python3 -c 'import pyodbc'
include $(TOPDIR)/rules.mk
PKG_NAME:=python-pyopenssl
-PKG_VERSION:=23.2.0
+PKG_VERSION:=23.3.0
PKG_RELEASE:=1
PYPI_NAME:=pyOpenSSL
-PKG_HASH:=276f931f55a452e7dea69c7173e984eb2a4407ce413c918aa34b55f82f9b8bac
+PKG_HASH:=6b2cba5cc46e822750ec3e5a81ee12819850b11303630d575e98108a079c2b12
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
--- /dev/null
+#
+# Copyright (C) 2023 Jeffery To
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-referencing
+PKG_VERSION:=0.32.0
+PKG_RELEASE:=1
+
+PYPI_NAME:=referencing
+PKG_HASH:=689e64fe121843dcfd57b71933318ef1f91188ffb45367332700a86ac8fd6161
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-hatchling/host python-hatch-vcs/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-referencing
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=JSON Referencing + Python
+ URL:=https://github.com/python-jsonschema/referencing
+ DEPENDS:= \
+ +python3-light \
+ +python3-email \
+ +python3-urllib \
+ +python3-attrs \
+ +python3-rpds-py
+endef
+
+define Package/python3-referencing/description
+An implementation-agnostic implementation of JSON reference resolution.
+endef
+
+$(eval $(call Py3Package,python3-referencing))
+$(eval $(call BuildPackage,python3-referencing))
+$(eval $(call BuildPackage,python3-referencing-src))
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-referencing ] || exit 0
+
+python3 - << 'EOF'
+
+from referencing import Registry, Resource
+import referencing.jsonschema
+
+schema = Resource.from_contents( # Parse some contents into a 2020-12 JSON Schema
+ {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "urn:example:a-202012-schema",
+ "$defs": {
+ "nonNegativeInteger": {
+ "$anchor": "nonNegativeInteger",
+ "type": "integer",
+ "minimum": 0,
+ },
+ },
+ }
+)
+registry = schema @ Registry() # Add the resource to a new registry
+
+# From here forward, this would usually be done within a library wrapping this one,
+# like a JSON Schema implementation
+resolver = registry.resolver()
+resolved = resolver.lookup("urn:example:a-202012-schema#nonNegativeInteger")
+assert resolved.contents == {
+ "$anchor": "nonNegativeInteger",
+ "type": "integer",
+ "minimum": 0,
+}
+
+EOF
--- /dev/null
+#
+# Copyright (C) 2023 Jeffery To
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-rpds-py
+PKG_VERSION:=0.10.6
+PKG_RELEASE:=1
+
+PYPI_NAME:=rpds-py
+PYPI_SOURCE_NAME:=rpds_py
+PKG_HASH:=4ce5a708d65a8dbf3748d2474b580d606b1b9f91b5c6ab2a316e0b0cf7a4ba50
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-maturin/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-rpds-py
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Bindings to Rust's persistent data structures
+ URL:=https://github.com/crate-py/rpds
+ DEPENDS:=+python3-light $(RUST_ARCH_DEPENDS)
+endef
+
+define Package/python3-rpds-py/description
+Python bindings to the Rust rpds crate for persistent data structures.
+endef
+
+$(eval $(call Py3Package,python3-rpds-py))
+$(eval $(call BuildPackage,python3-rpds-py))
+$(eval $(call BuildPackage,python3-rpds-py-src))
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-rpds-py ] || exit 0
+
+python3 - << 'EOF'
+
+from rpds import HashTrieMap, HashTrieSet, List
+
+m = HashTrieMap({"foo": "bar", "baz": "quux"})
+assert m.insert("spam", 37) == HashTrieMap({"foo": "bar", "baz": "quux", "spam": 37})
+assert m.remove("foo") == HashTrieMap({"baz": "quux"})
+
+s = HashTrieSet({"foo", "bar", "baz", "quux"})
+assert s.insert("spam") == HashTrieSet({"foo", "bar", "baz", "quux", "spam"})
+assert s.remove("foo") == HashTrieSet({"bar", "baz", "quux"})
+
+L = List([1, 3, 5])
+assert L.push_front(-1) == List([-1, 1, 3, 5])
+assert L.rest == List([3, 5])
+
+EOF
include $(TOPDIR)/rules.mk
PKG_NAME:=python-setuptools-rust
-PKG_VERSION:=1.7.0
+PKG_VERSION:=1.8.1
PKG_RELEASE:=1
PYPI_NAME:=setuptools-rust
-PKG_HASH:=c7100999948235a38ae7e555fe199aa66c253dc384b125f5d85473bf81eae3a3
+PKG_HASH:=94b1dd5d5308b3138d5b933c3a2b55e6d6927d1a22632e509fcea9ddd0f7e486
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
python-wheel/host \
python-setuptools-scm/host \
python-semantic-version/host \
- python-typing-extensions/host \
rust/host
include ../pypi.mk
+python3-logging \
+python3-semantic-version \
+python3-setuptools \
- +python3-typing-extensions \
+rust
BUILDONLY:=1
endef
include $(TOPDIR)/rules.mk
PKG_NAME:=python-setuptools
-PKG_VERSION:=68.2.2
+PKG_VERSION:=69.0.2
PKG_RELEASE:=1
PYPI_NAME:=setuptools
-PKG_HASH:=4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87
+PKG_HASH:=735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=python-texttable
-PKG_VERSION:=1.6.7
+PKG_VERSION:=1.7.0
PKG_RELEASE:=1
PYPI_NAME:=texttable
-PKG_HASH:=290348fb67f7746931bcdfd55ac7584ecd4e5b0846ab164333f0794b121760f2
+PKG_HASH:=2d2068fb55115807d3ac77a4ca68fa48803e84ebb0ee2340f858107a36522638
PKG_MAINTAINER:=Javier Marcet <javier@marcet.info>
PKG_LICENSE:=MIT
include $(TOPDIR)/rules.mk
PKG_NAME:=python-trove-classifiers
-PKG_VERSION:=2023.9.19
+PKG_VERSION:=2023.11.29
PKG_RELEASE:=1
PYPI_NAME:=trove-classifiers
-PKG_HASH:=3e700af445c802f251ce2b741ee78d2e5dfa5ab8115b933b89ca631b414691c9
+PKG_HASH:=ff8f7fd82c7932113b46e7ef6742c70091cc63640c8c65db00d91f2e940b9514
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=python-twisted
-PKG_VERSION:=23.8.0
+PKG_VERSION:=23.10.0
PKG_RELEASE:=1
PYPI_NAME:=Twisted
PYPI_SOURCE_NAME:=twisted
-PKG_HASH:=3c73360add17336a622c0d811c2a2ce29866b6e59b1125fd6509b17252098a24
+PKG_HASH:=987847a0790a2c597197613686e2784fd54167df3a55d0fb17c8412305d76ce5
PKG_BUILD_DEPENDS:=libtirpc
--- a/pyproject.toml
+++ b/pyproject.toml
-@@ -150,7 +150,6 @@ ckeygen = "twisted.conch.scripts.ckeygen
+@@ -138,7 +138,6 @@ ckeygen = "twisted.conch.scripts.ckeygen
conch = "twisted.conch.scripts.conch:run"
mailmail = "twisted.mail.scripts.mailmail:run"
pyhtmlizer = "twisted.scripts.htmlizer:run"
--- a/pyproject.toml
+++ b/pyproject.toml
-@@ -194,6 +194,7 @@ exclude = [
+@@ -182,6 +182,7 @@ exclude = [
"*.pxi",
"*.pyx",
"build.bat",
include $(TOPDIR)/rules.mk
PKG_NAME:=python-typing-extensions
-PKG_VERSION:=4.8.0
+PKG_VERSION:=4.9.0
PKG_RELEASE:=1
PYPI_NAME:=typing-extensions
PYPI_SOURCE_NAME:=typing_extensions
-PKG_HASH:=df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef
+PKG_HASH:=23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783
PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com>, Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=Python-2.0.1 0BSD
--- /dev/null
+#
+# Copyright (C) 2023 Jeffery To
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-userpath
+PKG_VERSION:=1.9.1
+PKG_RELEASE:=1
+
+PYPI_NAME:=userpath
+PKG_HASH:=ce8176728d98c914b6401781bf3b23fccd968d1647539c8788c7010375e02796
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE.txt
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-hatchling/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-userpath
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Cross-platform tool for modifying a user's PATH
+ URL:=https://github.com/ofek/userpath
+ DEPENDS:=+python3-light +python3-click +python3-psutil
+endef
+
+define Package/python3-userpath/description
+This is a tool for modifying a user's PATH.
+endef
+
+$(eval $(call Py3Package,python3-userpath))
+$(eval $(call BuildPackage,python3-userpath))
+$(eval $(call BuildPackage,python3-userpath-src))
--- /dev/null
+From 9175a0a97c7bc2eeb995e53d50a07be6a7e834f0 Mon Sep 17 00:00:00 2001
+From: Jeffery To <jeffery.to@gmail.com>
+Date: Thu, 9 Nov 2023 14:20:58 +0800
+Subject: [PATCH] Handle OSErrors when running show path commands
+
+Bash may not always be installed, for example on OpenWrt, and attempting
+to call the show path commands for Bash will cause a FileNotFoundError
+to be raised.
+
+This wraps the subprocess call with a try statement and returns the
+empty string in the case of an OSError.
+---
+ userpath/utils.py | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/userpath/utils.py
++++ b/userpath/utils.py
+@@ -30,8 +30,11 @@ def ensure_parent_dir_exists(path):
+
+
+ def get_flat_output(command, sep=os.pathsep, **kwargs):
+- process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
+- output = process.communicate()[0].decode(locale.getpreferredencoding(False)).strip()
++ try:
++ process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
++ output = process.communicate()[0].decode(locale.getpreferredencoding(False)).strip()
++ except OSError:
++ return ''
+
+ # We do this because the output may contain new lines.
+ lines = [line.strip() for line in output.splitlines()]
--- /dev/null
+From dffcc1c5823bcce10b420467db41e42ec41f4702 Mon Sep 17 00:00:00 2001
+From: Jeffery To <jeffery.to@gmail.com>
+Date: Thu, 9 Nov 2023 17:48:50 +0800
+Subject: [PATCH 1/2] Use Sh as base class for Bash and Zsh
+
+---
+ userpath/shells.py | 41 ++++++++++++++++++++++++++---------------
+ 1 file changed, 26 insertions(+), 15 deletions(-)
+
+--- a/userpath/shells.py
++++ b/userpath/shells.py
+@@ -12,24 +12,36 @@ class Shell(object):
+
+
+ class Sh(Shell):
+- def config(self, location, front=True):
++ name = 'sh'
++
++ def _config_contents(self, location, front=True):
+ head, tail = (location, '$PATH') if front else ('$PATH', location)
+ new_path = '{}{}{}'.format(head, pathsep, tail)
++ return 'export PATH="{}"'.format(new_path)
++
++ def config(self, location, front=True):
++ contents = self._config_contents(location, front=front)
++ return {path.join(self.home, '.profile'): contents}
+
+- return {path.join(self.home, '.profile'): 'PATH="{}"'.format(new_path)}
++ @classmethod
++ def _interactive_show_path_command(cls):
++ return [cls.name, '-i', '-c', 'echo $PATH']
++
++ @classmethod
++ def _interactive_login_show_path_command(cls):
++ return [cls.name, '-i', '-l', '-c', 'echo $PATH']
+
+ @classmethod
+ def show_path_commands(cls):
+ # TODO: Find out what file influences non-login shells. The issue may simply be our Docker setup.
+- return [['sh', '-i', '-l', '-c', 'echo $PATH']]
++ return [cls._interactive_login_show_path_command()]
+
+
+-class Bash(Shell):
+- def config(self, location, front=True):
+- head, tail = (location, '$PATH') if front else ('$PATH', location)
+- new_path = '{}{}{}'.format(head, pathsep, tail)
+- contents = 'export PATH="{}"'.format(new_path)
++class Bash(Sh):
++ name = 'bash'
+
++ def config(self, location, front=True):
++ contents = self._config_contents(location, front=front)
+ configs = {path.join(self.home, '.bashrc'): contents}
+
+ # https://github.com/ofek/userpath/issues/3#issuecomment-492491977
+@@ -50,7 +62,7 @@ class Bash(Shell):
+
+ @classmethod
+ def show_path_commands(cls):
+- return [['bash', '-i', '-c', 'echo $PATH'], ['bash', '-i', '-l', '-c', 'echo $PATH']]
++ return [cls._interactive_show_path_command(), cls._interactive_login_show_path_command()]
+
+
+ class Fish(Shell):
+@@ -88,18 +100,17 @@ class Xonsh(Shell):
+ return [['xonsh', '-i', '-c', command], ['xonsh', '-i', '--login', '-c', command]]
+
+
+-class Zsh(Shell):
+- def config(self, location, front=True):
+- head, tail = (location, '$PATH') if front else ('$PATH', location)
+- new_path = '{}{}{}'.format(head, pathsep, tail)
+- contents = 'export PATH="{}"'.format(new_path)
++class Zsh(Sh):
++ name = 'zsh'
+
++ def config(self, location, front=True):
++ contents = self._config_contents(location, front=front)
+ zdotdir = environ.get('ZDOTDIR', self.home)
+ return {path.join(zdotdir, '.zshrc'): contents, path.join(zdotdir, '.zprofile'): contents}
+
+ @classmethod
+ def show_path_commands(cls):
+- return [['zsh', '-i', '-c', 'echo $PATH'], ['zsh', '-i', '-l', '-c', 'echo $PATH']]
++ return [cls._interactive_show_path_command(), cls._interactive_login_show_path_command()]
+
+
+ SHELLS = {
--- /dev/null
+From 7823b9b39c486aedf830783329abdc3bd9664ba4 Mon Sep 17 00:00:00 2001
+From: Jeffery To <jeffery.to@gmail.com>
+Date: Thu, 9 Nov 2023 17:51:21 +0800
+Subject: [PATCH 2/2] Add support for ash (Almquist shell)
+
+---
+ tests/docker/debian | 2 +-
+ tests/test_ash.py | 65 +++++++++++++++++++++++++++++++++++++++++++++
+ userpath/shells.py | 5 ++++
+ 3 files changed, 71 insertions(+), 1 deletion(-)
+ create mode 100644 tests/test_ash.py
+
+--- a/tests/docker/debian
++++ b/tests/docker/debian
+@@ -2,7 +2,7 @@ ARG PYTHON_VERSION
+ FROM python:${PYTHON_VERSION}
+
+ RUN apt-get update \
+- && apt-get --no-install-recommends -y install fish zsh
++ && apt-get --no-install-recommends -y install ash fish zsh
+
+ COPY requirements.txt /
+ RUN pip install -r requirements.txt
+--- /dev/null
++++ b/tests/test_ash.py
+@@ -0,0 +1,65 @@
++import pytest
++import userpath
++
++from .utils import SKIP_WINDOWS_CI, get_random_path
++
++SHELL_NAME = 'ash'
++
++pytestmark = [SKIP_WINDOWS_CI, pytest.mark.ash]
++
++
++@pytest.mark.usefixtures('shell_test')
++class TestDebian(object):
++ DOCKERFILE = 'debian'
++
++ def test_prepend(self, request, shell_test):
++ if shell_test is None:
++ location = get_random_path()
++ assert not userpath.in_current_path(location)
++ assert userpath.prepend(location, check=True)
++ assert userpath.in_new_path(location)
++ assert userpath.need_shell_restart(location)
++ else:
++ process = shell_test(request.node.name)
++ stdout, stderr = process.communicate()
++
++ assert process.returncode == 0, (stdout + stderr).decode('utf-8')
++
++ def test_prepend_multiple(self, request, shell_test):
++ if shell_test is None:
++ locations = [get_random_path(), get_random_path()]
++ assert not userpath.in_current_path(locations)
++ assert userpath.prepend(locations, check=True)
++ assert userpath.in_new_path(locations)
++ assert userpath.need_shell_restart(locations)
++ else:
++ process = shell_test(request.node.name)
++ stdout, stderr = process.communicate()
++
++ assert process.returncode == 0, (stdout + stderr).decode('utf-8')
++
++ def test_append(self, request, shell_test):
++ if shell_test is None:
++ location = get_random_path()
++ assert not userpath.in_current_path(location)
++ assert userpath.append(location, check=True)
++ assert userpath.in_new_path(location)
++ assert userpath.need_shell_restart(location)
++ else:
++ process = shell_test(request.node.name)
++ stdout, stderr = process.communicate()
++
++ assert process.returncode == 0, (stdout + stderr).decode('utf-8')
++
++ def test_append_multiple(self, request, shell_test):
++ if shell_test is None:
++ locations = [get_random_path(), get_random_path()]
++ assert not userpath.in_current_path(locations)
++ assert userpath.append(locations, check=True)
++ assert userpath.in_new_path(locations)
++ assert userpath.need_shell_restart(locations)
++ else:
++ process = shell_test(request.node.name)
++ stdout, stderr = process.communicate()
++
++ assert process.returncode == 0, (stdout + stderr).decode('utf-8')
+--- a/userpath/shells.py
++++ b/userpath/shells.py
+@@ -37,6 +37,10 @@ class Sh(Shell):
+ return [cls._interactive_login_show_path_command()]
+
+
++class Ash(Sh):
++ name = 'ash'
++
++
+ class Bash(Sh):
+ name = 'bash'
+
+@@ -114,6 +118,7 @@ class Zsh(Sh):
+
+
+ SHELLS = {
++ 'ash': Ash,
+ 'bash': Bash,
+ 'fish': Fish,
+ 'sh': Sh,
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-userpath ] || exit 0
+
+userpath --version | grep -Fx "userpath, version $PKG_VERSION"
--- /dev/null
+#
+# Copyright (C) 2023 Jeffery To
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-versioneer
+PKG_VERSION:=0.29
+PKG_RELEASE:=1
+
+PYPI_NAME:=versioneer
+PKG_HASH:=5ab283b9857211d61b53318b7c792cf68e798e765ee17c27ade9f6c924235731
+
+PKG_LICENSE:=Unlicense
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_HOST_ONLY:=1
+HOST_BUILD_DEPENDS:=python3/host python-build/host python-installer/host python-wheel/host
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+include ../python3-package.mk
+include ../python3-host-build.mk
+
+define Package/python3-versioneer
+ SECTION:=lang
+ CATEGORY:=Languages
+ SUBMENU:=Python
+ TITLE:=Easy VCS-based management of project version strings
+ URL:=https://github.com/python-versioneer/python-versioneer
+ DEPENDS:=+python3-light
+ BUILDONLY:=1
+endef
+
+define Package/python3-versioneer/description
+This is a tool for managing a recorded version number in
+setuptools-based python projects. The goal is to remove the tedious and
+error-prone "update the embedded version string" step from your release
+process. Making a new release should be as easy as recording a new tag
+in your version-control system, and maybe making new tarballs.
+endef
+
+$(eval $(call Py3Package,python3-versioneer))
+$(eval $(call BuildPackage,python3-versioneer))
+$(eval $(call BuildPackage,python3-versioneer-src))
+$(eval $(call HostBuild))
include $(TOPDIR)/rules.mk
PKG_NAME:=python-websocket-client
-PKG_VERSION:=1.6.2
+PKG_VERSION:=1.6.4
PKG_RELEASE:=1
PYPI_NAME:=websocket-client
-PKG_HASH:=53e95c826bf800c4c465f50093a8c4ff091c7327023b10bfaff40cf1ef170eaa
+PKG_HASH:=b3324019b3c28572086c4a319f91d1dcd44e6e11cd340232978c684a7650d0df
PKG_MAINTAINER:=Javier Marcet <javier@marcet.info>
PKG_LICENSE:=Apache-2.0
include $(TOPDIR)/rules.mk
PKG_NAME:=python-wheel
-PKG_VERSION:=0.41.2
+PKG_VERSION:=0.42.0
PKG_RELEASE:=1
PYPI_NAME:=wheel
-PKG_HASH:=0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985
+PKG_HASH:=c45be39f7882c9d34243236f2d63cbd58039e360f85d0913425fbd7ceea617a8
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE.txt
include $(TOPDIR)/rules.mk
PKG_NAME:=python-zope-interface
-PKG_VERSION:=6.0
+PKG_VERSION:=6.1
PKG_RELEASE:=1
PYPI_NAME:=zope.interface
-PKG_HASH:=aab584725afd10c710b8f1e6e208dbee2d0ad009f57d674cb9d1b3964037275d
+PKG_HASH:=2fdc7ccbd6eb6b7df5353012fbed6c3c5d04ceaca0038f75e601060e95345309
PKG_LICENSE:=ZPL-2.1
PKG_LICENSE_FILES:=LICENSE.txt
SUBMENU:=Python
TITLE:=Interfaces for Python
URL:=https://github.com/zopefoundation/zope.interface
- DEPENDS:=+python3-light
+ DEPENDS:=+python3-light +python3-logging
endef
define Package/python3-zope-interface/description
--- a/setup.py
+++ b/setup.py
-@@ -124,7 +124,7 @@ setup(name='zope.interface',
+@@ -125,7 +125,7 @@ setup(name='zope.interface',
"Framework :: Zope :: 3",
"Topic :: Software Development :: Libraries :: Python Modules",
],
package_dir={'': 'src'},
namespace_packages=["zope"],
cmdclass={
-@@ -132,6 +132,7 @@ setup(name='zope.interface',
+@@ -133,6 +133,7 @@ setup(name='zope.interface',
},
test_suite='zope.interface.tests',
include_package_data=True,
--- /dev/null
+#!/bin/sh
+
+[ "$1" = python3-zope-interface ] || exit 0
+
+python3 -c 'import zope.interface'
CFLAGS="$(HOST_CFLAGS)" \
CPPFLAGS="$(HOST_CPPFLAGS) -I$(HOST_PYTHON3_INC_DIR)" \
LDFLAGS="$(HOST_LDFLAGS) -lpython$(PYTHON3_VERSION) -Wl$(comma)-rpath$(comma)$(STAGING_DIR_HOSTPKG)/lib" \
- CARGO_HOME="$(CARGO_HOME)" \
- PATH="$(CARGO_HOME)/bin:$(PATH)"
+ $(CARGO_HOST_CONFIG_VARS) \
+ SETUPTOOLS_RUST_CARGO_PROFILE="$(CARGO_HOST_PROFILE)"
# $(1) => directory of python script
# $(2) => python script and its arguments
_python_sysroot="$(STAGING_DIR)" \
_python_prefix="/usr" \
_python_exec_prefix="/usr" \
- CARGO_BUILD_TARGET="$(RUSTC_TARGET_ARCH)" \
- CARGO_HOME="$(CARGO_HOME)" \
- PATH="$(CARGO_HOME)/bin:$(PATH)" \
+ $(CARGO_PKG_CONFIG_VARS) \
PYO3_CROSS_LIB_DIR="$(PYTHON3_LIB_DIR)" \
- RUSTFLAGS="$(CARGO_RUSTFLAGS)"
+ SETUPTOOLS_RUST_CARGO_PROFILE="$(CARGO_PKG_PROFILE)"
# $(1) => directory of python script
# $(2) => python script and its arguments
# Note: keep in sync with setuptools & pip
PYTHON3_VERSION_MAJOR:=3
PYTHON3_VERSION_MINOR:=11
-PYTHON3_VERSION_MICRO:=5
+PYTHON3_VERSION_MICRO:=7
PYTHON3_VERSION:=$(PYTHON3_VERSION_MAJOR).$(PYTHON3_VERSION_MINOR)
-PYTHON3_SETUPTOOLS_PKG_RELEASE:=1
+PYTHON3_SETUPTOOLS_PKG_RELEASE:=2
PYTHON3_PIP_PKG_RELEASE:=1
PYTHON3_SETUPTOOLS_VERSION:=65.5.0
PKG_SOURCE:=Python-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://www.python.org/ftp/python/$(PKG_VERSION)
-PKG_HASH:=85cd12e9cf1d6d5a45f17f7afe1cebe7ee628d3282281c492e86adf636defa3f
+PKG_HASH:=18e1aa7e66ff3a58423d59ed22815a6954e53342122c45df20c96877c062b9b7
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=Python-2.0.1 0BSD
--- /dev/null
+From e359a7a3c4f9e70360a068bef19c95938fdacede Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Wed, 23 Dec 2015 11:33:14 +0100
+Subject: [PATCH] Adjust library/header paths for cross-compilation
+
+When cross-compiling third-party extensions, the get_python_inc() or
+get_python_lib() can be called, to return the path to headers or
+libraries. However, they use the sys.prefix of the host Python, which
+returns incorrect paths when cross-compiling (paths pointing to host
+headers and libraries).
+
+In order to fix this, we introduce the _python_sysroot, _python_prefix
+and _python_exec_prefix variables, that allow to override these
+values, and get correct header/library paths when cross-compiling
+third-party Python modules.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+[adapt for setuptools, rename environment variable, use fixed lib path]
+Signed-off-by: Jeffery To <jeffery.to@gmail.com>
+---
+ Lib/distutils/command/build_ext.py | 5 ++++-
+ Lib/sysconfig.py | 15 +++++++++++----
+ 2 files changed, 15 insertions(+), 5 deletions(-)
+
+--- a/setuptools/_distutils/command/build_ext.py
++++ b/setuptools/_distutils/command/build_ext.py
+@@ -238,7 +238,10 @@ class build_ext(Command):
+ if sysconfig.get_config_var('Py_ENABLE_SHARED'):
+ if not sysconfig.python_build:
+ # building third party extensions
+- self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
++ libdir = sysconfig.get_config_var('LIBDIR')
++ if 'STAGING_DIR' in os.environ:
++ libdir = os.environ.get('STAGING_DIR') + '/usr/lib'
++ self.library_dirs.append(libdir)
+ else:
+ # building python standard extensions
+ self.library_dirs.append('.')
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
-@@ -2123,6 +2123,7 @@ libinstall: all $(srcdir)/Modules/xxmodu
+@@ -2133,6 +2133,7 @@ libinstall: all $(srcdir)/Modules/xxmodu
$(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \
$(DESTDIR)$(LIBDEST)/distutils/tests ; \
fi
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
$(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
-j0 -d $(LIBDEST) -f \
-@@ -2150,6 +2151,7 @@ libinstall: all $(srcdir)/Modules/xxmodu
+@@ -2160,6 +2161,7 @@ libinstall: all $(srcdir)/Modules/xxmodu
$(PYTHON_FOR_BUILD) -Wi -OO $(DESTDIR)$(LIBDEST)/compileall.py \
-j0 -d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
-@@ -2168,7 +2168,7 @@ python-config: $(srcdir)/Misc/python-con
+@@ -2178,7 +2178,7 @@ python-config: $(srcdir)/Misc/python-con
@ # On Darwin, always use the python version of the script, the shell
@ # version doesn't use the compiler customizations that are provided
@ # in python (_osx_support.py).
+#endif
--- a/configure.ac
+++ b/configure.ac
-@@ -917,180 +917,14 @@ fi
+@@ -925,180 +925,14 @@ fi
AC_MSG_CHECKING([for the platform triplet based on compiler characteristics])
--- /dev/null
+menu "Configuration options (for developers)"
+
+config RUST_SCCACHE
+ bool "Use sccache"
+ help
+ Shared compilation cache; see https://github.com/mozilla/sccache
+
+config RUST_SCCACHE_DIR
+ string "Set sccache directory" if RUST_SCCACHE
+ default ""
+ help
+ Store sccache in this directory.
+ If not set, uses './.sccache'
+
+endmenu
include $(TOPDIR)/rules.mk
PKG_NAME:=rust
-PKG_VERSION:=1.72.0
-PKG_RELEASE:=2
+PKG_VERSION:=1.74.0
+PKG_RELEASE:=1
PKG_SOURCE:=rustc-$(PKG_VERSION)-src.tar.gz
PKG_SOURCE_URL:=https://static.rust-lang.org/dist/
-PKG_HASH:=ea9d61bbb51d76b6ea681156f69f0e0596b59722f04414b01c6e100b4b5be3a1
+PKG_HASH:=882b584bc321c5dcfe77cdaa69f277906b936255ef7808fcd5c7492925cf1049
HOST_BUILD_DIR:=$(BUILD_DIR)/host/rustc-$(PKG_VERSION)-src
PKG_MAINTAINER:=Luca Barbato <lu_zero@luminem.org>
PKG_LICENSE:=Apache-2.0 MIT
PKG_LICENSE_FILES:=LICENSE-APACHE LICENSE-MIT
-HOST_BUILD_DEPENDS:=python3/host
PKG_HOST_ONLY:=1
+PKG_BUILD_FLAGS:=no-mips16
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/package.mk
TITLE:=Rust Programming Language Compiler
URL:=https://www.rust-lang.org/
DEPENDS:=$(RUST_ARCH_DEPENDS)
- BUILDONLY:=1
endef
define Package/rust/description
guarantee memory safety by using a borrow checker to validate references.
endef
+define Package/rust/config
+ source "$(SOURCE)/Config.in"
+endef
+
# Rust-lang has an uninstall script
-RUST_UNINSTALL:=$(CARGO_HOME)/lib/rustlib/uninstall.sh
+RUST_UNINSTALL:=$(STAGING_DIR)/host/lib/rustlib/uninstall.sh
# Target Flags
TARGET_CONFIGURE_ARGS = \
--set=target.$(RUSTC_TARGET_ARCH).cxx=$(TARGET_CXX_NOCACHE) \
--set=target.$(RUSTC_TARGET_ARCH).linker=$(TARGET_CC_NOCACHE) \
--set=target.$(RUSTC_TARGET_ARCH).ranlib=$(TARGET_RANLIB) \
+ --set=target.$(RUSTC_TARGET_ARCH).crt-static=false \
$(if $(CONFIG_USE_MUSL),--set=target.$(RUSTC_TARGET_ARCH).musl-root=$(TOOLCHAIN_DIR))
# CARGO_HOME is an environmental
-HOST_CONFIGURE_OPTS += CARGO_HOME="$(CARGO_HOME)"
+HOST_CONFIGURE_VARS += CARGO_HOME="$(CARGO_HOME)"
# Rust Configuration Arguments
HOST_CONFIGURE_ARGS = \
--build=$(RUSTC_HOST_ARCH) \
--target=$(RUSTC_TARGET_ARCH),$(RUSTC_HOST_ARCH) \
--host=$(RUSTC_HOST_ARCH) \
- --prefix=$(CARGO_HOME) \
- --bindir=$(CARGO_HOME)/bin \
- --libdir=$(CARGO_HOME)/lib \
- --sysconfdir=$(CARGO_HOME)/etc \
- --datadir=$(CARGO_HOME)/share \
- --mandir=$(CARGO_HOME)/man \
- --dist-compression-formats=xz \
+ --prefix=$(STAGING_DIR)/host \
+ --bindir=$(STAGING_DIR)/host/bin \
+ --libdir=$(STAGING_DIR)/host/lib \
+ --sysconfdir=$(STAGING_DIR)/host/etc \
+ --datadir=$(STAGING_DIR)/host/share \
+ --mandir=$(STAGING_DIR)/host/man \
+ --dist-compression-formats=gz \
--enable-missing-tools \
--disable-sanitizers \
--release-channel=stable \
endef
define Host/Compile
- ( \
- cd $(HOST_BUILD_DIR) ; \
- $(PYTHON) x.py --config ./config.toml dist build-manifest cargo llvm-tools \
- rustc rust-std rust-src ; \
- )
+ $(RUST_SCCACHE_VARS) \
+ CARGO_HOME=$(CARGO_HOME) \
+ TARGET_CFLAGS="$(TARGET_CFLAGS)" \
+ OPENWRT_RUSTC_BOOTSTRAP_CACHE=$(DL_DIR)/rustc \
+ $(PYTHON) $(HOST_BUILD_DIR)/x.py \
+ --build-dir $(HOST_BUILD_DIR)/build \
+ --config $(HOST_BUILD_DIR)/config.toml \
+ dist build-manifest cargo llvm-tools rustc rust-std rust-src
endef
define Host/Install
( \
cd $(HOST_BUILD_DIR)/build/dist ; \
- find -iname "*.xz" -exec tar -xJf {} \; ; \
- find ./* -type f -name install.sh -execdir sh {} --prefix=$(CARGO_HOME) --disable-ldconfig \; ; \
- \
- sed -e 's|@RUSTC_TARGET_ARCH@|$(RUSTC_TARGET_ARCH)|g' \
- -e 's|@TARGET_CC_NOCACHE@|$(TARGET_CC_NOCACHE)|g' \
- $(CURDIR)/files/cargo-config > $(CARGO_HOME)/config.toml ; \
+ for targz in *.tar.gz; do \
+ $(STAGING_DIR_HOST)/bin/libdeflate-gzip -dc "$$$$targz" | tar -xf - ; \
+ done ; \
+ find . -mindepth 2 -maxdepth 2 -type f -name install.sh \
+ -execdir bash '{}' --prefix=$(STAGING_DIR)/host --disable-ldconfig \; ; \
)
endef
+++ /dev/null
-[target.@RUSTC_TARGET_ARCH@]
-linker = "@TARGET_CC_NOCACHE@"
-
-[profile.stripped]
-inherits = "release"
-opt-level = "s"
-strip = true
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
-@@ -430,9 +430,9 @@ dependencies = [
+@@ -424,9 +424,9 @@ dependencies = [
[[package]]
name = "lzma-sys"
dependencies = [
"cc",
"libc",
-@@ -899,9 +899,9 @@ dependencies = [
+@@ -871,9 +871,9 @@ dependencies = [
[[package]]
name = "xz2"
--- /dev/null
+--- a/src/bootstrap/bootstrap.py
++++ b/src/bootstrap/bootstrap.py
+@@ -557,7 +557,7 @@ class RustBuild(object):
+ shutil.rmtree(bin_root)
+
+ key = self.stage0_compiler.date
+- cache_dst = os.path.join(self.build_dir, "cache")
++ cache_dst = os.getenv('OPENWRT_RUSTC_BOOTSTRAP_CACHE', os.path.join(self.build_dir, "cache"))
+ rustc_cache = os.path.join(cache_dst, key)
+ if not os.path.exists(rustc_cache):
+ os.makedirs(rustc_cache)
+--- a/src/bootstrap/download.rs
++++ b/src/bootstrap/download.rs
+@@ -211,7 +211,13 @@ impl Config {
+ Some(other) => panic!("unsupported protocol {other} in {url}"),
+ None => panic!("no protocol in {url}"),
+ }
+- t!(std::fs::rename(&tempfile, dest_path));
++ match std::fs::rename(&tempfile, dest_path) {
++ Ok(v) => v,
++ Err(_) => {
++ t!(std::fs::copy(&tempfile, dest_path));
++ t!(std::fs::remove_file(&tempfile));
++ }
++ }
+ }
+
+ fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
+@@ -529,7 +535,10 @@ impl Config {
+ key: &str,
+ destination: &str,
+ ) {
+- let cache_dst = self.out.join("cache");
++ let cache_dst = match env::var_os("OPENWRT_RUSTC_BOOTSTRAP_CACHE") {
++ Some(v) => PathBuf::from(v),
++ None => self.out.join("cache"),
++ };
+ let cache_dir = cache_dst.join(key);
+ if !cache_dir.exists() {
+ t!(fs::create_dir_all(&cache_dir));
+@@ -656,7 +665,10 @@ download-rustc = false
+ let llvm_assertions = self.llvm_assertions;
+
+ let cache_prefix = format!("llvm-{llvm_sha}-{llvm_assertions}");
+- let cache_dst = self.out.join("cache");
++ let cache_dst = match env::var_os("OPENWRT_RUSTC_BOOTSTRAP_CACHE") {
++ Some(v) => PathBuf::from(v),
++ None => self.out.join("cache"),
++ };
+ let rustc_cache = cache_dst.join(cache_prefix);
+ if !rustc_cache.exists() {
+ t!(fs::create_dir_all(&rustc_cache));
--- /dev/null
+This patch bumps all libc dependencies and checksums to 0.2.147, which includes the fix for musl 1.2.4.
+
+--- a/vendor/addr2line-0.19.0/Cargo.lock
++++ b/vendor/addr2line-0.19.0/Cargo.lock
+@@ -235,9 +235,9 @@ checksum = "e2abad23fbc42b3700f2f279844d
+
+ [[package]]
+ name = "libc"
+-version = "0.2.126"
++version = "0.2.147"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
++checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+ [[package]]
+ name = "memchr"
+--- a/vendor/backtrace-0.3.67/Cargo.lock
++++ b/vendor/backtrace-0.3.67/Cargo.lock
+@@ -64,9 +64,9 @@ checksum = "dec7af912d60cdbd3677c1af9352
+
+ [[package]]
+ name = "libc"
+-version = "0.2.138"
++version = "0.2.147"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
++checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+ [[package]]
+ name = "libloading"
+--- a/vendor/cranelift-jit/Cargo.lock
++++ b/vendor/cranelift-jit/Cargo.lock
+@@ -224,9 +224,9 @@ dependencies = [
+
+ [[package]]
+ name = "libc"
+-version = "0.2.141"
++version = "0.2.147"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
++checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+ [[package]]
+ name = "log"
+--- a/vendor/crossbeam-channel/Cargo.lock
++++ b/vendor/crossbeam-channel/Cargo.lock
+@@ -50,9 +50,9 @@ dependencies = [
+
+ [[package]]
+ name = "libc"
+-version = "0.2.141"
++version = "0.2.147"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
++checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+ [[package]]
+ name = "num_cpus"
+--- a/vendor/elasticlunr-rs/Cargo.lock
++++ b/vendor/elasticlunr-rs/Cargo.lock
+@@ -555,9 +555,9 @@ checksum = "e2abad23fbc42b3700f2f279844d
+
+ [[package]]
+ name = "libc"
+-version = "0.2.140"
++version = "0.2.147"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
++checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+ [[package]]
+ name = "lindera"
+--- a/vendor/handlebars/Cargo.lock
++++ b/vendor/handlebars/Cargo.lock
+@@ -550,9 +550,9 @@ checksum = "e2abad23fbc42b3700f2f279844d
+
+ [[package]]
+ name = "libc"
+-version = "0.2.140"
++version = "0.2.147"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
++checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+ [[package]]
+ name = "lock_api"
+--- a/vendor/icu_locid/Cargo.lock
++++ b/vendor/icu_locid/Cargo.lock
+@@ -318,9 +318,9 @@ checksum = "e2abad23fbc42b3700f2f279844d
+
+ [[package]]
+ name = "libc"
+-version = "0.2.141"
++version = "0.2.147"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
++checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+ [[package]]
+ name = "litemap"
+--- a/vendor/libffi/Cargo.lock
++++ b/vendor/libffi/Cargo.lock
+@@ -10,9 +10,9 @@ checksum = "50d30906286121d95be3d479533b
+
+ [[package]]
+ name = "libc"
+-version = "0.2.140"
++version = "0.2.147"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
++checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+ [[package]]
+ name = "libffi"
+--- a/vendor/tracing-tree/Cargo.lock
++++ b/vendor/tracing-tree/Cargo.lock
+@@ -296,9 +296,9 @@ checksum = "e2abad23fbc42b3700f2f279844d
+
+ [[package]]
+ name = "libc"
+-version = "0.2.141"
++version = "0.2.147"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
++checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+ [[package]]
+ name = "linux-raw-sys"
#
# Copyright (C) 2023 Luca Barbato and Donald Hoskins
+# Variables (all optional) to be set in package Makefiles:
+#
+# RUST_HOST_FEATURES - list of options, default empty
+#
+# Space or comma separated list of features to activate
+#
+# e.g. RUST_HOST_FEATURES:=enable-foo,with-bar
+
ifeq ($(origin RUST_INCLUDE_DIR),undefined)
RUST_INCLUDE_DIR:=$(dir $(lastword $(MAKEFILE_LIST)))
endif
include $(RUST_INCLUDE_DIR)/rust-values.mk
+CARGO_HOST_VARS= \
+ $(CARGO_HOST_CONFIG_VARS) \
+ CC=$(HOSTCC_NOCACHE) \
+ MAKEFLAGS="$(HOST_JOBS)"
+
# $(1) path to the package (optional)
# $(2) additional arguments to cargo (optional)
define Host/Compile/Cargo
- ( \
- cd $(HOST_BUILD_DIR) ; \
- export PATH="$(CARGO_HOME)/bin:$(PATH)" ; \
- CARGO_HOME=$(CARGO_HOME) \
- CC=$(HOSTCC_NOCACHE) \
- cargo install -v \
- --profile stripped \
- $(if $(RUST_PKG_FEATURES),--features "$(RUST_PKG_FEATURES)") \
- --root $(HOST_INSTALL_DIR) \
- --path "$(if $(strip $(1)),$(strip $(1)),.)" $(2) ; \
- )
+ +$(CARGO_HOST_VARS) \
+ cargo install -v \
+ --profile $(CARGO_HOST_PROFILE) \
+ $(if $(RUST_HOST_FEATURES),--features "$(RUST_HOST_FEATURES)") \
+ --root $(HOST_INSTALL_DIR) \
+ --path "$(HOST_BUILD_DIR)/$(if $(strip $(1)),$(strip $(1)))" \
+ $(if $(filter --jobserver%,$(HOST_JOBS)),,-j1) \
+ $(2)
endef
define Host/Uninstall/Cargo
- ( \
- cd $(HOST_BUILD_DIR) ; \
- export PATH="$(CARGO_HOME)/bin:$(PATH)" ; \
- CARGO_HOME=$(CARGO_HOME) \
- CC=$(HOSTCC_NOCACHE) \
- cargo uninstall -v \
- --root $(HOST_INSTALL_DIR) || true ; \
- )
+ +$(CARGO_HOST_VARS) \
+ cargo uninstall -v \
+ --root $(HOST_INSTALL_DIR) \
+ || true
endef
define RustBinHostBuild
endif
include $(RUST_INCLUDE_DIR)/rust-values.mk
+CARGO_PKG_VARS= \
+ $(CARGO_PKG_CONFIG_VARS) \
+ CC=$(HOSTCC_NOCACHE) \
+ MAKEFLAGS="$(PKG_JOBS)"
+
# $(1) path to the package (optional)
# $(2) additional arguments to cargo (optional)
define Build/Compile/Cargo
- ( \
- cd $(PKG_BUILD_DIR) ; \
- export PATH="$(CARGO_HOME)/bin:$(PATH)" ; \
- CARGO_HOME=$(CARGO_HOME) \
- TARGET_CFLAGS="$(TARGET_CFLAGS) $(RUSTC_CFLAGS)" \
- TARGET_CC=$(TARGET_CC_NOCACHE) \
- CC=$(HOSTCC_NOCACHE) \
- RUSTFLAGS="$(CARGO_RUSTFLAGS)" \
- $(CARGO_VARS) \
- cargo install -v \
- --profile stripped \
- --target $(RUSTC_TARGET_ARCH) \
- $(if $(strip $(RUST_PKG_FEATURES)),--features "$(strip $(RUST_PKG_FEATURES))") \
- --root $(PKG_INSTALL_DIR) \
- --path "$(if $(strip $(1)),$(strip $(1)),.)" \
- $(2) ; \
- )
+ +$(CARGO_PKG_VARS) \
+ cargo install -v \
+ --profile $(CARGO_PKG_PROFILE) \
+ $(if $(strip $(RUST_PKG_FEATURES)),--features "$(strip $(RUST_PKG_FEATURES))") \
+ --root $(PKG_INSTALL_DIR) \
+ --path "$(PKG_BUILD_DIR)/$(if $(strip $(1)),$(strip $(1)))" \
+ $(if $(filter --jobserver%,$(PKG_JOBS)),,-j1) \
+ $(2)
endef
define RustBinPackage
# Rust Environmental Vars
RUSTC_HOST_SUFFIX:=$(word 4, $(subst -, ,$(GNU_HOST_NAME)))
RUSTC_HOST_ARCH:=$(HOST_ARCH)-unknown-linux-$(RUSTC_HOST_SUFFIX)
-CARGO_HOME:=$(STAGING_DIR)/host/cargo
-CARGO_VARS?=
+CARGO_HOME:=$(DL_DIR)/cargo
ifeq ($(CONFIG_USE_MUSL),y)
# Force linking of the SSP library for musl
ifeq ($(CONFIG_HAS_FPU),y)
RUSTC_TARGET_ARCH:=$(subst musleabi,musleabihf,$(RUSTC_TARGET_ARCH))
+ RUSTC_TARGET_ARCH:=$(subst gnueabi,gnueabihf,$(RUSTC_TARGET_ARCH))
endif
endif
# Support only a subset for now.
RUST_ARCH_DEPENDS:=@(aarch64||arm||i386||i686||mips||mipsel||mips64||mips64el||mipsel||powerpc64||riscv64||x86_64)
+
+ifneq ($(CONFIG_RUST_SCCACHE),)
+ RUST_SCCACHE_DIR:=$(if $(call qstrip,$(CONFIG_RUST_SCCACHE_DIR)),$(call qstrip,$(CONFIG_RUST_SCCACHE_DIR)),$(TOPDIR)/.sccache)
+
+ RUST_SCCACHE_VARS:= \
+ CARGO_INCREMENTAL=0 \
+ RUSTC_WRAPPER=sccache \
+ SCCACHE_DIR=$(RUST_SCCACHE_DIR)
+endif
+
+CARGO_HOST_CONFIG_VARS= \
+ $(RUST_SCCACHE_VARS) \
+ CARGO_HOME=$(CARGO_HOME)
+
+CARGO_HOST_PROFILE:=release
+
+CARGO_PKG_CONFIG_VARS= \
+ $(RUST_SCCACHE_VARS) \
+ CARGO_BUILD_TARGET=$(RUSTC_TARGET_ARCH) \
+ CARGO_HOME=$(CARGO_HOME) \
+ CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 \
+ CARGO_PROFILE_RELEASE_DEBUG=false \
+ CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS=false \
+ CARGO_PROFILE_RELEASE_LTO=true \
+ CARGO_PROFILE_RELEASE_OPT_LEVEL=z \
+ CARGO_PROFILE_RELEASE_OVERFLOW_CHECKS=true \
+ CARGO_PROFILE_RELEASE_PANIC=unwind \
+ CARGO_PROFILE_RELEASE_RPATH=false \
+ CARGO_TARGET_$(subst -,_,$(call toupper,$(RUSTC_TARGET_ARCH)))_LINKER=$(TARGET_CC_NOCACHE) \
+ RUSTFLAGS="$(CARGO_RUSTFLAGS)" \
+ TARGET_CC=$(TARGET_CC_NOCACHE) \
+ TARGET_CFLAGS="$(TARGET_CFLAGS) $(RUSTC_CFLAGS)"
+
+CARGO_PKG_PROFILE:=$(if $(CONFIG_DEBUG),dev,release)
For more information please see the avahi documentation.
endef
-define Package/libavahi-compat-libdnssd
- $(call Package/avahi/Default)
- SECTION:=libs
- CATEGORY:=Libraries
- VARIANT:=dbus
- DEPENDS:=+libavahi-client
- TITLE+= (libdnssd)
-endef
-
-define Package/libavahi-compat-libdnssd/description
-$(call Package/avahi/Default/description)
- .
- This packages adds the libavahi-compat-libdnssd library.
- It also automatically adds the required libavahi-client package.
- For more information please see the avahi documentation.
-endef
-
define Package/avahi-utils
$(call Package/avahi/Default)
SUBMENU:=IP Addresses and Names
--with-autoipd-group=nogroup
ifeq ($(BUILD_VARIANT),dbus)
-ifneq ($(CONFIG_PACKAGE_libavahi-compat-libdnssd),)
-CONFIGURE_ARGS += \
- --enable-compat-libdns_sd
-endif
CONFIGURE_ARGS += \
--enable-dbus
else
$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libavahi-* $(1)/usr/lib/
-ifneq ($(CONFIG_PACKAGE_libavahi-compat-libdnssd),)
-ifeq ($(BUILD_VARIANT),dbus)
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdns_sd* $(1)/usr/lib/
-endif
-endif
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
endef
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libavahi-client.so.* $(1)/usr/lib/
endef
-define Package/libavahi-compat-libdnssd/install
- $(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdns_sd.so* $(1)/usr/lib/
-endef
-
define Package/avahi-utils/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
endef
$(eval $(call BuildPackage,libavahi-client))
-$(eval $(call BuildPackage,libavahi-compat-libdnssd))
$(eval $(call BuildPackage,avahi-utils))
$(eval $(call BuildPackage,libavahi-dbus-support))
$(eval $(call BuildPackage,libavahi-nodbus-support))
PKG_NAME:=cyrus-sasl
PKG_VERSION:=2.1.28
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
TITLE+= (sasldb libraries)
endef
+define Package/libsasl2-utils
+ $(call Package/libsasl2/Default)
+ DEPENDS:=+libsasl2 +libdb47
+ TITLE+= (sasldb utilities)
+endef
+
TARGET_CFLAGS += $(FPIC)
CONFIGURE_ARGS += \
--enable-shared \
$(CP) $(PKG_INSTALL_DIR)/usr/lib/sasl2/libsasldb.so* $(1)/usr/lib/sasl2/
endef
+define Package/libsasl2-utils/install
+ $(INSTALL_DIR) $(1)/usr/sbin/
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/{pluginviewer,sasldblistusers2,saslpasswd2} $(1)/usr/sbin/
+endef
+
$(eval $(call BuildPackage,libsasl2))
$(eval $(call BuildPackage,libsasl2-sasldb))
+$(eval $(call BuildPackage,libsasl2-utils))
PKG_NAME:=efivar
PKG_VERSION:=38
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://github.com/rhboot/efivar/releases/download/$(PKG_VERSION)
SECTION:=libs
CATEGORY:=Libraries
TITLE:=Tools and libraries to work with EFI variables
- DEPENDS:=@TARGET_x86_64
+ DEPENDS:=@(TARGET_x86_64||TARGET_armsr_armv8)
URL:=https://github.com/rhboot/efibootmgr
endef
--- /dev/null
+From ca48d3964d26f5e3b38d73655f19b1836b16bd2d Mon Sep 17 00:00:00 2001
+From: Alexander Kanavin <alex@linutronix.de>
+Date: Tue, 18 Jan 2022 11:53:41 +0100
+Subject: [PATCH] src/Makefile: build util.c separately for makeguids
+
+util.c needs to be built twice when cross-compiling:
+for the build machine to be able to link with
+makeguids which then runs during the same build,
+and then for the actual target.
+
+Signed-off-by: Alexander Kanavin <alex@linutronix.de>
+---
+ src/Makefile | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -28,10 +28,13 @@ EFIVAR_OBJECTS = $(patsubst %.S,%.o,$(pa
+ EFISECDB_SOURCES = efisecdb.c guid-symbols.c secdb-dump.c util.c
+ EFISECDB_OBJECTS = $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(EFISECDB_SOURCES)))
+ GENERATED_SOURCES = include/efivar/efivar-guids.h guid-symbols.c
+-MAKEGUIDS_SOURCES = makeguids.c util.c
++MAKEGUIDS_SOURCES = makeguids.c util-makeguids.c
+ MAKEGUIDS_OBJECTS = $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(MAKEGUIDS_SOURCES)))
+ MAKEGUIDS_OUTPUT = $(GENERATED_SOURCES) guids.lds
+
++util-makeguids.c : util.c
++ cp util.c util-makeguids.c
++
+ ALL_SOURCES=$(LIBEFISEC_SOURCES) $(LIBEFIBOOT_SOURCES) $(LIBEFIVAR_SOURCES) \
+ $(MAKEGUIDS_SOURCES) $(GENERATED_SOURCES) $(EFIVAR_SOURCES) \
+ $(sort $(wildcard include/efivar/*.h))
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE.md
PKG_VERSION:=0.9.7
-PKG_RELEASE:=4
+PKG_RELEASE:=5
# Use this for official releasees
PKG_HASH:=12b7b046004db29317b7b937dc794abf719c400ba3115af8d41849127b562681
--- /dev/null
+From 19fe46ecb796c0d30d66dd7e7038fd7f2d6f9bf4 Mon Sep 17 00:00:00 2001
+From: Florian Lindner <florian.lindner@student.tuwien.ac.at>
+Date: Thu, 8 Jun 2023 16:55:34 +0200
+Subject: [PATCH] bindings: include <cstdint> in key.hpp for uint8_t
+
+---
+ src/bindings/cpp/include/key.hpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/src/bindings/cpp/include/key.hpp
++++ b/src/bindings/cpp/include/key.hpp
+@@ -10,6 +10,7 @@
+ #define ELEKTRA_KEY_HPP
+
+ #include <cstdarg>
++#include <cstdint>
+ #include <cstring>
+ #include <functional>
+ #include <locale>
PKG_NAME:=h2o
PKG_VERSION:=2.2.6
-PKG_RELEASE:=14
+PKG_RELEASE:=15
PKG_SOURCE_URL:=https://codeload.github.com/h2o/h2o/tar.gz/v${PKG_VERSION}?
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
--- /dev/null
+commit d07b601a5549798f8e500582336756e04dfd25c5
+Author: Remi Gacogne <remi.gacogne@powerdns.com>
+Date: Tue Oct 10 15:47:57 2023 +0200
+
+ [http2] delay processing requests upon observing suspicious behavior
+
+ Backport of 94fbc54b6c9309912fe3d53e7b63408bbe9a1b0d to v2.2.x
+
+--- a/include/h2o.h
++++ b/include/h2o.h
+@@ -378,6 +378,10 @@ struct st_h2o_globalconf_t {
+ * list of callbacks
+ */
+ h2o_protocol_callbacks_t callbacks;
++ /**
++ * milliseconds to delay processing requests when suspicious behavior is detected
++ */
++ uint64_t dos_delay;
+ } http2;
+
+ struct {
+@@ -590,6 +594,10 @@ struct st_h2o_context_t {
+ * timeout entry used for graceful shutdown
+ */
+ h2o_timeout_entry_t _graceful_shutdown_timeout;
++ /*
++ * dos timeout
++ */
++ h2o_timeout_t dos_delay_timeout;
+ struct {
+ /**
+ * counter for http2 errors internally emitted by h2o
+--- a/include/h2o/http2_internal.h
++++ b/include/h2o/http2_internal.h
+@@ -179,6 +179,7 @@ struct st_h2o_http2_stream_t {
+ h2o_linklist_t link;
+ h2o_http2_scheduler_openref_t scheduler;
+ } _refs;
++ unsigned reset_by_peer : 1;
+ h2o_send_state_t send_state; /* state of the ostream, only used in push mode */
+ /* placed at last since it is large and has it's own ctor */
+ h2o_req_t req;
+@@ -232,6 +233,13 @@ struct st_h2o_http2_conn_t {
+ } _write;
+ h2o_cache_t *push_memo;
+ h2o_http2_casper_t *casper;
++ /**
++ * DoS mitigation; the idea here is to delay processing requests when observing suspicious behavior
++ */
++ struct {
++ h2o_timeout_entry_t process_delay;
++ size_t reset_budget; /* RST_STREAM frames are considered suspicious when this value goes down to zero */
++ } dos_mitigation;
+ };
+
+ int h2o_http2_update_peer_settings(h2o_http2_settings_t *settings, const uint8_t *src, size_t len, const char **err_desc);
+--- a/lib/core/config.c
++++ b/lib/core/config.c
+@@ -196,6 +196,7 @@ void h2o_config_init(h2o_globalconf_t *c
+ config->http2.latency_optimization.min_rtt = 50; // milliseconds
+ config->http2.latency_optimization.max_additional_delay = 10;
+ config->http2.latency_optimization.max_cwnd = 65535;
++ config->http2.dos_delay = 100; /* 100ms processing delay when observing suspicious behavior */
+ config->http2.callbacks = H2O_HTTP2_CALLBACKS;
+ // config->mimemap = h2o_mimemap_create();
+
+--- a/lib/core/configurator.c
++++ b/lib/core/configurator.c
+@@ -531,6 +531,12 @@ static int on_config_http2_casper(h2o_co
+ return 0;
+ }
+
++
++static int on_config_http2_dos_delay(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node)
++{
++ return config_timeout(cmd, node, &ctx->globalconf->http2.dos_delay);
++}
++
+ static int assert_is_mimetype(h2o_configurator_command_t *cmd, yoml_t *node)
+ {
+ if (node->type != YOML_TYPE_SCALAR) {
+@@ -910,6 +916,9 @@ void h2o_configurator__init_core(h2o_glo
+ on_config_http2_push_preload);
+ h2o_configurator_define_command(&c->super, "http2-casper", H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_HOST,
+ on_config_http2_casper);
++ h2o_configurator_define_command(&c->super, "http2-dos-delay",
++ H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR,
++ on_config_http2_dos_delay);
+ h2o_configurator_define_command(&c->super, "file.mime.settypes",
+ (H2O_CONFIGURATOR_FLAG_ALL_LEVELS & ~H2O_CONFIGURATOR_FLAG_EXTENSION) |
+ H2O_CONFIGURATOR_FLAG_EXPECT_MAPPING,
+--- a/lib/core/context.c
++++ b/lib/core/context.c
+@@ -101,6 +101,7 @@ void h2o_context_init(h2o_context_t *ctx
+ h2o_linklist_init_anchor(&ctx->http1._conns);
+ h2o_timeout_init(ctx->loop, &ctx->http2.idle_timeout, config->http2.idle_timeout);
+ h2o_timeout_init(ctx->loop, &ctx->http2.graceful_shutdown_timeout, config->http2.graceful_shutdown_timeout);
++ h2o_timeout_init(ctx->loop, &ctx->http2.dos_delay_timeout, config->http2.dos_delay);
+ h2o_linklist_init_anchor(&ctx->http2._conns);
+ ctx->proxy.client_ctx.loop = loop;
+ h2o_timeout_init(ctx->loop, &ctx->proxy.io_timeout, config->proxy.io_timeout);
+@@ -146,6 +147,7 @@ void h2o_context_dispose(h2o_context_t *
+ h2o_timeout_dispose(ctx->loop, &ctx->http1.req_timeout);
+ h2o_timeout_dispose(ctx->loop, &ctx->http2.idle_timeout);
+ h2o_timeout_dispose(ctx->loop, &ctx->http2.graceful_shutdown_timeout);
++ h2o_timeout_dispose(ctx->loop, &ctx->http2.dos_delay_timeout);
+ h2o_timeout_dispose(ctx->loop, &ctx->proxy.io_timeout);
+ /* what should we do here? assert(!h2o_linklist_is_empty(&ctx->http2._conns); */
+
+--- a/lib/http2/connection.c
++++ b/lib/http2/connection.c
+@@ -161,7 +161,6 @@ static void update_idle_timeout(h2o_http
+ h2o_timeout_unlink(&conn->_timeout_entry);
+
+ if (conn->num_streams.pull.half_closed + conn->num_streams.push.half_closed == 0) {
+- assert(h2o_linklist_is_empty(&conn->_pending_reqs));
+ conn->_timeout_entry.cb = on_idle_timeout;
+ h2o_timeout_link(conn->super.ctx->loop, &conn->super.ctx->http2.idle_timeout, &conn->_timeout_entry);
+ }
+@@ -175,6 +174,9 @@ static int can_run_requests(h2o_http2_co
+
+ static void run_pending_requests(h2o_http2_conn_t *conn)
+ {
++ if (h2o_timeout_is_linked(&conn->dos_mitigation.process_delay))
++ return;
++
+ while (!h2o_linklist_is_empty(&conn->_pending_reqs) && can_run_requests(conn)) {
+ /* fetch and detach a pending stream */
+ h2o_http2_stream_t *stream = H2O_STRUCT_FROM_MEMBER(h2o_http2_stream_t, _refs.link, conn->_pending_reqs.next);
+@@ -226,6 +228,16 @@ void h2o_http2_conn_unregister_stream(h2
+ assert(h2o_http2_scheduler_is_open(&stream->_refs.scheduler));
+ h2o_http2_scheduler_close(&stream->_refs.scheduler);
+
++ /* Decrement reset_budget if the stream was reset by peer, otherwise increment. By doing so, we penalize connections that
++ * generate resets for >50% of requests. */
++ if (stream->reset_by_peer) {
++ if (conn->dos_mitigation.reset_budget > 0)
++ --conn->dos_mitigation.reset_budget;
++ } else {
++ if (conn->dos_mitigation.reset_budget < conn->super.ctx->globalconf->http2.max_concurrent_requests_per_connection)
++ ++conn->dos_mitigation.reset_budget;
++ }
++
+ switch (stream->state) {
+ case H2O_HTTP2_STREAM_STATE_IDLE:
+ case H2O_HTTP2_STREAM_STATE_RECV_HEADERS:
+@@ -272,6 +284,8 @@ void close_connection_now(h2o_http2_conn
+ h2o_hpack_dispose_header_table(&conn->_output_header_table);
+ assert(h2o_linklist_is_empty(&conn->_pending_reqs));
+ h2o_timeout_unlink(&conn->_timeout_entry);
++ if (h2o_timeout_is_linked(&conn->dos_mitigation.process_delay))
++ h2o_timeout_unlink(&conn->dos_mitigation.process_delay);
+ h2o_buffer_dispose(&conn->_write.buf);
+ if (conn->_write.buf_in_flight != NULL)
+ h2o_buffer_dispose(&conn->_write.buf_in_flight);
+@@ -797,11 +811,19 @@ static int handle_rst_stream_frame(h2o_h
+ return H2O_HTTP2_ERROR_PROTOCOL;
+ }
+
+- stream = h2o_http2_conn_get_stream(conn, frame->stream_id);
+- if (stream != NULL) {
++ if ((stream = h2o_http2_conn_get_stream(conn, frame->stream_id)) == NULL)
++ return 0;
++
+ /* reset the stream */
++ stream->reset_by_peer = 1;
+ h2o_http2_stream_reset(conn, stream);
+- }
++
++ /* setup process delay if we've just ran out of reset budget */
++ if (conn->dos_mitigation.reset_budget == 0 && conn->super.ctx->globalconf->http2.dos_delay != 0 &&
++ !h2o_timeout_is_linked(&conn->dos_mitigation.process_delay))
++ h2o_timeout_link(conn->super.ctx->loop, &conn->super.ctx->http2.dos_delay_timeout,
++ &conn->dos_mitigation.process_delay);
++
+ /* TODO log */
+
+ return 0;
+@@ -1204,6 +1226,14 @@ static h2o_iovec_t log_priority_actual_w
+ return h2o_iovec_init(s, len);
+ }
+
++static void on_dos_process_delay(h2o_timeout_entry_t *timer)
++{
++ h2o_http2_conn_t *conn = H2O_STRUCT_FROM_MEMBER(h2o_http2_conn_t, dos_mitigation.process_delay, timer);
++
++ assert(!h2o_timeout_is_linked(&conn->dos_mitigation.process_delay));
++ run_pending_requests(conn);
++}
++
+ static h2o_http2_conn_t *create_conn(h2o_context_t *ctx, h2o_hostconf_t **hosts, h2o_socket_t *sock, struct timeval connected_at)
+ {
+ static const h2o_conn_callbacks_t callbacks = {
+@@ -1240,6 +1270,9 @@ static h2o_http2_conn_t *create_conn(h2o
+ conn->_write.timeout_entry.cb = emit_writereq;
+ h2o_http2_window_init(&conn->_write.window, &conn->peer_settings);
+
++ conn->dos_mitigation.process_delay.cb = on_dos_process_delay;
++ conn->dos_mitigation.reset_budget = conn->super.ctx->globalconf->http2.max_concurrent_requests_per_connection;
++
+ return conn;
+ }
+
--- /dev/null
+commit e47cd15ff1fec9211088c809cb92593800dd4da2
+Author: Peter van Dijk <peter.van.dijk@powerdns.com>
+Date: Wed Oct 11 11:39:48 2023 +0200
+
+ bump soname
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -29,9 +29,9 @@ SET(VERSION_MINOR "2")
+ SET(VERSION_PATCH "6")
+ SET(VERSION_PRERELEASE "")
+ SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_PRERELEASE}")
+-SET(LIBRARY_VERSION_MAJOR "0")
+-SET(LIBRARY_VERSION_MINOR "13")
+-SET(LIBRARY_VERSION_PATCH "6")
++SET(LIBRARY_VERSION_MAJOR "1")
++SET(LIBRARY_VERSION_MINOR "0")
++SET(LIBRARY_VERSION_PATCH "0")
+ SET(LIBRARY_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}${VERSION_PRERELEASE}")
+ SET(LIBRARY_SOVERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}")
+
+--- a/include/h2o/version.h
++++ b/include/h2o/version.h
+@@ -28,8 +28,8 @@
+ #define H2O_VERSION_MINOR 2
+ #define H2O_VERSION_PATCH 6
+
+-#define H2O_LIBRARY_VERSION_MAJOR 0
+-#define H2O_LIBRARY_VERSION_MINOR 13
+-#define H2O_LIBRARY_VERSION_PATCH 6
++#define H2O_LIBRARY_VERSION_MAJOR 1
++#define H2O_LIBRARY_VERSION_MINOR 0
++#define H2O_LIBRARY_VERSION_PATCH 0
+
+ #endif
include $(TOPDIR)/rules.mk
PKG_NAME:=icu4c
-MAJOR_VERSION:=73
-MINOR_VERSION:=2
+MAJOR_VERSION:=74
+MINOR_VERSION:=1
PKG_VERSION:=$(MAJOR_VERSION).$(MINOR_VERSION)
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(MAJOR_VERSION)_$(MINOR_VERSION)-src.tgz
PKG_SOURCE_URL:=https://github.com/unicode-org/icu/releases/download/release-$(MAJOR_VERSION)-$(MINOR_VERSION)
-PKG_HASH:=818a80712ed3caacd9b652305e01afc7fa167e6f2e94996da44b90c2ab604ce1
+PKG_HASH:=86ce8e60681972e60e4dcb2490c697463fcec60dd400a5f9bffba26d0b52b8d0
PKG_LICENSE:=ICU
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=libdaq3
-PKG_VERSION:=3.0.12
+PKG_VERSION:=3.0.13
PKG_RELEASE:=1
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
PKG_SOURCE:=libdaq-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/snort3/libdaq/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=dedfdb88de151d61009bdb365322853687b1add4adec248952d2a93b70f584af
+PKG_HASH:=3a48b934bc45a1fe44b3887185d33a76a042c1d10aa177e3e7c417d83da67213
PKG_BUILD_DIR:=$(BUILD_DIR)/libdaq-$(PKG_VERSION)
PKG_FIXUP:=autoreconf
include $(TOPDIR)/rules.mk
PKG_NAME:=libmbim
-PKG_SOURCE_VERSION:=1.28.4
+PKG_SOURCE_VERSION:=1.30.0
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
-PKG_MIRROR_HASH:=7ecc6d1e565392817311254045337907bbad015b46ec88542ea63594f47778be
+PKG_MIRROR_HASH:=8fc4e2d78d6a1003bf89303d3ce779283b176d74e84a241ba8efb0d468605268
PKG_BUILD_FLAGS:=gc-sections
include $(TOPDIR)/rules.mk
PKG_NAME:=libndpi
-PKG_VERSION:=4.6
+PKG_VERSION:=4.8
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/ntop/nDPI/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=6f307e23ab11b2b9e84a696120810e27a854072576a49783ff84fd37a1d7411b
+PKG_HASH:=8f6235ba672d4ac8e4cbebb5611bc712a74587d9d53a649f483e4bcca5b80e58
PKG_BUILD_DIR:=$(BUILD_DIR)/nDPI-$(PKG_VERSION)
PKG_MAINTAINER:=Banglang Huang <banglang.huang@foxmail.com>, Toni Uhlig <matzeton@googlemail.com>
endif
ifneq ($(CONFIG_LIBNDPI_PCRE),)
-CONFIGURE_ARGS += --with-pcre
+CONFIGURE_ARGS += --with-pcre2
endif
ifneq ($(CONFIG_LIBNDPI_MAXMINDDB),)
CATEGORY:=Libraries
TITLE:=Library for deep-packet inspection
URL:=https://github.com/ntop/nDPI
- DEPENDS:=+LIBNDPI_GCRYPT:libgcrypt +LIBNDPI_PCRE:libpcre +LIBNDPI_MAXMINDDB:libmaxminddb +LIBNDPI_NDPIREADER:libpcap
+ DEPENDS:=+LIBNDPI_GCRYPT:libgcrypt +LIBNDPI_PCRE:libpcre2 +LIBNDPI_MAXMINDDB:libmaxminddb +LIBNDPI_NDPIREADER:libpcap
endef
define Package/libndpi/description
--- /dev/null
+From 8fed2be3d5b83949fabb2bdf39d6de4f24d2e68f Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Mon, 30 Oct 2023 18:10:51 +0100
+Subject: [PATCH] Move from PCRE to PCRE2
+
+Move from PCRE to PCRE2. PCRE is EOL and won't receive any security
+updates anymore. Convert to PCRE2 by converting any function PCRE2 new
+API.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ configure.ac | 18 ++++----
+ src/lib/ndpi_utils.c | 46 ++++++++++-----------
+ src/lib/third_party/include/rce_injection.h | 6 +--
+ tests/do.sh.in | 4 +-
+ 4 files changed, 37 insertions(+), 37 deletions(-)
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -359,14 +359,14 @@ AS_IF([test "${with_local_libgcrypt+set}
+ AC_DEFINE_UNQUOTED(USE_HOST_LIBGCRYPT, 1, [Use locally installed libgcrypt instead of builtin gcrypt-light])
+ ])
+
+-dnl> PCRE
+-PCRE_ENABLED=0
+-AC_ARG_WITH(pcre, AS_HELP_STRING([--with-pcre], [Enable nDPI build with libpcre]))
+-if test "${with_pcre+set}" = set; then :
+- AC_CHECK_LIB(pcre, pcre_compile, AC_DEFINE_UNQUOTED(HAVE_PCRE, 1, [libpcre(-dev) is present]))
+- if test "x$ac_cv_lib_pcre_pcre_compile" = xyes; then :
+- ADDITIONAL_LIBS="${ADDITIONAL_LIBS} -lpcre"
+- PCRE_ENABLED=1
++dnl> PCRE2
++PCRE2_ENABLED=0
++AC_ARG_WITH(pcre2, AS_HELP_STRING([--with-pcre2], [Enable nDPI build with libpcre2]))
++if test "${with_pcre2+set}" = set; then :
++ AC_CHECK_LIB(pcre2-8, pcre2_compile_8, AC_DEFINE_UNQUOTED(HAVE_PCRE2, 1, [libpcre2(-dev) is present]))
++ if test "x$ac_cv_lib_pcre2_8_pcre2_compile_8" = xyes; then :
++ ADDITIONAL_LIBS="${ADDITIONAL_LIBS} -lpcre2-8"
++ PCRE2_ENABLED=1
+ fi
+ fi
+
+@@ -420,7 +420,7 @@ AC_SUBST(GPROF_CFLAGS)
+ AC_SUBST(GPROF_LIBS)
+ AC_SUBST(GPROF_ENABLED)
+ AC_SUBST(USE_HOST_LIBGCRYPT)
+-AC_SUBST(PCRE_ENABLED)
++AC_SUBST(PCRE2_ENABLED)
+ AC_SUBST(NBPF_ENABLED)
+ AC_SUBST(HANDLE_TLS_SIGS)
+ AC_SUBST(DISABLE_NPCAP)
+--- a/src/lib/ndpi_utils.c
++++ b/src/lib/ndpi_utils.c
+@@ -62,12 +62,12 @@
+
+ // #define DEBUG_REASSEMBLY
+
+-#ifdef HAVE_PCRE
+-#include <pcre.h>
++#ifdef HAVE_PCRE2
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+
+-struct pcre_struct {
+- pcre *compiled;
+- pcre_extra *optimized;
++struct pcre2_struct {
++ pcre2_code *compiled;
+ };
+ #endif
+
+@@ -1712,18 +1712,19 @@ static int ndpi_is_xss_injection(char* q
+
+ /* ********************************** */
+
+-#ifdef HAVE_PCRE
++#ifdef HAVE_PCRE2
+
+ static void ndpi_compile_rce_regex() {
+- const char *pcreErrorStr = NULL;
+- int pcreErrorOffset;
++ PCRE2_UCHAR pcreErrorStr[128];
++ PCRE2_SIZE pcreErrorOffset;
++ int pcreErrorCode;
+
+ for(int i = 0; i < N_RCE_REGEX; i++) {
+- comp_rx[i] = (struct pcre_struct*)ndpi_malloc(sizeof(struct pcre_struct));
++ comp_rx[i] = (struct pcre2_struct*)ndpi_malloc(sizeof(struct pcre2_struct));
+
+- comp_rx[i]->compiled = pcre_compile(rce_regex[i], 0, &pcreErrorStr,
++ comp_rx[i]->compiled = pcre2_compile((PCRE2_SPTR)rce_regex[i], PCRE2_ZERO_TERMINATED, 0, &pcreErrorCode,
+ &pcreErrorOffset, NULL);
+-
++ pcre2_get_error_message(pcreErrorCode, pcreErrorStr, 128);
+ if(comp_rx[i]->compiled == NULL) {
+ #ifdef DEBUG
+ NDPI_LOG_ERR(ndpi_str, "ERROR: Could not compile '%s': %s\n", rce_regex[i],
+@@ -1733,17 +1734,16 @@ static void ndpi_compile_rce_regex() {
+ continue;
+ }
+
+- comp_rx[i]->optimized = pcre_study(comp_rx[i]->compiled, 0, &pcreErrorStr);
++ pcreErrorCode = pcre2_jit_compile(comp_rx[i]->compiled, PCRE2_JIT_COMPLETE);
+
+ #ifdef DEBUG
+- if(pcreErrorStr != NULL) {
+- NDPI_LOG_ERR(ndpi_str, "ERROR: Could not study '%s': %s\n", rce_regex[i],
++ if(pcreErrorCode < 0) {
++ pcre2_get_error_message(pcreErrorCode, pcreErrorStr, 128);
++ NDPI_LOG_ERR(ndpi_str, "ERROR: Could not jit compile '%s': %s\n", rce_regex[i],
+ pcreErrorStr);
+ }
+ #endif
+ }
+-
+- ndpi_free((void *)pcreErrorStr);
+ }
+
+ static int ndpi_is_rce_injection(char* query) {
+@@ -1752,17 +1752,17 @@ static int ndpi_is_rce_injection(char* q
+ initialized_comp_rx = 1;
+ }
+
++ pcre2_match_data *pcreMatchData;
+ int pcreExecRet;
+- int subStrVec[30];
+
+ for(int i = 0; i < N_RCE_REGEX; i++) {
+ unsigned int length = strlen(query);
+
+- pcreExecRet = pcre_exec(comp_rx[i]->compiled,
+- comp_rx[i]->optimized,
+- query, length, 0, 0, subStrVec, 30);
+-
+- if(pcreExecRet >= 0) {
++ pcreMatchData = pcre2_match_data_create_from_pattern(comp_rx[i]->compiled, NULL);
++ pcreExecRet = pcre2_match(comp_rx[i]->compiled,
++ (PCRE2_SPTR)query, length, 0, 0, pcreMatchData, NULL);
++ pcre2_match_data_free(pcreMatchData);
++ if(pcreExecRet > 0) {
+ return 1;
+ }
+ #ifdef DEBUG
+@@ -1852,7 +1852,7 @@ ndpi_risk_enum ndpi_validate_url(char *u
+ rc = NDPI_URL_POSSIBLE_XSS;
+ else if(ndpi_is_sql_injection(decoded))
+ rc = NDPI_URL_POSSIBLE_SQL_INJECTION;
+-#ifdef HAVE_PCRE
++#ifdef HAVE_PCRE2
+ else if(ndpi_is_rce_injection(decoded))
+ rc = NDPI_URL_POSSIBLE_RCE_INJECTION;
+ #endif
+--- a/src/lib/third_party/include/rce_injection.h
++++ b/src/lib/third_party/include/rce_injection.h
+@@ -1,4 +1,4 @@
+-#ifdef HAVE_PCRE
++#ifdef HAVE_PCRE2
+
+ #ifndef NDPI_RCE_H
+ #define NDPI_RCE_H
+@@ -8,7 +8,7 @@
+ #define N_RCE_REGEX 7
+
+ /* Compiled regex */
+-static struct pcre_struct *comp_rx[N_RCE_REGEX];
++static struct pcre2_struct *comp_rx[N_RCE_REGEX];
+
+ static unsigned int initialized_comp_rx = 0;
+
+@@ -615,4 +615,4 @@ static const char *pwsh_commands[] = {
+ "-PSConsoleFile"
+ };
+
+-#endif //HAVE_PCRE
+\ No newline at end of file
++#endif //HAVE_PCRE2
+\ No newline at end of file
+--- a/tests/do.sh.in
++++ b/tests/do.sh.in
+@@ -26,7 +26,7 @@ CMD_COLORDIFF="$(which colordiff)"
+
+ EXE_SUFFIX=@EXE_SUFFIX@
+ GPROF_ENABLED=@GPROF_ENABLED@
+-PCRE_ENABLED=@PCRE_ENABLED@
++PCRE2_ENABLED=@PCRE2_ENABLED@
+ PCRE_PCAPS="WebattackRCE.pcap"
+ NBPF_ENABLED=@NBPF_ENABLED@
+ NBPF_PCAPS="h323-overflow.pcap"
+@@ -84,7 +84,7 @@ check_results() {
+ [ $SKIP_PCAP = 1 ] && continue
+ fi
+ SKIP_PCAP=0
+- if [ $PCRE_ENABLED -eq 0 ]; then
++ if [ $PCRE2_ENABLED -eq 0 ]; then
+ for p in $PCRE_PCAPS; do
+ if [ $f = $p ]; then
+ SKIP_PCAP=1
include $(TOPDIR)/rules.mk
PKG_NAME:=libnpupnp
-PKG_VERSION:=5.0.0
-PKG_RELEASE:=2
+PKG_VERSION:=5.1.2
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.lesbonscomptes.com/upmpdcli/downloads
-PKG_HASH:=2e5648cf180a425ef57b8c9c0d9dbd77f0314487ea0e0a85ebc6c3ef87cab05b
+PKG_HASH:=c1be8b2f654ef520791fbfaf13006fdd84522e6480a3126006e40caceea23552
PKG_MAINTAINER:=
PKG_LICENSE:=LGPL-2.1-or-later
PKG_LICENSE_FILES:=COPYING
-PKG_INSTALL:=1
-PKG_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=libmicrohttpd
-PKG_BUILD_FLAGS:=lto
include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
define Package/libnpupnp
SECTION:=libs
branch (around 1.6.25).
endef
+MESON_OPTIONS += \
+ -Db_lto=true
+
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/npupnp
$(CP) $(PKG_INSTALL_DIR)/usr/include/npupnp/* $(1)/usr/include/npupnp/
include $(TOPDIR)/rules.mk
PKG_NAME:=libqmi
-PKG_SOURCE_VERSION:=1.32.4
+PKG_SOURCE_VERSION:=1.34.0
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libqmi.git
-PKG_MIRROR_HASH:=674f5848c56c11cdc2fbc82c52e5bc2a3a0fddb56315dc4220544688a7b0e17a
+PKG_MIRROR_HASH:=af3dc760d0c40ef8af1f8b424435daa12bff698ed45b1cc9a9e38ea62ed047f0
PKG_BUILD_FLAGS:=gc-sections
--- /dev/null
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libsocketcan
+PKG_VERSION:=0.0.12
+PKG_RELEASE=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://www.pengutronix.de/software/libsocketcan/download/
+PKG_HASH:=be8280124707701935e6294d366e2474158b758fa4b2e3cae571d5b256d2fe34
+
+PKG_MAINTAINER:=Yegor Yefremov <yegorslists@googlemail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_INSTALL:=1
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libsocketcan
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=Library to control SocketCAN interfaces
+ URL:=https://git.pengutronix.de/cgit/tools/libsocketcan
+endef
+
+define Package/libsocketcan/description
+ This userspace library allows one to do common configure/control tasks
+on a SocketCAN interface.
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/can_netlink.h $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/libsocketcan.h $(1)/usr/include
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsocketcan.{a,so*} $(1)/usr/lib
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libsocketcan.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libsocketcan/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsocketcan.so* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libsocketcan))
include $(TOPDIR)/rules.mk
PKG_NAME:=libupnpp
-PKG_VERSION:=0.22.2
+PKG_VERSION:=0.24.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.lesbonscomptes.com/upmpdcli/downloads
-PKG_HASH:=90338c19383333fd4eeec8a866a8c4add1754ef9a6a720ddd9af97e6754ff849
+PKG_HASH:=f09d5162f237bcb971ef4bbd45de9e93a073d96555cd691374eb1a3f338b2d0b
PKG_MAINTAINER:=
PKG_LICENSE:=LGPL-2.1-or-later
include $(TOPDIR)/rules.mk
PKG_NAME:=liburing
-PKG_VERSION:=2.4
+PKG_VERSION:=2.5
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://git.kernel.dk/cgit/liburing/snapshot
-PKG_HASH:=ca260e7a5820c2d0e737ec1e9b999f10776dbe84a169a02a0eff10c8eeaf3394
+PKG_HASH:=319ff9096a5655362a9741c5145b45494db810e38679a1de82e2f440c17181a6
PKG_MAINTAINER:=Christian Lachner <gladiac@gmail.com>
PKG_LICENSE:=MIT
include $(TOPDIR)/rules.mk
PKG_NAME:=libxslt
-PKG_VERSION:=1.1.37
+PKG_VERSION:=1.1.39
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNOME/libxslt/$(basename $(PKG_VERSION))
-PKG_HASH:=3a4b27dc8027ccd6146725950336f1ec520928f320f144eb5fa7990ae6123ab4
+PKG_HASH:=2a20ad621148339b0759c4d4e96719362dee64c9a096dbba625ba053846349f0
PKG_MAINTAINER:=Jiri Slachta <jiri@slachta.eu>
PKG_LICENSE:=MIT
include $(TOPDIR)/rules.mk
PKG_NAME:=libzip
-PKG_VERSION:=1.9.2
+PKG_VERSION:=1.10.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://libzip.org/download/
-PKG_HASH:=c93e9852b7b2dc931197831438fee5295976ee0ba24f8524a8907be5c2ba5937
+PKG_HASH:=dc3c8d5b4c8bbd09626864f6bcf93de701540f761d76b85d7c7d710f4bd90318
PKG_MAINTAINER:=Michael Heimpold <mhei@heimpold.de>
+++ /dev/null
---- a/lib/zipint.h
-+++ b/lib/zipint.h
-@@ -180,8 +180,10 @@ zip_source_t *zip_source_pkware_decode(z
- zip_source_t *zip_source_pkware_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
- int zip_source_remove(zip_source_t *);
- zip_int64_t zip_source_supports(zip_source_t *src);
-+#ifdef HAVE_CRYPTO
- zip_source_t *zip_source_winzip_aes_decode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
- zip_source_t *zip_source_winzip_aes_encode(zip_t *, zip_source_t *, zip_uint16_t, int, const char *);
-+#endif
- zip_source_t *zip_source_buffer_with_attributes(zip_t *za, const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes);
- zip_source_t *zip_source_buffer_with_attributes_create(const void *data, zip_uint64_t len, int freep, zip_file_attributes_t *attributes, zip_error_t *error);
-
include $(TOPDIR)/rules.mk
PKG_NAME:=newt
-PKG_VERSION:=0.52.23
+PKG_VERSION:=0.52.24
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://releases.pagure.org/newt
-PKG_HASH:=caa372907b14ececfe298f0d512a62f41d33b290610244a58aed07bbc5ada12a
+PKG_HASH:=5ded7e221f85f642521c49b1826c8de19845aa372baf5d630a51774b544fbdbb
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=LGPL-2.0-only
--- /dev/null
+#!/bin/sh
+
+case "$1" in
+
+python3-newt)
+ python3 -c 'import snack'
+ ;;
+
+whiptail)
+ whiptail --version | grep -Fx "whiptail (newt): $PKG_VERSION"
+ ;;
+
+esac
include $(TOPDIR)/rules.mk
PKG_NAME:=nghttp2
-PKG_VERSION:=1.51.0
+PKG_VERSION:=1.57.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/nghttp2/nghttp2/releases/download/v$(PKG_VERSION)
-PKG_HASH:=66aa76d97c143f42295405a31413e5e7d157968dad9f957bb4b015b598882e6b
+PKG_HASH:=9210b0113109f43be526ac5835d58a701411821a4d39e155c40d67c40f47a958
PKG_MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
PKG_LICENSE:=MIT
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nghttp3
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ngtcp2/nghttp3/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=b3ffb23a90442a0eafe8bfbefbc8b4ffb5179d68a7c0b8a416a34cf04b28d7c5
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libnghttp3
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=HTTP/3 library written in C
+ URL:=https://nghttp2.org/nghttp3
+endef
+
+define Package/libnghttp3/description
+nghttp3 is a thin HTTP/3 layer over an underlying QUIC stack.
+endef
+
+CMAKE_OPTIONS += -DENABLE_LIB_ONLY=ON
+
+define Package/libnghttp3/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libnghttp3.so* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libnghttp3))
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ngtcp2
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ngtcp2/ngtcp2/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=987d784643edea4f2859c405f7dfbc53871a9f7ae5fcddf5fb12ec5dfce1ef22
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libngtcp2
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=Implementation of QUIC protocol
+ URL:=https://nghttp2.org/ngtcp2
+ DEPENDS:=+libnghttp3 +libopenssl
+endef
+
+define Package/libngtcp2/description
+ngtcp2 project is an effort to implement QUIC protocol which is now being
+discussed in IETF QUICWG for its standardization.
+endef
+
+CMAKE_OPTIONS += -DENABLE_LIB_ONLY=ON
+
+define Package/libngtcp2/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libngtcp2*.so* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libngtcp2))
include $(TOPDIR)/rules.mk
PKG_NAME:=OpenBLAS
-PKG_VERSION:=0.3.23
+PKG_VERSION:=0.3.24
PKG_RELEASE:=1
PKG_SOURCE:=OpenBLAS-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/xianyi/OpenBLAS/releases/download/v$(PKG_VERSION)/
-PKG_HASH:=5d9491d07168a5d00116cdc068a40022c3455bf9293c7cb86a65b1054d7e5114
+PKG_HASH:=ceadc5065da97bd92404cac7254da66cc6eb192679cf1002098688978d4d5132
PKG_LICENSE:=BSD 3-Clause
PKG_MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>
include $(INCLUDE_DIR)/package.mk
CONFIGURE_ARGS += \
- --with-unixodbc=$(STAGING_DIR_HOST)/bin/odbc_config \
+ --with-unixodbc=$(STAGING_DIR)/host/bin/odbc_config \
--with-libpq=$(STAGING_DIR)/usr
define Package/psqlodbc/Default
+++ /dev/null
-#
-# Copyright (C) 2016 Ben Rosser <rosser.bjr@gmail.com>
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=quasselc
-PKG_SOURCE_DATE:=2017-01-11
-PKG_SOURCE_VERSION:=a0a1e6bd87d3eac68b5369972d1c2035cfe47e94
-PKG_RELEASE:=4
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/phhusson/QuasselC/tar.gz/$(PKG_SOURCE_VERSION)?
-PKG_HASH:=fe7b48a13c0e6dad81cdae18069d4f5607af64d73a3201f42d79548170dde510
-PKG_BUILD_DIR:=$(BUILD_DIR)/QuasselC-$(PKG_SOURCE_VERSION)
-
-PKG_MAINTAINER:=Ben Rosser <rosser.bjr@gmail.com>
-PKG_LICENSE:=LGPL-3.0
-PKG_LICENSE_FILES:=COPYING.LESSER
-
-PKG_BUILD_PARALLEL:=1
-PKG_INSTALL:=1
-
-include $(INCLUDE_DIR)/package.mk
-include $(INCLUDE_DIR)/nls.mk
-
-MAKE_FLAGS += prefix=$(STAGING_DIR)/usr libdir=$(STAGING_DIR)/usr/lib includedir=$(STAGING_DIR)/usr/include
-MAKE_INSTALL_FLAGS += prefix=/usr libdir=/usr/lib includedir=/usr/include
-
-define Package/quasselc
- SECTION:=libs
- CATEGORY:=Libraries
- DEPENDS:=+glib2
- SUBMENU:=Instant Messaging
- URL:=https://github.com/phhusson/QuasselC
- TITLE:=API to access a Quassel Core in pure C
-endef
-
-define Package/quasselc/description
- An implementation of the Quassel protocol in pure C.
-endef
-
-define Build/InstallDev
- $(INSTALL_DIR) $(1)/usr/include/quasselc
- $(CP) $(PKG_INSTALL_DIR)/usr/include/quasselc/* $(1)/usr/include/quasselc/
-
- $(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libquasselc.so* $(1)/usr/lib/
- $(LN) libquasselc.so.0 $(1)/usr/lib/libquasselc.so
-
- $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/quasselc.pc $(1)/usr/lib/pkgconfig/
-endef
-
-define Package/quasselc/install
- $(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libquasselc.so* $(1)/usr/lib/
-endef
-
-$(eval $(call BuildPackage,quasselc))
+++ /dev/null
---- a/Makefile
-+++ b/Makefile
-@@ -2,11 +2,11 @@ prefix ?= /usr/local
- libdir ?= $(prefix)/lib
- includedir ?= $(prefix)/include
-
--CFLAGS:=-Wall -g -Wextra $(shell pkg-config glib-2.0 --cflags) -Wswitch-enum -std=gnu11 -O2 -fPIC
-+CFLAGS+=-Wall -g -Wextra $(shell pkg-config glib-2.0 --cflags) -Wswitch-enum -std=gnu11 -fPIC
- SO_VERSION = 0
- VERSION = 0
- INSTALL = install
--LDLIBS:=$(shell pkg-config glib-2.0 --libs) -lz
-+LDFLAGS+=$(shell pkg-config glib-2.0 --libs) -lz
-
- BOTLIBS := -Wl,-rpath,.
-
-@@ -15,10 +15,10 @@ lib_objects=setters.o getters.o main.o c
- all: bot libquasselc.so.$(VERSION) quasselc.pc
-
- libquasselc.so.$(VERSION): $(lib_objects)
-- $(CC) -shared -o $@ -Wl,-soname,libquasselc.so.$(SO_VERSION) $^ $(LDLIBS)
-+ $(CC) -shared -o $@ -Wl,-soname,libquasselc.so.$(SO_VERSION) $^ $(LDFLAGS)
-
- bot: bot.o display.o libquasselc.so.$(VERSION)
-- $(CC) -o $@ $^ $(LDLIBS) $(BOTLIBS)
-+ $(CC) -o $@ $^ $(LDFLAGS) $(BOTLIBS)
-
- clean:
- rm -f *.o bot libquasselc.so.$(VERSION) quasselc.pc
include $(TOPDIR)/rules.mk
PKG_NAME:=unixodbc
-PKG_VERSION:=2.3.9
-PKG_RELEASE:=2
+PKG_VERSION:=2.3.12
+PKG_RELEASE:=1
PKG_SOURCE:=unixODBC-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.unixodbc.org
-PKG_HASH:=52833eac3d681c8b0c9a5a65f2ebd745b3a964f208fc748f977e44015a31b207
+PKG_HASH:=f210501445ce21bf607ba51ef8c125e10e22dffdffec377646462df5f01915ec
PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
-PKG_LICENSE:=prog GPL libs LGPL
+PKG_LICENSE:=LGPL-2.1-or-later GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING exe/COPYING
PKG_CPE_ID:=cpe:/a:unixodbc:unixodbc
PKG_BUILD_DIR:=$(BUILD_DIR)/unixODBC-$(PKG_VERSION)
-HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/unixODBC-$(PKG_VERSION)
-HOST_BUILD_DEPENDS:=unixodbc
+HOST_BUILD_DIR:=$(BUILD_DIR)/host/unixODBC-$(PKG_VERSION)
+PKG_BUILD_PARALLEL:=1
PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+HOST_BUILD_DEPENDS:=unixodbc
+HOST_BUILD_PARALLEL:=1
# if your other package depends on unixodbc and needs
# odbc_config, add to your other Makefile
CONFIGURE_ARGS += \
--disable-gui \
--with-pic \
- --enable-drivers \
- --includedir=$(STAGING_DIR)/usr/include
+ --enable-drivers
define Package/unixodbc/Default
SUBMENU:=Database
TITLE:=unixODBC
- URL:=http://www.unixodbc.org
+ URL:=https://www.unixodbc.org
+endef
+
+define Package/unixodbc/Default/description
+unixODBC is an Open Source ODBC sub-system and an ODBC SDK for Linux,
+Mac OSX, and UNIX.
+endef
+
+define Package/libodbc
+$(call Package/unixodbc/Default)
+ TITLE+= Driver Manager library
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=+libltdl +libpthread
+ ABI_VERSION:=2
+endef
+
+define Package/libodbc/description
+$(call Package/unixodbc/Default/description)
+
+This package provides the unixODBC Driver Manager library.
+endef
+
+define Package/libodbccr
+$(call Package/unixodbc/Default)
+ TITLE+= Cursor library
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=+libodbc +libltdl +libpthread
+ ABI_VERSION:=2
+endef
+
+define Package/libodbccr/description
+$(call Package/unixodbc/Default/description)
+
+This package provides the unixODBC Cursor library.
+endef
+
+define Package/libodbcinst
+$(call Package/unixodbc/Default)
+ TITLE+= Configuration library
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=+libltdl +libpthread
+ ABI_VERSION:=2
+endef
+
+define Package/libodbcinst/description
+$(call Package/unixodbc/Default/description)
+
+This package provides the unixODBC Configuration library.
endef
define Package/unixodbc
- $(call Package/unixodbc/Default)
+$(call Package/unixodbc/Default)
TITLE+= (libraries)
SECTION:=libs
CATEGORY:=Libraries
- DEPENDS:=+libltdl +libpthread
+ DEPENDS:=+libodbc +libodbccr +libodbcinst
endef
define Package/unixodbc/description
- unixODBC is an Open Source ODBC sub-system and an ODBC SDK for Linux,
- Mac OSX, and UNIX.
+$(call Package/unixodbc/Default/description)
+
+This package installs the unixODBC Driver Manager, Cursor, and
+Configuration libraries. This package is provided for backwards
+compatibility; these libraries are available in separate packages.
endef
define Package/unixodbc-tools
- $(call Package/unixodbc/Default)
+$(call Package/unixodbc/Default)
SECTION:=utils
CATEGORY:=Utilities
TITLE+= Tools
- DEPENDS:=+unixodbc +libncurses +libreadline
+ DEPENDS:=+libodbc +libodbcinst +libltdl +libreadline
endef
define Package/unixodbc-tools/description
- Command Line Tools to help install a driver and work with SQL.
+$(call Package/unixodbc/Default/description)
+
+This package provides command-line tools to help install a driver and
+work with SQL.
endef
define Package/pgsqlodbc
- $(call Package/unixodbc/Default)
+$(call Package/unixodbc/Default)
SECTION:=libs
CATEGORY:=Libraries
- TITLE:=Postgresql driver for ODBC
- DEPENDS:=+unixodbc +libpq
+ TITLE:=PostgreSQL driver for ODBC
+ DEPENDS:=+libodbc +libpq +libltdl +libpthread
+ ABI_VERSION:=2
endef
define Package/pgsqlodbc/description
- Postgresql driver for ODBC.
-endef
+$(call Package/unixodbc/Default/description)
-define Build/Compile
- $(MAKE) -C $(PKG_BUILD_DIR) \
- DESTDIR="$(PKG_INSTALL_DIR)" \
- $(MAKE_FLAGS) \
- ARCH="$(ARCH)" \
- CC="$(TARGET_CC)"
- $(MAKE) -C $(PKG_BUILD_DIR) \
- DESTDIR="$(PKG_INSTALL_DIR)" \
- $(MAKE_FLAGS) \
- ARCH="$(ARCH)" \
- install -i
+This package provides the PostgreSQL driver for ODBC.
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
- $(CP) $(PKG_INSTALL_DIR)/$(STAGING_DIR)/usr/include/*.h $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
# Save autoconf config.h file for host build
# copy target autoconf config.h and unixodbc_conf.h file for host build
- $(INSTALL_DIR) $(1)/tmp/unixodbc
- $(CP) $(PKG_BUILD_DIR)/config.h $(1)/tmp/unixodbc/
- $(CP) $(PKG_BUILD_DIR)/unixodbc_conf.h $(1)/tmp/unixodbc/
+ $(INSTALL_DIR) $(1)/usr/include/unixodbc
+ $(CP) $(PKG_BUILD_DIR)/config.h $(1)/usr/include/unixodbc/
+ $(CP) $(PKG_BUILD_DIR)/unixodbc_conf.h $(1)/usr/include/unixodbc/
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
$(INSTALL_DIR) $(1)/etc
$(CP) $(PKG_INSTALL_DIR)/etc/odbc* $(1)/etc/
$(INSTALL_DIR) $(1)/etc/ODBCDataSources
- $(TARGET_CC) $(TARGET_CFLAGS) -E ./files/unixodbc_conf.h | tr '@' '\#' >$(1)/usr/include/unixodbc_conf.h
endef
-define Package/unixodbc/install
+define Package/libodbc/install
$(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libodbc[ci]*so* $(1)/usr/lib/
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libodbc.*so* $(1)/usr/lib/
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnn*so* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libodbc.so* $(1)/usr/lib/
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/odbc.init $(1)/etc/init.d/odbc
$(LN) /tmp/etc/odbcinst.ini $(1)/etc/odbcinst.ini
endef
+define Package/libodbccr/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libodbccr.so* $(1)/usr/lib/
+endef
+
+define Package/libodbcinst/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libodbcinst.so* $(1)/usr/lib/
+endef
+
+Package/unixodbc/install:=:
+
define Package/unixodbc-tools/install
$(INSTALL_DIR) $(1)/usr/bin
$(CP) $(PKG_INSTALL_DIR)/usr/bin/{dltest,isql,iusql,odbcinst,slencheck} $(1)/usr/bin/
define Package/pgsqlodbc/install
$(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libodbcpsql*so* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libodbcpsql.so* $(1)/usr/lib/
$(INSTALL_DIR) $(1)/etc/odbcinst.ini.d/
- echo "[PostgreSQL]" > $(1)/etc/odbcinst.ini.d/pgsqlodbc.ini
- echo "Description = unixODBC PostgreSQL driver" >> $(1)/etc/odbcinst.ini.d/pgsqlodbc.ini
- echo "Driver = /usr/lib/libodbcpsql.so" >> $(1)/etc/odbcinst.ini.d/pgsqlodbc.ini
+ $(INSTALL_DATA) ./files/pgsqlodbc.ini $(1)/etc/odbcinst.ini.d/
endef
define Host/Configure
$(call Host/Configure/Default)
- cp $(STAGING_DIR)/tmp/unixodbc/config.h $(HOST_BUILD_DIR)
- sed -i -e 's!\(LIB_PREFIX \).*$$$$!\1"$(STAGING_DIR)/usr/lib"!' $(HOST_BUILD_DIR)/config.h
- cp $(STAGING_DIR)/tmp/unixodbc/unixodbc_conf.h $(HOST_BUILD_DIR)
+ $(CP) $(STAGING_DIR)/usr/include/unixodbc/config.h $(HOST_BUILD_DIR)
+ $(CP) $(STAGING_DIR)/usr/include/unixodbc/unixodbc_conf.h $(HOST_BUILD_DIR)
+ $(CP) $(STAGING_DIR)/usr/include/unixodbc.h $(HOST_BUILD_DIR)
+ $(SED) 's!^#define INCLUDE_PREFIX ".*"!#define INCLUDE_PREFIX "$(STAGING_DIR)/usr/include"!' \
+ -e 's!^#define LIB_PREFIX ".*"!#define LIB_PREFIX "$(STAGING_DIR)/usr/lib"!' \
+ $(HOST_BUILD_DIR)/config.h \
+ $(HOST_BUILD_DIR)/unixodbc_conf.h
endef
define Host/Compile
- $(MAKE) -C $(HOST_BUILD_DIR)/exe \
- DESTDIR="$(HOST_INSTALL_DIR)" \
- CC="$(HOSTCC)" \
- CFLAGS="$(HOST_CFLAGS) -DUSE_UNIXODBC_CONF_H" \
- LDFLAGS="$(HOST_LDFLAGS)" \
- odbc_config
+ $(call Host/Compile/Default,-C $(HOST_BUILD_DIR)/exe odbc_config)
endef
define Host/Install
- $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
- $(INSTALL_BIN) $(HOST_BUILD_DIR)/exe/odbc_config $(STAGING_DIR_HOST)/bin
+ $(INSTALL_DIR) $(STAGING_DIR)/host/bin
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/exe/odbc_config $(STAGING_DIR)/host/bin/
endef
+$(eval $(call BuildPackage,libodbc))
+$(eval $(call BuildPackage,libodbccr))
+$(eval $(call BuildPackage,libodbcinst))
$(eval $(call BuildPackage,unixodbc))
$(eval $(call BuildPackage,unixodbc-tools))
$(eval $(call BuildPackage,pgsqlodbc))
--- /dev/null
+[PostgreSQL]
+Description = unixODBC PostgreSQL driver
+Driver = /usr/lib/libodbcpsql.so
+++ /dev/null
-@ifndef HAVE_UNISTD_H
- @define HAVE_UNISTD_H
-@endif
-@ifndef HAVE_PWD_H
- @define HAVE_PWD_H
-@endif
-@ifndef HAVE_SYS_TYPES_H
- @define HAVE_SYS_TYPES_H
-@endif
-@ifndef HAVE_LONG_LONG
- @define HAVE_LONG_LONG
-@endif
-@ifndef ODBCINT64
- @define ODBCINT64 long
-@endif
-@ifndef UODBCINT64
- @define UODBCINT64 unsigned long
-@endif
-@ifndef SIZEOF_LONG_INT
- @define SIZEOF_LONG_INT __SIZEOF_LONG__
-@endif
-
\ No newline at end of file
+++ /dev/null
---- a/exe/odbc-config.c
-+++ b/exe/odbc-config.c
-@@ -40,6 +40,33 @@
- #include <unistd.h>
- #endif
-
-+#ifdef USE_UNIXODBC_CONF_H
-+
-+#ifdef HAVE_UNISTD_H
-+#undef HAVE_UNISTD_H
-+#endif
-+#ifdef HAVE_PWD_H
-+#undef HAVE_PWD_H
-+#endif
-+#ifdef HAVE_SYS_TYPES_H
-+#undef HAVE_SYS_TYPES_H
-+#endif
-+#ifdef HAVE_LONG_LONG
-+#undef HAVE_LONG_LONG
-+#endif
-+#ifdef ODBCINT64
-+#undef ODBCINT64
-+#endif
-+#ifdef UODBCINT64
-+#undef UODBCINT64
-+#endif
-+#ifdef SIZEOF_LONG_INT
-+#undef SIZEOF_LONG_INT
-+#endif
-+
-+#include <unixodbc_conf.h>
-+#endif
-+
- #include <sql.h>
-
- static void usage( void )
--- /dev/null
+#!/bin/sh
+
+[ "$1" = unixodbc-tools ] || exit 0
+
+isql --version | grep -Fx "unixODBC $PKG_VERSION"
include $(TOPDIR)/rules.mk
PKG_NAME:=xmlrpc-c
-PKG_VERSION:=1.51.07
+PKG_VERSION:=1.54.06
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tgz
PKG_SOURCE_URL:=@SF/xmlrpc-c/Xmlrpc-c%20Super%20Stable/$(PKG_VERSION)
-PKG_HASH:=84d20ae33f927582f821d61c0b9194aefbf1d7924590a13fa9da5ae1698aded9
+PKG_HASH:=ae6d0fb58f38f1536511360dc0081d3876c1f209d9eaa54357e2bacd690a5640
PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
PKG_LICENSE:=VARIOUS
$(call Package/xmlrpc-c/Default)
TITLE+= (uses internal expat variant)
DEPENDS:=+xmlrpc-c-common
-# PROVIDES:=xmlrpc-c
+ PROVIDES:=xmlrpc-c
VARIANT:=internal
- HIDDEN:=1
-endef
-
-define Package/xmlrpc-c
- $(call Package/xmlrpc-c/Default)
- TITLE+= (uses internal expat variant)
- DEPENDS:=+xmlrpc-c-internal
endef
define Package/xmlrpc-c-libxml2
$(call Package/xmlrpc-c/Default)
TITLE+= (uses libxml2)
- DEPENDS:=+xmlrpc-c-common +libxml2 @BROKEN
-# PROVIDES:=xmlrpc-c
+ DEPENDS:=+xmlrpc-c-common +libxml2
+ PROVIDES:=xmlrpc-c
VARIANT:=libxml2
endef
define Package/xmlrpc-c-abyss
$(call Package/xmlrpc-c/Default)
TITLE+= - abyss
- DEPENDS:=+xmlrpc-c-common @BROKEN
+ DEPENDS:=+xmlrpc-c-common
endef
define Package/xmlrpc-c-server-abyss
CONFIGURE_ARGS+= \
--disable-wininet-client \
--disable-libwww-client \
- --disable-abyss-server \
--disable-cgi-server \
--disable-cplusplus \
- --disable-abyss-threads \
- --without-libwww-ssl
+ --without-libwww-ssl \
+ --disable-abyss-openssl
ifeq ($(BUILD_VARIANT),libxml2)
CONFIGURE_ARGS += \
endif
define Build/Compile
- ( cd $(PKG_BUILD_DIR)/lib/expat/gennmtab && cc -I$(PKG_BUILD_DIR) -c gennmtab.c -o gennmtab.o && cc -o gennmtab gennmtab.o )
+ ( cd $(PKG_BUILD_DIR)/lib/expat/gennmtab && cc -I$(PKG_BUILD_DIR) -c gennmtab.c -o gennmtab.o && cc -o gennmtab gennmtab.o )
$(call Build/Compile/Default)
endef
$(1)/usr/lib/
endef
-define Package/xmlrpc-c/install
- true
-endef
-
-$(eval $(call BuildPackage,xmlrpc-c))
$(eval $(call BuildPackage,xmlrpc-c-common))
-#$(eval $(call BuildPackage,xmlrpc-c-libxml2))
+$(eval $(call BuildPackage,xmlrpc-c-libxml2))
$(eval $(call BuildPackage,xmlrpc-c-internal))
$(eval $(call BuildPackage,xmlrpc-c-server))
-#$(eval $(call BuildPackage,xmlrpc-c-abyss))
-#$(eval $(call BuildPackage,xmlrpc-c-server-abyss))
+$(eval $(call BuildPackage,xmlrpc-c-abyss))
+$(eval $(call BuildPackage,xmlrpc-c-server-abyss))
$(eval $(call BuildPackage,xmlrpc-c-client))
--- /dev/null
+--- a/src/xmlrpc_server_abyss.c
++++ b/src/xmlrpc_server_abyss.c
+@@ -780,7 +780,7 @@ createServer(xmlrpc_env *
+ ServerInit2(abyssServerP, &error);
+
+ if (error) {
+- xmlrpc_faultf(envP, error);
++ xmlrpc_faultf(envP, "%s", error);
+ xmlrpc_strfree(error);
+ }
+ }
--- /dev/null
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -183,7 +183,7 @@ $(LIBXMLRPC_SERVER): \
+ $(call shliblefn, libxmlrpc)
+ $(LIBXMLRPC_SERVER): LIBOBJECTS = $(LIBXMLRPC_SERVER_MODS:%=%.osh)
+ $(LIBXMLRPC_SERVER): LIBDEP = \
+- -L. -lxmlrpc $(XML_PARSER_LIBDEP) $(LIBXMLRPC_UTIL_LIBDEP)
++ -L. -lxmlrpc $(LIBXMLRPC_UTIL_LIBDEP)
+
+ LIBXMLRPC_SERVER_ABYSS = $(call shlibfn, libxmlrpc_server_abyss)
+
+@@ -197,7 +197,7 @@ $(LIBXMLRPC_SERVER_ABYSS): LIBOBJECTS =
+ $(LIBXMLRPC_SERVER_ABYSS): LIBDEP = \
+ -L. -lxmlrpc_server \
+ -L$(LIBXMLRPC_ABYSS_DIR) -lxmlrpc_abyss \
+- -L. -lxmlrpc $(XML_PARSER_LIBDEP) $(LIBXMLRPC_UTIL_LIBDEP)
++ -L. -lxmlrpc $(LIBXMLRPC_UTIL_LIBDEP)
+ ifeq ($(MSVCRT),yes)
+ $(LIBXMLRPC_SERVER_ABYSS): LIBDEP += -lws2_32 -lwsock32
+ endif
+@@ -212,7 +212,7 @@ $(LIBXMLRPC_SERVER_CGI): \
+ $(LIBXMLRPC_SERVER_CGI): LIBOBJECTS = $(LIBXMLRPC_SERVER_CGI_MODS:%=%.osh)
+ $(LIBXMLRPC_SERVER_CGI): LIBDEP = \
+ -L. -lxmlrpc_server \
+- -L. -lxmlrpc $(XML_PARSER_LIBDEP) $(LIBXMLRPC_UTIL_LIBDEP)
++ -L. -lxmlrpc $(LIBXMLRPC_UTIL_LIBDEP)
+
+ LIBXMLRPC_CLIENT = $(call shlibfn, libxmlrpc_client)
+
+@@ -237,7 +237,6 @@ $(LIBXMLRPC_CLIENT): LIBOBJECTS = \
+ LIBXMLRPC_CLIENT_LIBDEP = \
+ -Lblddir/src -Lblddir/lib/libutil \
+ -lxmlrpc -lxmlrpc_util \
+- $(XML_PARSER_LIBDEP) \
+ $(TRANSPORT_LIBDEP) \
+
+ $(LIBXMLRPC_CLIENT): LIBDEP = \
include $(TOPDIR)/rules.mk
PKG_NAME:=exim
-PKG_VERSION:=4.96.1
+PKG_VERSION:=4.96.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://ftp.exim.org/pub/exim/exim4/
-PKG_HASH:=93ac0755c317e1fdbbea8ccb70a868876bdf3148692891c72ad0fe816767033d
+PKG_HASH:=038e327e8d1e93d005bac9bb06fd22aec44d5028930d6dbe8817ad44bbfc1de6
PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
PKG_LICENSE:=GPL-2.0-or-later
#endif
--- a/src/string.c
+++ b/src/string.c
-@@ -418,6 +418,7 @@ return ss;
+@@ -428,6 +428,7 @@ return ss;
#if (defined(HAVE_LOCAL_SCAN) || defined(EXPAND_DLFUNC)) \
&& !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
/*************************************************
* Copy and save string *
*************************************************/
-@@ -463,6 +464,7 @@ string_copyn_function(const uschar * s,
+@@ -473,6 +474,7 @@ string_copyn_function(const uschar * s,
{
return string_copyn(s, n);
}
include $(TOPDIR)/rules.mk
PKG_NAME:=fdm
-PKG_VERSION:=2.0
-PKG_RELEASE:=3
+PKG_VERSION:=2.2
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/nicm/fdm/releases/download/$(PKG_VERSION)
-PKG_HASH:=06b28cb6b792570bc61d7e29b13d2af46b92fea77e058b2b17e11e8f7ed0cea4
+PKG_HASH:=53aad117829834e21c1b9bf20496a1aa1c0e0fb98fe7735e1e73314266fb6c16
PKG_MAINTAINER:=Dmitry V. Zimin <pfzim@mail.ru>
PKG_LICENSE:=BSD-2-Clause
TITLE:=fetch mail and deliver
URL:=https://github.com/nicm/fdm
MENU:=1
- DEPENDS:=+tdb +zlib +libopenssl +FDM_WITH_PCRE:libpcre
+ DEPENDS:=+tdb +zlib +libopenssl +FDM_WITH_PCRE:libpcre2
USERID:=_fdm=99:_fdm=99
endef
endef
ifdef CONFIG_FDM_WITH_PCRE
- CONFIGURE_ARGS += --enable-pcre
+ CONFIGURE_ARGS += --enable-pcre2
endif
define Package/fdm/config
+++ /dev/null
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -123,6 +123,3 @@ endif
- if NO_STRTONUM
- nodist_fdm_SOURCES += compat/strtonum.c
- endif
--if NO_B64_NTOP
--nodist_fdm_SOURCES += compat/base64.c
--endif
+++ /dev/null
-From 3aa079c4885d89257c5033b4992011511b603150 Mon Sep 17 00:00:00 2001
-From: Rosen Penev <rosenp@gmail.com>
-Date: Tue, 26 Jun 2018 14:14:34 -0700
-Subject: [PATCH] Fix compile with OpenSSL 1.1.0
-
-OpenSSL 1.1.0 deprecared SSL_library_init and SSL_load_error_strings.
-They're part of OPENSSL_init_ssl now.
----
- fdm.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/fdm.c
-+++ b/fdm.c
-@@ -717,8 +717,10 @@ retry:
- }
- conf.lock_file = lock;
-
-+#if OPENSSL_VERSION_NUMBER < 0x10100000L
- SSL_library_init();
- SSL_load_error_strings();
-+#endif
-
- /* Filter account list. */
- TAILQ_INIT(&actaq);
+++ /dev/null
-From 3232e537ccaba4417b25d9d70264e4a5533042da Mon Sep 17 00:00:00 2001
-From: Nicholas Marriott <nicholas.marriott@gmail.com>
-Date: Mon, 18 Mar 2019 13:04:00 +0000
-Subject: [PATCH] Fix bas64 declarations, from makepost at firemail dot cc.
-
----
- fdm.h | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
---- a/fdm.h
-+++ b/fdm.h
-@@ -20,7 +20,6 @@
- #define FDM_H
-
- #include <sys/param.h>
--#include <sys/cdefs.h>
- #include <sys/stat.h>
-
- #ifdef HAVE_QUEUE_H
-@@ -725,8 +724,8 @@ size_t strlcat(char *, const char *, s
-
- #ifndef HAVE_B64_NTOP
- /* base64.c */
--int b64_ntop(src, srclength, target, targsize);
--int b64_pton(src, target, targsize);
-+int b64_ntop(u_char const *, size_t, char *, size_t);
-+int b64_pton(char const *, u_char *, size_t);
- #endif
-
- /* shm.c */
--- /dev/null
+From f1ec1982725d60045c0d871f3e613f2880046c22 Mon Sep 17 00:00:00 2001
+From: Nicholas Marriott <nicholas.marriott@gmail.com>
+Date: Wed, 1 Feb 2023 15:31:30 +0000
+Subject: [PATCH] Fix bugs in PCRE2 code - don't walk off the end of the match
+ list if NOMATCH is returned, and don't stop on empty matches. From Thomas
+ Hurst.
+
+---
+ pcre.c | 45 ++++++++++++++++++++++++++-------------------
+ 1 file changed, 26 insertions(+), 19 deletions(-)
+
+--- a/pcre.c
++++ b/pcre.c
+@@ -66,7 +66,7 @@ int
+ re_block(struct re *re, const void *buf, size_t len, struct rmlist *rml,
+ char **cause)
+ {
+- int res;
++ int res, ret;
+ pcre2_match_data *pmd;
+ PCRE2_SIZE *ovector;
+ u_int i, j;
+@@ -85,27 +85,34 @@ re_block(struct re *re, const void *buf,
+ }
+
+ pmd = pcre2_match_data_create_from_pattern(re->pcre2, NULL);
+- res = pcre2_match(re->pcre2, buf, len, 0, 0, pmd, NULL);
+- if (res < 0 && res != PCRE2_ERROR_NOMATCH) {
+- xasprintf(cause, "%s: regexec failed", re->str);
+- pcre2_match_data_free(pmd);
+- return (-1);
+- }
++ if (pmd == NULL)
++ fatalx("pcre2_match_data_create_from_pattern failed");
+
+- if (rml != NULL) {
+- ovector = pcre2_get_ovector_pointer(pmd);
+- for (i = 0; i < res; i++) {
+- j = i * 2;
+- if (ovector[j + 1] <= ovector[j])
+- break;
+- rml->list[i].valid = 1;
+- rml->list[i].so = ovector[j];
+- rml->list[i].eo = ovector[j + 1];
++ res = pcre2_match(re->pcre2, buf, len, 0, 0, pmd, NULL);
++ if (res > 0) {
++ if (rml != NULL) {
++ if (res > NPMATCH)
++ res = NPMATCH;
++ ovector = pcre2_get_ovector_pointer(pmd);
++ for (i = 0; i < res; i++) {
++ j = i * 2;
++ if (ovector[j + 1] < ovector[j])
++ break;
++ rml->list[i].valid = 1;
++ rml->list[i].so = ovector[j];
++ rml->list[i].eo = ovector[j + 1];
++ }
++ rml->valid = 1;
+ }
+- rml->valid = 1;
++ ret = 1;
++ } else if (res == PCRE2_ERROR_NOMATCH)
++ ret = 0;
++ else {
++ xasprintf(cause, "%s: regexec failed", re->str);
++ ret = -1;
+ }
+-
+- return (res != PCRE2_ERROR_NOMATCH);
++ pcre2_match_data_free(pmd);
++ return (ret);
+ }
+
+ void
--- /dev/null
+From 028f59bef0ea9435fb8fbe095b2939652ce63479 Mon Sep 17 00:00:00 2001
+From: Nicholas Marriott <nicholas.marriott@gmail.com>
+Date: Mon, 3 Apr 2023 08:54:28 +0100
+Subject: [PATCH] Fix use-after-free, GitHub issue 126.
+
+---
+ connect.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/connect.c
++++ b/connect.c
+@@ -550,8 +550,8 @@ httpproxy(struct server *srv,
+ if (strlen(line) < 12 ||
+ strncmp(line, "HTTP/", 5) != 0 ||
+ strncmp(line + 8, " 200", 4) != 0) {
+- xfree(line);
+ xasprintf(cause, "unexpected data: %s", line);
++ xfree(line);
+ return (-1);
+ }
+ header = 1;
include $(TOPDIR)/rules.mk
PKG_NAME:=postfix
-PKG_VERSION:=3.5.8
-PKG_RELEASE:=3
+PKG_VERSION:=3.8.2
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:= \
https://de.postfix.org/ftpmirror/official/ \
http://ftp.porcupine.org/mirrors/postfix-release/official/
-PKG_HASH:=22582628cf3edc18c5155c9ff44543dd95a9435fb68135d76a99f572cb07456f
+PKG_HASH:=6790903cdbb5e0e47196691eb9a5f2cf8050262def941e039e6d4bf4043a5e30
PKG_MAINTAINER:=Denis Shulyaka <Shulyaka@gmail.com>
PKG_LICENSE:=IPL-1.0
postfix=25:postfix=25 \
postdrop=26:postdrop=26
URL:=http://www.postfix.org/
- DEPENDS:=+POSTFIX_CDB:tinycdb +POSTFIX_TLS:libopenssl +POSTFIX_SASL:libsasl2 +POSTFIX_LDAP:libopenldap +POSTFIX_DB:libdb47 +POSTFIX_SQLITE:libsqlite3 +POSTFIX_MYSQL:libmysqlclient +POSTFIX_PGSQL:libpq +POSTFIX_EAI:icu +POSTFIX_PCRE:libpcre
+ DEPENDS:=+POSTFIX_CDB:tinycdb +POSTFIX_TLS:libopenssl +POSTFIX_SASL:libsasl2 +POSTFIX_LDAP:libopenldap +POSTFIX_DB:libdb47 +POSTFIX_SQLITE:libsqlite3 +POSTFIX_MYSQL:libmysqlclient +POSTFIX_PGSQL:libpq +POSTFIX_EAI:icu +POSTFIX_PCRE:libpcre2
MENU:=1
endef
endif
ifdef CONFIG_POSTFIX_PCRE
- CCARGS+=-DHAS_PCRE -I$(STAGING_DIR)/usr/include/
- AUXLIBS+=-L$(STAGING_DIR)/usr/lib -lpcre
+ CCARGS+=-DHAS_PCRE=2 -I$(STAGING_DIR)/usr/include/
+ AUXLIBS+=-L$(STAGING_DIR)/usr/lib -lpcre2-8
else
CCARGS+=-DNO_PCRE
endif
#endif
--- a/src/util/sys_defs.h
+++ b/src/util/sys_defs.h
-@@ -1509,7 +1509,7 @@ extern int setsid(void);
+@@ -1519,7 +1519,7 @@ extern int setsid(void);
#endif
#ifndef HAS_CLOSEFROM
#endif
-@@ -1563,7 +1563,7 @@ typedef int pid_t;
+@@ -1573,7 +1573,7 @@ typedef int pid_t;
/*
* Clang-style attribute tests.
* XXX Without the unconditional test below, gcc 4.6 will barf on ``elif
* defined(__clang__) && __has_attribute(__whatever__)'' with error message
* ``missing binary operator before token "("''.
-@@ -1577,7 +1577,7 @@ typedef int pid_t;
+@@ -1587,7 +1587,7 @@ typedef int pid_t;
* warn for missing initializations and other trouble. However, OPENSTEP4
* gcc 2.7.x cannot handle this so we define this only if NORETURN isn't
* already defined above.
* Data point: gcc 2.7.2 has __attribute__ (Wietse Venema) but gcc 2.6.3 does
* not (Clive Jones). So we'll set the threshold at 2.7.
*/
-@@ -1653,12 +1653,12 @@ typedef int pid_t;
+@@ -1663,12 +1663,12 @@ typedef int pid_t;
* write to output parameters (for example, stat- or scanf-like functions)
* or from functions that have other useful side effects (for example,
* fseek- or rename-like functions).
* XXX Prepending "(void)" won't shut up GCC. Clang behaves as expected.
*/
#if ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ > 3)
-@@ -1747,7 +1747,7 @@ typedef const char *CONST_CHAR_STAR;
+@@ -1749,7 +1749,7 @@ typedef const char *CONST_CHAR_STAR;
* Safety. On some systems, ctype.h misbehaves with non-ASCII or negative
* characters. More importantly, Postfix uses the ISXXX() macros to ensure
* protocol compliance, so we have to rule out non-ASCII characters.
--- a/src/util/dict_db.c
+++ b/src/util/dict_db.c
-@@ -750,8 +750,8 @@ static DICT *dict_db_open(const char *cl
+@@ -751,8 +751,8 @@ static DICT *dict_db_open(const char *cl
msg_fatal("create DB database: %m");
if (db == 0)
msg_panic("db_create null result");
+// if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0)
+// msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM);
db_base_buf = vstring_alloc(100);
- #if DB_VERSION_MAJOR == 6 || DB_VERSION_MAJOR == 5 || \
+ #if DB_VERSION_MAJOR == 18 || DB_VERSION_MAJOR == 6 || DB_VERSION_MAJOR == 5 || \
(DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0)
--- a/src/util/sys_defs.h
+++ b/src/util/sys_defs.h
-@@ -760,9 +760,8 @@ extern int initgroups(const char *, int)
+@@ -774,9 +774,8 @@ extern int initgroups(const char *, int)
#define INTERNAL_LOCK MYFLOCK_STYLE_FLOCK
#define DEF_MAILBOX_LOCK "fcntl, dotlock" /* RedHat >= 4.x */
#define HAS_FSYNC
--- a/makedefs
+++ b/makedefs
-@@ -215,7 +215,7 @@ error() {
+@@ -233,7 +233,7 @@ ARFL=rv
case $# in
# Officially supported usage.
RELEASE=`(uname -r) 2>/dev/null`
# No ${x%%y} support in Solaris 11 /bin/sh
RELEASE_MAJOR=`expr "$RELEASE" : '\([0-9]*\)'` || exit 1
-@@ -242,6 +242,15 @@ case "$SYSTEM" in
+@@ -247,6 +247,15 @@ case $# in
esac
case "$SYSTEM.$RELEASE" in
--- a/src/posttls-finger/posttls-finger.c
+++ b/src/posttls-finger/posttls-finger.c
-@@ -342,6 +342,7 @@
+@@ -346,6 +346,7 @@
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+++ /dev/null
---- a/src/util/sys_defs.h
-+++ b/src/util/sys_defs.h
-@@ -749,7 +749,8 @@ extern int initgroups(const char *, int)
- /*
- * LINUX.
- */
--#if defined(LINUX2) || defined(LINUX3) || defined(LINUX4) || defined(LINUX5)
-+#if defined(LINUX2) || defined(LINUX3) || defined(LINUX4) || defined(LINUX5) \
-+ || defined(LINUX6)
- #define SUPPORTED
- #define UINT32_TYPE unsigned int
- #define UINT16_TYPE unsigned short
--- a/conf/main.cf
+++ b/conf/main.cf
-@@ -40,43 +40,8 @@ compatibility_level = 2
+@@ -44,43 +44,8 @@ compatibility_level = 3.8
#
#soft_bounce = no
# The default_privs parameter specifies the default rights used by
# the local delivery agent for delivery to external file or command.
# These rights are used in the absence of a recipient user context.
-@@ -632,45 +597,4 @@ debugger_command =
+@@ -641,45 +606,4 @@ debugger_command =
# -dmS $process_name gdb $daemon_directory/$process_name
# $process_id & sleep 1
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-libav
-PKG_VERSION:=1.22.3
+PKG_VERSION:=1.22.6
PKG_RELEASE:=1
PKG_SOURCE:=gst-libav-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gst-libav
-PKG_HASH:=2ec5c805808b4371a7e32b1da0202a1c8a6b36b6ce905080bf5c34097d12a923
+PKG_HASH:=7789e6408388a25f23cbf948cfc5c6230d735bbcd8b7f37f4a01c9e348a1e3a7
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-libav-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-plugins-bad
-PKG_VERSION:=1.22.3
+PKG_VERSION:=1.22.6
PKG_RELEASE:=1
PKG_SOURCE:=gst-plugins-bad-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://gstreamer.freedesktop.org/src/gst-plugins-bad/
-PKG_HASH:=e1798fee2d86127f0637481c607f983293bf0fd81aad70a5c7b47205af3621d8
+PKG_HASH:=b4029cd2908a089c55f1d902a565d007495c95b1442d838485dc47fb12df7137
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-bad-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
--- a/meson.build
+++ b/meson.build
-@@ -501,7 +501,7 @@ gst_plugins_bad_args = ['-DHAVE_CONFIG_H
+@@ -508,7 +508,7 @@ gst_plugins_bad_args = ['-DHAVE_CONFIG_H
configinc = include_directories('.')
libsinc = include_directories('gst-libs')
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-plugins-base
-PKG_VERSION:=1.22.3
+PKG_VERSION:=1.22.6
PKG_RELEASE:=1
PKG_SOURCE:=gst-plugins-base-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gst-plugins-base
-PKG_HASH:=1c596289a0d4207380233eba8c36a932c4d1aceba19932937d9b57c24cef89f3
+PKG_HASH:=50f2b4d17c02eefe430bbefa8c5cd134b1be78a53c0f60e951136d96cf49fd4b
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-base-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-plugins-good
-PKG_VERSION:=1.22.3
+PKG_VERSION:=1.22.6
PKG_RELEASE:=1
PKG_SOURCE:=gst-plugins-good-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gst-plugins-good/
-PKG_HASH:=af81154b3a2ef3f4d2feba395f25696feea6fd13ec62c92d3c7a973470710273
+PKG_HASH:=b3b07fe3f1ce7fe93aa9be7217866044548f35c4a7792280eec7e108a32f9817
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-good-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
--- a/meson.build
+++ b/meson.build
-@@ -461,7 +461,7 @@ endif
+@@ -469,7 +469,7 @@ endif
presetdir = join_paths(get_option('datadir'), 'gstreamer-' + api_version, 'presets')
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-plugins-ugly
-PKG_VERSION:=1.22.3
+PKG_VERSION:=1.22.6
PKG_RELEASE:=1
PKG_SOURCE:=gst-plugins-ugly-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gst-plugins-ugly
-PKG_HASH:=3dc98ed5c2293368b3c4e6ce55d89be834a0a62e9bf88ef17928cf03b7d5a360
+PKG_HASH:=3e31454c98cb2f7f6d2d355eceb933a892fa0f1dc09bc36c9abc930d8e29ca48
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-ugly-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
include $(TOPDIR)/rules.mk
PKG_NAME:=gstreamer1
-PKG_VERSION:=1.22.3
+PKG_VERSION:=1.22.6
PKG_RELEASE:=1
PKG_SOURCE:=gstreamer-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gstreamer
-PKG_HASH:=9ffeab95053f9f6995eb3b3da225e88f21c129cd60da002d3f795db70d6d5974
+PKG_HASH:=f500e6cfddff55908f937711fc26a0840de28a1e9ec49621c0b6f1adbd8f818e
PKG_BUILD_DIR:=$(BUILD_DIR)/gstreamer-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
help
Use internal POSIX Regular Expressions.
Note that not all EPG parsers will work with POSIX RegEx.
- config TVHEADEND_REGEX_PCRE
- bool "PCRE (libpcre)"
- select PACKAGE_libpcre
- help
- Use more advanced Perl-Compatible Regular Expressions, provided by libpcre.
config TVHEADEND_REGEX_PCRE2
bool "PCRE2 (libpcre2)"
select PACKAGE_libpcre2
PKG_NAME:=tvheadend
PKG_VERSION:=2023-06-05
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/tvheadend/tvheadend.git
$(ICONV_DEPENDS) \
+zlib \
+TVHEADEND_AVAHI_SUPPORT:libavahi-client \
- +TVHEADEND_REGEX_PCRE:libpcre \
+TVHEADEND_REGEX_PCRE2:libpcre2 \
+BUILD_PATENTED&&TVHEADEND_CSA:libdvbcsa
CONFIGURE_ARGS += --disable-trace
endif
+CONFIGURE_ARGS += --disable-pcre
ifneq ($(CONFIG_TVHEADEND_REGEX_PCRE2),)
- CONFIGURE_ARGS += --disable-pcre --enable-pcre2
-else
-ifneq ($(CONFIG_TVHEADEND_REGEX_PCRE),)
- CONFIGURE_ARGS += --enable-pcre --disable-pcre2
+ CONFIGURE_ARGS += --enable-pcre2
else
ifneq ($(CONFIG_TVHEADEND_REGEX_POSIX),)
- CONFIGURE_ARGS += --disable-pcre --disable-pcre2
-endif
+ CONFIGURE_ARGS += --disable-pcre2
endif
endif
include $(TOPDIR)/rules.mk
PKG_NAME:=yt-dlp
-PKG_VERSION:=2023.3.4
-PKG_RELEASE:=2
+PKG_VERSION:=2023.11.16
+PKG_RELEASE:=1
PYPI_NAME:=yt-dlp
-PKG_HASH:=265d5da97a76c15d7d9a4088a67b78acd5dcf6f8cfd8257c52f581ff996ff515
+PKG_HASH:=f0ccdaf12e08b15902601a4671c7ab12906d7b11de3ae75fa6506811c24ec5da
PKG_MAINTAINER:=Michal Vasilek <michal.vasilek@nic.cz>
PKG_LICENSE:=Unlicense
include $(TOPDIR)/rules.mk
PKG_NAME:=aardvark-dns
-PKG_VERSION:=1.8.0
+PKG_VERSION:=1.9.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/containers/aardvark-dns/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=c9b818110e3d5d45f8bdb3c9ccc48c994aedb0b19fefcc7577fc1ef7ed294343
+PKG_HASH:=d6b51743d334c42ec98ff229be044b5b2a5fedf8da45a005447809c4c1e9beea
PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
include ../../lang/rust/rust-package.mk
include $(TOPDIR)/rules.mk
PKG_NAME:=acme-acmesh
-PKG_VERSION:=3.0.6
+PKG_VERSION:=3.0.7
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/acmesh-official/acme.sh/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=4a8e44c27e2a8f01a978e8d15add8e9908b83f9b1555670e49a9b769421f5fa6
+PKG_HASH:=abd446d6bd45d0b44dca1dcbd931348797a3f82d1ed6fb171472eaf851a8d849
PKG_BUILD_DIR:=$(BUILD_DIR)/acme.sh-$(PKG_VERSION)
PKG_MAINTAINER:=Toke Høiland-Jørgensen <toke@toke.dk>
-# Copyright 2023 Stan Grishin (stangri@melmac.ca)
+# Copyright 2023 MOSSDeF, Stan Grishin (stangri@melmac.ca)
# TLD optimization written by Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.
include $(TOPDIR)/rules.mk
PKG_NAME:=adblock-fast
-PKG_VERSION:=1.0.0
-PKG_RELEASE:=6
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=7
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
PKG_LICENSE:=GPL-3.0-or-later
endef
define Package/adblock-fast/description
-Fast AdBlocking script to block ad or abuse/malware domains with DNSMASQ or Unbound.
+Fast AdBlocking script to block ad or abuse/malware domains with Dnsmasq, SmartDNS or Unbound.
Script supports local/remote list of domains and hosts-files for both block-listing and allow-listing.
Please see https://docs.openwrt.melmac.net/adblock-fast/ for more information.
endef
option compressed_cache '0'
option compressed_cache_dir '/etc'
option config_update_enabled '0'
- option config_update_url 'https://cdn.jsdelivr.net/gh/openwrt/packages/net/adblock-fast/files/adblock-fast.conf.update'
+ option config_update_url 'https://cdn.jsdelivr.net/gh/openwrt/packages/net/adblock-fast/files/adblock-fast.config.update'
option curl_additional_param ''
option curl_max_file_size '30000000'
option curl_retry '3'
# list force_dns_port '8443'
option led 'none'
option parallel_downloads '1'
+ option pause_timeout '20'
option procd_trigger_wan6 '0'
+ option procd_boot_delay '0'
option procd_boot_wan_timeout '60'
option verbosity '2'
#!/bin/sh /etc/rc.common
# Copyright 2023 MOSSDeF, Stan Grishin (stangri@melmac.ca)
-# shellcheck disable=SC1091,SC2015,SC2016,SC3037,SC3043,SC3045,SC3057,SC3060
+# shellcheck disable=SC3043
# shellcheck disable=SC2034
START=94
USE_PROCD=1
LC_ALL=C
-if type extra_command 1>/dev/null 2>&1; then
- extra_command 'allow' 'Allows domain in current block-list and config'
- extra_command 'check' 'Checks if specified domain is found in current block-list'
- extra_command 'dl' 'Force-downloads all enabled block-list'
- extra_command 'killcache' 'Delete all cached files'
- extra_command 'pause' 'Pauses AdBlocking for specified number of seconds (default: 60)'
- extra_command 'sizes' 'Displays the file-sizes of enabled block-lists'
- extra_command 'version' 'Show version information'
-else
-# shellcheck disable=SC2034
- EXTRA_COMMANDS='allow check dl killcache pause sizes status_service version'
-# shellcheck disable=SC2034
- EXTRA_HELP=' allow Allows domain(s) in current block-list and config
- check Checks if specified domain is found in current block-list
- dl Force-downloads all enabled block-list
- pause Pauses AdBlocking for specified number of seconds (default: 60)
- sizes Displays the file-sizes of enabled block-lists'
-fi
-
readonly PKG_VERSION='dev-test'
readonly packageName='adblock-fast'
readonly serviceName="$packageName $PKG_VERSION"
readonly dnsmasqServersCache="/var/run/${packageName}/dnsmasq.servers.cache"
readonly dnsmasqServersGzip="${packageName}.dnsmasq.servers.gz"
readonly dnsmasqServersFilter='s|^|server=/|;s|$|/|'
+readonly smartdnsDomainSetFile="/var/run/${packageName}/smartdns.domainset"
+readonly smartdnsDomainSetCache="/var/run/${packageName}/smartdns.domainset.cache"
+readonly smartdnsDomainSetConfig="/var/run/${packageName}/smartdns.domainset.conf"
+readonly smartdnsDomainSetGzip="${packageName}.smartdns.domainset.gz"
+readonly smartdnsDomainSetFilter=';'
+readonly smartdnsIpsetFile="/var/run/${packageName}/smartdns.ipset"
+readonly smartdnsIpsetCache="/var/run/${packageName}/smartdns.ipset.cache"
+readonly smartdnsIpsetConfig="/var/run/${packageName}/smartdns.ipset.conf"
+readonly smartdnsIpsetGzip="${packageName}.smartdns.ipset.gz"
+readonly smartdnsIpsetFilter=';'
+readonly smartdnsNftsetFile="/var/run/${packageName}/smartdns.nftset"
+readonly smartdnsNftsetCache="/var/run/${packageName}/smartdns.nftset.cache"
+readonly smartdnsNftsetConfig="/var/run/${packageName}/smartdns.nftset.conf"
+readonly smartdnsNftsetGzip="${packageName}.smartdns.nftset.gz"
+readonly smartdnsNftsetFilter=';'
readonly unboundFile="/var/lib/unbound/adb_list.${packageName}"
readonly unboundCache="/var/run/${packageName}/unbound.cache"
readonly unboundGzip="${packageName}.unbound.gz"
readonly unboundFilter='s|^|local-zone: "|;s|$|" static|'
-readonly A_TMP="/var/${packageName}.hosts.a.tmp"
-readonly B_TMP="/var/${packageName}.hosts.b.tmp"
+readonly A_TMP="/var/${packageName}.a.tmp"
+readonly B_TMP="/var/${packageName}.b.tmp"
+readonly SED_TMP="/var/${packageName}.sed.tmp"
readonly jsonFile="/dev/shm/$packageName-status.json"
readonly sharedMemoryError="/dev/shm/$packageName-error"
readonly hostsFilter='/localhost/d;/^#/d;/^[^0-9]/d;s/^0\.0\.0\.0.//;s/^127\.0\.0\.1.//;s/[[:space:]]*#.*$//;s/[[:cntrl:]]$//;s/[[:space:]]//g;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;'
readonly dnsmasqFileFilter='\|^server=/[[:alnum:]_.-].*/|!d;s|server=/||;s|/.*$||'
readonly dnsmasq2FileFilter='\|^local=/[[:alnum:]_.-].*/|!d;s|local=/||;s|/.*$||'
readonly dnsmasq3FileFilter='\|^address=/[[:alnum:]_.-].*/|!d;s|address=/||;s|/.*$||'
+readonly _ERROR_='\033[0;31mERROR\033[0m'
readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m'
readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m'
readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m'
readonly __FAIL__='\033[0;31m[\xe2\x9c\x97]\033[0m'
-readonly _ERROR_='\033[0;31mERROR\033[0m'
readonly _WARNING_='\033[0;33mWARNING\033[0m'
# shellcheck disable=SC2155
readonly ipset="$(command -v ipset)"
allowed_url=
blocked_url=
+# shellcheck disable=SC1091
+. /lib/functions.sh
+# shellcheck disable=SC1091
+. /lib/functions/network.sh
+# shellcheck disable=SC1091
+. /usr/share/libubox/jshn.sh
+
+append_newline() { is_newline_ending "$1" || echo '' >> "$1"; }
+check_ipset() { { command -v ipset && /usr/sbin/ipset help hash:net; } >/dev/null 2>&1; }
+check_nft() { command -v nft >/dev/null 2>&1; }
+check_dnsmasq() { command -v dnsmasq >/dev/null 2>&1; }
+check_dnsmasq_ipset() {
+ local o;
+ check_dnsmasq || return 1
+ o="$(dnsmasq -v 2>/dev/null)"
+ check_ipset && ! echo "$o" | grep -q 'no-ipset' && echo "$o" | grep -q 'ipset'
+}
+check_dnsmasq_nftset() {
+ local o;
+ check_dnsmasq || return 1
+ o="$(dnsmasq -v 2>/dev/null)"
+ check_nft && ! echo "$o" | grep -q 'no-nftset' && echo "$o" | grep -q 'nftset'
+}
+check_smartdns() { command -v smartdns >/dev/null 2>&1; }
+check_smartdns_ipset() { check_smartdns && check_ipset; }
+check_smartdns_nftset() { check_smartdns && check_nft; }
+check_unbound() { command -v unbound >/dev/null 2>&1; }
debug() { local i j; for i in "$@"; do eval "j=\$$i"; echo "${i}: ${j} "; done; }
+dnsmasq_hup() { killall -q -s HUP dnsmasq; }
+dnsmasq_kill() { killall -q -s KILL dnsmasq; }
+dnsmasq_restart() { /etc/init.d/dnsmasq restart >/dev/null 2>&1; }
+is_enabled() { uci_get "$1" 'config' 'enabled' '0'; }
+is_fw4_restart_needed() {
+ local dns force_dns
+ dns="$(uci_get "$packageName" 'config' 'dns' 'dnsmasq.servers')"
+ force_dns="$(uci_get "$packageName" 'config' 'force_dns' '1')"
+ if [ "$force_dns" = '1' ]; then
+ return 0
+ elif [ "$dns" = 'dnsmasq.ipset' ]; then
+ return 0
+ elif [ "$dns" = 'dnsmasq.nftset' ]; then
+ return 0
+ elif [ "$dns" = 'smartdns.ipset' ]; then
+ return 0
+ elif [ "$dns" = 'smartdns.nftset' ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+is_integer() {
+ case "$1" in
+ (*[!0123456789]*) return 1;;
+ ('') return 1;;
+ (*) return 0;;
+ esac
+}
+is_greater() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
+is_greater_or_equal() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" = "$2"; }
+# shellcheck disable=SC3057
+is_https_url() { [ "${1:0:8}" = "https://" ]; }
+is_newline_ending() { [ "$(tail -c1 "$1" | wc -l)" -ne '0' ]; }
+is_present() { command -v "$1" >/dev/null 2>&1; }
+is_running() {
+ local i j
+ i="$(json 'get' 'status')"
+ j="$(ubus_get_data 'status')"
+ if [ "$i" = 'statusStopped' ] || [ -z "${i}${j}" ]; then
+ return 1
+ else
+ return 0
+ fi
+}
+ipset() { "$ipset" "$@" >/dev/null 2>&1; }
+get_version() { grep -m1 -A2 -w "^Package: $1$" /usr/lib/opkg/status | sed -n 's/Version: //p'; }
+get_ram_free() { ubus call system info | jsonfilter -e '@.memory.free'; }
+get_ram_total() { ubus call system info | jsonfilter -e '@.memory.total'; }
+led_on(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'default-on' > "${1}/trigger" 2>&1; fi; }
+led_off(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'none' > "${1}/trigger" 2>&1; fi; }
+logger() { /usr/bin/logger -t "$packageName" "$@"; }
+nft() { "$nft" "$@" >/dev/null 2>&1; }
+output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; }
+output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; }
+output_fail() { output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; }
+output_failn() { output 1 "$_FAIL_\\n"; output 2 "$__FAIL__\\n"; }
+print_json_bool() { json_init; json_add_boolean "$1" "$2"; json_dump; json_cleanup; }
+print_json_int() { json_init; json_add_int "$1" "$2"; json_dump; json_cleanup; }
+print_json_string() { json_init; json_add_string "$1" "$2"; json_dump; json_cleanup; }
+sanitize_dir() { [ -d "$(readlink -fn "$1")" ] && readlink -fn "$1"; }
+smartdns_restart() { /etc/init.d/smartdns restart >/dev/null 2>&1; }
+str_contains() { test "$1" != "$(str_replace "$1" "$2" '')"; }
+str_contains_word() { echo "$1" | grep -q -w "$2"; }
+# shellcheck disable=SC2018,SC2019
+str_to_lower() { echo "$1" | tr 'A-Z' 'a-z'; }
+# shellcheck disable=SC2018,SC2019
+str_to_upper() { echo "$1" | tr 'a-z' 'A-Z'; }
+str_replace() { printf "%b" "$1" | sed -e "s/$(printf "%b" "$2")/$(printf "%b" "$3")/g"; }
+ubus_get_data() { ubus call service list "{ 'name': '$packageName' }" | jsonfilter -e "@['${packageName}'].instances.main.data.${1}"; }
+ubus_get_ports() { ubus call service list "{ 'name': '$packageName' }" | jsonfilter -e "@['${packageName}'].instances.main.data.firewall.*.dest_port"; }
+uci_get_protocol() { uci_get 'network' "$1" 'proto'; }
+unbound_restart() { /etc/init.d/unbound restart >/dev/null 2>&1; }
+
+json() {
+# shellcheck disable=SC2034
+ local action="$1" param="$2" value="$3"
+ shift 3
+# shellcheck disable=SC2124
+ local extras="$@" line
+ local status message error stats
+ local reload restart curReload curRestart
+ local ret i
+ if [ -s "$jsonFile" ]; then
+ json_load_file "$jsonFile" 2>/dev/null
+ json_select 'data' 2>/dev/null
+ for i in status message error stats reload restart; do
+ json_get_var "$i" "$i" 2>/dev/null
+ done
+ fi
+ case "$action" in
+ get)
+ case "$param" in
+ triggers)
+# shellcheck disable=SC2154
+ curReload="$parallel_downloads $debug $download_timeout \
+ $allowed_domain $blocked_domain $allowed_url $blocked_url $dns \
+ $config_update_enabled $config_update_url $dnsmasq_config_file_url \
+ $curl_additional_param $curl_max_file_size $curl_retry"
+# shellcheck disable=SC2154
+ curRestart="$compressed_cache $compressed_cache_dir $force_dns $led \
+ $force_dns_port"
+ if [ ! -s "$jsonFile" ]; then
+ ret='on_boot'
+ elif [ "$curReload" != "$reload" ]; then
+ ret='download'
+ elif [ "$curRestart" != "$restart" ]; then
+ ret='restart'
+ fi
+ printf "%b" "$ret"
+ return;;
+ *)
+ printf "%b" "$(eval echo "\$$param")"; return;;
+ esac
+ ;;
+ add)
+ line="$(eval echo "\$$param")"
+ eval "$param"='${line:+$line }${value}${extras:+|$extras}'
+ ;;
+ del)
+ case "$param" in
+ all)
+ unset status message error stats;;
+ triggers)
+ unset reload restart;;
+ *)
+ unset "$param";;
+ esac
+ ;;
+ set)
+ case "$param" in
+ triggers)
+ reload="$parallel_downloads $debug $download_timeout \
+ $allowed_domain $blocked_domain $allowed_url $blocked_url $dns \
+ $config_update_enabled $config_update_url $dnsmasq_config_file_url \
+ $curl_additional_param $curl_max_file_size $curl_retry"
+ restart="$compressed_cache $compressed_cache_dir $force_dns $led \
+ $force_dns_port"
+ ;;
+ *)
+ eval "$param"='${value}${extras:+|$extras}';;
+ esac
+ ;;
+ esac
+ json_init
+ json_add_object 'data'
+ json_add_string version "$PKG_VERSION"
+ json_add_string status "$status"
+ json_add_string message "$message"
+ json_add_string error "$error"
+ json_add_string stats "$stats"
+ json_add_string reload "$reload"
+ json_add_string restart "$restart"
+ json_close_object
+ mkdir -p "$(dirname "$jsonFile")"
+ json_dump > "$jsonFile"
+ sync
+}
+
+get_local_filesize() {
+ local file="$1" size
+ [ -f "$file" ] || return 0
+ if is_present stat; then
+ size="$(stat -c%s "$file")"
+ elif is_present wc; then
+ size="$(wc -c < "$file")"
+ fi
+# shellcheck disable=SC3037
+ echo -en "$size"
+}
+
+get_url_filesize() {
+ local url="$1" size size_command
+ [ -n "$url" ] || return 0
+ is_present 'curl' || return 0
+ size_command='curl --silent --insecure --fail --head --request GET'
+# size="$($size_command "$url" | grep -Po '^[cC]ontent-[lL]ength: \K\w+')"
+ size="$($size_command "$url" | grep -Eo '^[cC]ontent-[lL]ength: (.*)' | awk '{print $2}')"
+# shellcheck disable=SC3037
+ echo -en "$size"
+}
+
+output() {
+# Target verbosity level with the first parameter being an integer
+ is_integer() {
+ case "$1" in
+ (*[!0123456789]*) return 1;;
+ ('') return 1;;
+ (*) return 0;;
+ esac
+ }
+ local msg memmsg logmsg text
+ local sharedMemoryOutput="/dev/shm/$packageName-output"
+ if [ -z "$verbosity" ] && [ -n "$packageName" ]; then
+ verbosity="$(uci_get "$packageName" 'config' 'verbosity' '2')"
+ fi
+ if [ $# -ne 1 ] && is_integer "$1"; then
+ if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; text="$*"; else return 0; fi
+ fi
+ text="${text:-$*}";
+ [ -t 1 ] && printf "%b" "$text"
+# shellcheck disable=SC3060
+ msg="${text//$serviceName /service }";
+ if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then
+ [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")"
+ logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')"
+ logger -t "${packageName:-service} [$$]" "$(printf "%b" "$logmsg")"
+ rm -f "$sharedMemoryOutput"
+ else
+ printf "%b" "$msg" >> "$sharedMemoryOutput"
+ fi
+}
uci_add_list_if_new() {
local PACKAGE="$1"
done
uci_add_list "$PACKAGE" "$CONFIG" "$OPTION" "$VALUE"
}
+
uci_changes() {
local PACKAGE="$1"
local CONFIG="$2"
local OPTION="$3"
- /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} changes "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}"
+ if [ -s "${UCI_CONFIG_DIR:-/etc/config/}${PACKAGE}" ]; then
+ /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} changes "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}"
+ fi
}
-ipset() { "$ipset" "$@" >/dev/null 2>&1; }
-nft() { "$nft" "$@" >/dev/null 2>&1; }
+if type extra_command 1>/dev/null 2>&1; then
+ extra_command 'allow' 'Allows domain in current block-list and config'
+ extra_command 'check' 'Checks if specified domain is found in current block-list'
+ extra_command 'check_lists' 'Checks if specified domain is found in enabled block-lists'
+ extra_command 'dl' 'Force-downloads all enabled block-list'
+ extra_command 'killcache' 'Delete all cached files'
+ extra_command 'pause' 'Pauses AdBlocking for specified number of seconds (default: 60)'
+ extra_command 'sizes' 'Displays the file-sizes of enabled block-lists'
+ extra_command 'version' 'Show version information'
+else
+# shellcheck disable=SC2034
+ EXTRA_COMMANDS='allow check dl killcache pause sizes status_service version'
+# shellcheck disable=SC2034
+ EXTRA_HELP=' allow Allows domain(s) in current block-list and config
+ check Checks if specified domain is found in current block-list
+ dl Force-downloads all enabled block-list
+ pause Pauses AdBlocking for specified number of seconds (default: 60)
+ sizes Displays the file-sizes of enabled block-lists'
+fi
get_text() {
local r
errorCreatingDirectory) r="failed to create output/cache/gzip file directory";;
errorDetectingFileType) r="failed to detect format";;
errorNothingToDo) r="no blocked list URLs nor blocked-domains enabled";;
+ errorTooLittleRam) r="free ram (%s) is not enough to process all enabled block-lists";;
statusNoInstall) r="$serviceName is not installed or not found";;
statusStopped) r="Stopped";;
statusForceReloading) r="Force Reloading";;
statusDownloading) r="Downloading";;
statusProcessing) r="Processing";;
- statusError) r="Error";;
- statusWarning) r="Warning";;
- statusFail) r="Fail";;
+ statusFail) r="failed to start";;
statusSuccess) r="Success";;
warningExternalDnsmasqConfig)
r="use of external dnsmasq config file detected, please set 'dns' option to 'dnsmasq.conf'";;
- warningMissingRecommendedPackages) r="Some recommended packages are missing";;
+ warningMissingRecommendedPackages) r="some recommended packages are missing";;
warningInvalidCompressedCacheDir) r="invalid compressed cache directory '%s'";;
+ warningFreeRamCheckFail) r="can't detect free RAM";;
esac
- echo "$r"
-}
-
-output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; }
-output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; }
-output_fail() { output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; }
-output_failn() { output 1 "$_FAIL_\\n"; output 2 "$__FAIL__\\n"; }
-str_replace() { printf "%b" "$1" | sed -e "s/$(printf "%b" "$2")/$(printf "%b" "$3")/g"; }
-str_contains() { test "$1" != "$(str_replace "$1" "$2" '')"; }
-is_greater() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
-is_greater_or_equal() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" = "$2"; }
-is_chaos_calmer() { ubus -S call system board | grep -q 'Chaos Calmer'; }
-led_on(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'default-on' > "${1}/trigger" 2>&1; fi; }
-led_off(){ if [ -n "${1}" ] && [ -e "${1}/trigger" ]; then echo 'none' > "${1}/trigger" 2>&1; fi; }
-dnsmasq_hup() { killall -q -s HUP dnsmasq; }
-dnsmasq_kill() { killall -q -s KILL dnsmasq; }
-dnsmasq_restart() { /etc/init.d/dnsmasq restart >/dev/null 2>&1; }
-unbound_restart() { /etc/init.d/unbound restart >/dev/null 2>&1; }
-is_present() { command -v "$1" >/dev/null 2>&1; }
-sanitize_dir() { [ -d "$(readlink -fn "$1")" ] && readlink -fn "$1"; }
-
-output() {
-# Can take a single parameter (text) to be output at any verbosity
-# Or target verbosity level and text to be output at specifc verbosity
- local msg memmsg logmsg
- local sharedMemoryOutput="/dev/shm/$packageName-output"
- verbosity="${verbosity:-2}"
- if [ $# -ne 1 ]; then
- if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; else return 0; fi
- fi
- [ -t 1 ] && printf "%b" "$1"
- msg="${1//$serviceName /service }";
- if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then
- [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")"
- logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')"
- logger -t "${packageName:-service} [$$]" "$(printf "%b" "$logmsg")"
- rm -f "$sharedMemoryOutput"
- else
- printf "%b" "$msg" >> "$sharedMemoryOutput"
- fi
+ shift
+# shellcheck disable=SC2059
+ printf "$r" "$@"
}
load_network() {
local param="$1"
- local i j wan_if wan_gw wan_proto
+ local i j wan_if wan_gw
local counter wan_if_timeout="$procd_boot_wan_timeout" wan_gw_timeout='5'
counter=0
while [ -z "$wan_if" ]; do
done
counter=0
- wan_proto="$(uci -q get "network.${wan_if}.proto")"
- if [ "$wan_proto" = 'pppoe' ]; then
+ if [ "$(uci_get_protocol "$wan_if")" = 'pppoe' ]; then
wan_gw_timeout=$((wan_gw_timeout+10))
fi
while [ "$counter" -le "$wan_gw_timeout" ]; do
output "Waiting to discover $wan_if gateway...\\n"
sleep 1
done
- json add error "errorNoWanGateway"
+ json add error 'errorNoWanGateway'
output "${_ERROR_}: $(get_text 'errorNoWanGateway')!\\n"; return 1;
}
append_url() {
local cfg="$1" var="$2"
local en action url
- config_get en "$cfg" enabled '1'
+ config_get_bool en "$cfg" enabled '1'
config_get action "$cfg" action 'block'
config_get url "$cfg" url
if [ "$en" = '1' ]; then
fi
}
- detect_file_type() {
- local file="$1"
- if [ "$(head -1 "$file")" = '[Adblock Plus]' ] || \
- grep -q '^||' "$file"; then
- echo 'adblockplus'
- elif grep -q '^server=' "$file"; then
- echo 'dnsmasq'
- elif grep -q '^local=' "$file"; then
- echo 'dnsmasq2'
- elif grep -q '^address=' "$file"; then
- echo 'dnsmasq3'
- elif grep -q '^0\.0\.0\.0' "$file" || grep -q '^127\.0\.0\.1' "$file"; then
- echo 'hosts'
- elif [ -n "$(sed "$domainsFilter" "$file" | head -1)" ]; then
- echo 'domains'
- fi
- }
-# detect_file_type() {
-# local file="$1"
-# if [ -n "$(sed "$adBlockPlusFilter" "$file" | head -1)" ]; then
-# echo 'adblockplus'
-# elif [ -n "$(sed "$dnsmasqFileFilter" "$file" | head -1)" ]; then
-# echo 'dnsmasq'
-# elif [ -n "$(sed "$dnsmasq2FileFilter" "$file" | head -1)" ]; then
-# echo 'dnsmasq2'
-# elif [ -n "$(sed "$hostsFilter" "$file" | head -1)" ]; then
-# echo 'hosts'
-# elif [ -n "$(sed "$domainsFilter" "$file" | head -1)" ]; then
-# echo 'domains'
-# fi
-# }
+detect_file_type() {
+ local file="$1"
+ if [ "$(head -1 "$file")" = '[Adblock Plus]' ] || \
+ grep -q '^||' "$file"; then
+ echo 'adblockplus'
+ elif grep -q '^server=' "$file"; then
+ echo 'dnsmasq'
+ elif grep -q '^local=' "$file"; then
+ echo 'dnsmasq2'
+ elif grep -q '^address=' "$file"; then
+ echo 'dnsmasq3'
+ elif grep -q '^0\.0\.0\.0' "$file" || grep -q '^127\.0\.0\.1' "$file"; then
+ echo 'hosts'
+ elif [ -n "$(sed "$domainsFilter" "$file" | head -1)" ]; then
+ echo 'domains'
+ fi
+}
load_environment() {
local i j
[ -z "$load_environment_flag" ] || return 0
if [ "$validation_result" != '0' ]; then
- json add error "errorConfigValidationFail"
+ json add error 'errorConfigValidationFail'
output "${_ERROR_}: $(get_text 'errorConfigValidationFail')!\\n"
output "Please check if the '$packageConfigFile' contains correct values for config options.\\n"
return 1
fi
if [ "$enabled" -eq 0 ]; then
- json add error "errorServiceDisabled"
+ json add error 'errorServiceDisabled'
output "${_ERROR_}: $(get_text 'errorServiceDisabled')!\\n"
output "Run the following commands before starting service again:\\n"
output "uci set ${packageName}.config.enabled='1'; uci commit $packageName;\\n"
return 1
fi
- if [ "$debug" -ne 0 ]; then
+ if [ "$debug" -ne '0' ]; then
exec 1>>"/tmp/$packageName.log"
exec 2>&1
set -x
fi
+# TODO: check for resolver and error out on start
+
if [ -n "$dnsmasq_config_file_url" ]; then
case "$dns" in
dnsmasq.conf) :;;
*)
if [ "$param" != 'quiet' ]; then
- json add warning "warningExternalDnsmasqConfig"
+ json add warning 'warningExternalDnsmasqConfig'
output "${_WARNING_}: $(get_text 'warningExternalDnsmasqConfig')!\\n"
fi
;;
fi
case "$dns" in
- dnsmasq.addnhosts|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|dnsmasq.servers)
+ dnsmasq.*)
if dnsmasq -v 2>/dev/null | grep -q 'no-IDN' || ! dnsmasq -v 2>/dev/null | grep -q -w 'IDN'; then
- allow_non_ascii=0
+ allow_non_ascii='0'
fi
;;
- unbound.adb_list)
- allow_non_ascii=1;;
+ smartdns.*)
+ allow_non_ascii='0'
+ ;;
+ unbound.*)
+ allow_non_ascii='1'
+ ;;
esac
case "$dns" in
dnsmasq.ipset)
if dnsmasq -v 2>/dev/null | grep -q 'no-ipset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'ipset'; then
if [ "$param" != 'quiet' ]; then
- json add error "errorNoDnsmasqIpset"
+ json add error 'errorNoDnsmasqIpset'
output "${_ERROR_}: $(get_text 'errorNoDnsmasqIpset')!\\n"
fi
dns='dnsmasq.servers'
fi
if ! ipset help hash:net; then
if [ "$param" != 'quiet' ]; then
- json add error "errorNoIpset"
+ json add error 'errorNoIpset'
output "${_ERROR_}: $(get_text 'errorNoIpset')!\\n"
fi
dns='dnsmasq.servers'
dnsmasq.nftset)
if dnsmasq -v 2>/dev/null | grep -q 'no-nftset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'nftset'; then
if [ "$param" != 'quiet' ]; then
- json add error "errorNoDnsmasqNftset"
+ json add error 'errorNoDnsmasqNftset'
output "${_ERROR_}: $(get_text 'errorNoDnsmasqNftset')!\\n"
fi
dns='dnsmasq.servers'
fi
if [ -z "$nft" ]; then
if [ "$param" != 'quiet' ]; then
- json add error "errorNoNft"
+ json add error 'errorNoNft'
output "${_ERROR_}: $(get_text 'errorNoNft')!\\n"
fi
dns='dnsmasq.servers'
fi
;;
+ smartdns.ipset)
+ if ! ipset help hash:net; then
+ if [ "$param" != 'quiet' ]; then
+ json add error 'errorNoIpset'
+ output "${_ERROR_}: $(get_text 'errorNoIpset')!\\n"
+ fi
+ dns='smartdns.domainset'
+ fi
+ ;;
+ smartdns.nftset)
+ if [ -z "$nft" ]; then
+ if [ "$param" != 'quiet' ]; then
+ json add error 'errorNoNft'
+ output "${_ERROR_}: $(get_text 'errorNoNft')!\\n"
+ fi
+ dns='smartdns.domainset'
+ fi
+ ;;
esac
if [ "$(sanitize_dir "$compressed_cache_dir")" = '/' ]; then
compressed_cache_dir="$(sanitize_dir "$compressed_cache_dir")"
else
json add warning 'warningInvalidCompressedCacheDir' "$compressed_cache_dir"
+ output "${_WARNING_}: $(get_text 'warningInvalidCompressedCacheDir' "$compressed_cache_dir")!\\n"
compressed_cache_dir="/etc"
fi
outputFile="$dnsmasqAddnhostsFile"
outputCache="$dnsmasqAddnhostsCache"
outputGzip="${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
- if [ "$ipv6_enabled" -ne 0 ]; then
+ if [ "$ipv6_enabled" -ne '0' ]; then
outputFilterIPv6="$dnsmasqAddnhostsFilterIPv6"
fi
- rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
- rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
- rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
- rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
- rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
;;
dnsmasq.conf)
outputFilter="$dnsmasqConfFilter"
outputFile="$dnsmasqConfFile"
outputCache="$dnsmasqConfCache"
outputGzip="${compressed_cache_dir}/${dnsmasqConfGzip}"
- rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
- rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
- rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
- rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
- rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
;;
dnsmasq.ipset)
outputFilter="$dnsmasqIpsetFilter"
outputFile="$dnsmasqIpsetFile"
outputCache="$dnsmasqIpsetCache"
outputGzip="${compressed_cache_dir}/${dnsmasqIpsetGzip}"
- rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
- rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
- rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
- rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
- rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
;;
dnsmasq.nftset)
- if [ "$ipv6_enabled" -ne 0 ]; then
+ if [ "$ipv6_enabled" -ne '0' ]; then
outputFilter="$dnsmasqNftsetFilterIPv6"
else
outputFilter="$dnsmasqNftsetFilter"
outputFile="$dnsmasqNftsetFile"
outputCache="$dnsmasqNftsetCache"
outputGzip="${compressed_cache_dir}/${dnsmasqNftsetGzip}"
- rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
- rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
- rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
- rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
- rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
;;
dnsmasq.servers)
outputFilter="$dnsmasqServersFilter"
outputFile="$dnsmasqServersFile"
outputCache="$dnsmasqServersCache"
outputGzip="${compressed_cache_dir}/${dnsmasqServersGzip}"
- rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
- rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
- rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
- rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
- rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
+ ;;
+ smartdns.domainset)
+ outputFilter="$smartdnsDomainSetFilter"
+ outputFile="$smartdnsDomainSetFile"
+ outputCache="$smartdnsDomainSetCache"
+ outputGzip="${compressed_cache_dir}/${smartdnsDomainSetGzip}"
+ outputConfig="$smartdnsDomainSetConfig"
+ ;;
+ smartdns.ipset)
+ outputFilter="$smartdnsIpsetFilter"
+ outputFile="$smartdnsIpsetFile"
+ outputCache="$smartdnsIpsetCache"
+ outputGzip="${compressed_cache_dir}/${smartdnsIpsetGzip}"
+ outputConfig="$smartdnsIpsetConfig"
+ ;;
+ smartdns.nftset)
+ outputFilter="$smartdnsNftsetFilter"
+ outputFile="$smartdnsNftsetFile"
+ outputCache="$smartdnsNftsetCache"
+ outputGzip="${compressed_cache_dir}/${smartdnsNftsetGzip}"
+ outputConfig="$smartdnsNftsetConfig"
;;
unbound.adb_list)
outputFilter="$unboundFilter"
outputFile="$unboundFile"
outputCache="$unboundCache"
outputGzip="$unboundGzip"
- rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
- rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
- rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
- rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
- rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
;;
esac
- for i in "$jsonFile" "$outputFile" "$outputCache" "$outputGzip"; do
+ [ "$dns" = 'dnsmasq.addnhosts' ] || rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
+ [ "$dns" = 'dnsmasq.conf' ] || rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
+ [ "$dns" = 'dnsmasq.ipset' ] || rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
+ [ "$dns" = 'dnsmasq.nftset' ] || rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
+ [ "$dns" = 'dnsmasq.servers' ] || rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
+ [ "$dns" = 'smartdns.domainset' ] || rm -f "$smartdnsDomainSetFile" "$smartdnsDomainSetCache" "${compressed_cache_dir}/${smartdnsDomainSetGzip}" "$smartdnsDomainSetConfig"
+ [ "$dns" = 'smartdns.ipset' ] || rm -f "$smartdnsIpsetFile" "$smartdnsIpsetCache" "${compressed_cache_dir}/${smartdnsIpsetGzip}" "$smartdnsIpsetConfig"
+ [ "$dns" = 'smartdns.nftset' ] || rm -f "$smartdnsNftsetFile" "$smartdnsNftsetCache" "${compressed_cache_dir}/${smartdnsNftsetGzip}" "$smartdnsNftsetConfig"
+ [ "$dns" = 'unbound.adb_list' ] || rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
+
+ for i in "$jsonFile" "$outputFile" "$outputCache" "$outputGzip" "$outputConfig"; do
+ [ -n "$i" ] || continue
if ! mkdir -p "$(dirname "$i")"; then
if [ "$param" != 'quiet' ]; then
- json add error "errorOutputDirCreate" "$i"
+ json add error 'errorOutputDirCreate' "$i"
output "${_ERROR_}: $(get_text 'errorOutputDirCreate' "$i")!\\n"
fi
fi
is_present 'gawk' && awk='gawk'
if ! is_present '/usr/libexec/grep-gnu' || ! is_present '/usr/libexec/sed-gnu' || \
! is_present '/usr/libexec/sort-coreutils' || ! is_present 'gawk'; then
- local s="opkg update; opkg --force-overwrite install"
- is_present 'gawk' || s="$s gawk"
- is_present '/usr/libexec/grep-gnu' || s="$s grep"
- is_present '/usr/libexec/sed-gnu' || s="$s sed"
- is_present '/usr/libexec/sort-coreutils' || s="$s coreutils-sort"
+ local s
+ is_present 'gawk' || s="${s:+$s }gawk"
+ is_present '/usr/libexec/grep-gnu' || s="${s:+$s }grep"
+ is_present '/usr/libexec/sed-gnu' || s="${s:+$s }sed"
+ is_present '/usr/libexec/sort-coreutils' || s="${s:+$s }coreutils-sort"
if [ "$param" != 'quiet' ]; then
- json add warning "warningMissingRecommendedPackages" "${i}"
+ json add warning 'warningMissingRecommendedPackages' "$s"
output "${_WARNING_}: $(get_text 'warningMissingRecommendedPackages'), install them by running:\\n"
- output "$s;\\n"
+ output "opkg update; opkg --force-overwrite install $s;\\n"
fi
fi
# Prefer curl because it supports the file:// scheme.
fi
}
-get_url_filesize() {
- local url="$1" size size_command
- [ -n "$url" ] || return 0
- is_present 'curl' || return 0
- size_command='curl --silent --insecure --fail --head --request GET'
- size="$($size_command "$url" | grep -Po '^[cC]ontent-[lL]ength: \K\w+')"
- echo -en "$size"
-}
-
-get_local_filesize() {
- local file="$1" size
- [ -f "$file" ] || return 0
- if is_present stat; then
- size="$(stat -c%s "$file")"
- elif is_present wc; then
- size="$(wc -c < "$file")"
- fi
- echo -en "$size"
-}
-
-resolver_config() {
- local cfg="$1" param="$2"
- case "$param" in
- dnsmasq.addnhosts)
- if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" = "$dnsmasqServersFile" ]; then
- uci_remove 'dhcp' "$cfg" 'serversfile'
- fi
- uci_add_list_if_new 'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
- ;;
- cleanup|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|unbound.adb_list)
- uci_remove_list 'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
- if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" = "$dnsmasqServersFile" ]; then
- uci_remove 'dhcp' "$cfg" 'serversfile'
+resolver() {
+ _dnsmasq_instance_config() {
+ local cfg="$1" param="$2"
+ [ -s "/etc/config/dhcp" ] || return 0
+ case "$param" in
+ dnsmasq.addnhosts)
+ if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" = "$dnsmasqServersFile" ]; then
+ uci_remove 'dhcp' "$cfg" 'serversfile'
+ fi
+ uci_add_list_if_new 'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
+ ;;
+ cleanup|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|unbound.adb_list)
+ uci_remove_list 'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
+ if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" = "$dnsmasqServersFile" ]; then
+ uci_remove 'dhcp' "$cfg" 'serversfile'
+ fi
+ ;;
+ dnsmasq.servers)
+ uci_remove_list 'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
+ if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" != "$dnsmasqServersFile" ]; then
+ uci_set 'dhcp' "$cfg" 'serversfile' "$dnsmasqServersFile"
+ fi
+ ;;
+ esac
+ }
+ _smartdns_instance_config() {
+ [ -s "/etc/config/smartdns" ] || return 0
+ local cfg="$1" param="$2"
+ case "$param" in
+ cleanup)
+ uci_remove_list 'smartdns' "$cfg" 'conf_files' "$outputConfig"
+ rm -f "$outputConfig"
+ ;;
+ smartdns.domainset)
+ { echo "domain-set -name adblock-fast -file $outputFile"; \
+ echo "domain-rules /domain-set:adblock-fast/ -a #"; } > "$outputConfig"
+ uci_add_list_if_new 'smartdns' "$cfg" 'conf_files' "$outputConfig"
+ ;;
+ smartdns.ipset)
+ { echo "domain-set -name adblock-fast -file $outputFile"; \
+ echo "domain-rules /domain-set:adblock-fast/ -ipset adb"; } > "$outputConfig"
+ uci_add_list_if_new 'smartdns' "$cfg" 'conf_files' "$outputConfig"
+ ;;
+ smartdns.nftset)
+ local nftset="#4:inet#fw4#adb4"
+ [ "$ipv6_enabled" -ne '0' ] && nftset="${nftset},#6:inet#fw4#adb6"
+ { echo "domain-set -name adblock-fast -file $outputFile"; \
+ echo "domain-rules /domain-set:adblock-fast/ -nftset $nftset"; } > "$outputConfig"
+ uci_add_list_if_new 'smartdns' "$cfg" 'conf_files' "$outputConfig"
+ ;;
+ esac
+ }
+
+ local param output_text i
+ case $1 in
+ cleanup)
+ rm -f "$dnsmasqAddnhostsFile" "$dnsmasqAddnhostsCache" "${compressed_cache_dir}/${dnsmasqAddnhostsGzip}"
+ rm -f "$dnsmasqConfFile" "$dnsmasqConfCache" "${compressed_cache_dir}/${dnsmasqConfGzip}"
+ rm -f "$dnsmasqIpsetFile" "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
+ rm -f "$dnsmasqNftsetFile" "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
+ rm -f "$dnsmasqServersFile" "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
+ rm -f "$smartdnsDomainSetFile" "$smartdnsDomainSetCache" "${compressed_cache_dir}/${smartdnsDomainSetGzip}" "$smartdnsDomainSetConfig"
+ rm -f "$smartdnsIpsetFile" "$smartdnsIpsetCache" "${compressed_cache_dir}/${smartdnsIpsetGzip}" "$smartdnsIpsetConfig"
+ rm -f "$smartdnsNftsetFile" "$smartdnsNftsetCache" "${compressed_cache_dir}/${smartdnsNftsetGzip}" "$smartdnsNftsetConfig"
+ rm -f "$unboundFile" "$unboundCache" "$unboundGzip"
+ if [ -s "/etc/config/dhcp" ]; then
+ config_load 'dhcp'
+ config_foreach _dnsmasq_instance_config 'dnsmasq' 'cleanup'
+ [ -n "$(uci_changes 'dhcp')" ] && uci_commit 'dhcp'
fi
- ;;
- dnsmasq.servers)
- uci_remove_list 'dhcp' "$cfg" 'addnhosts' "$dnsmasqAddnhostsFile"
- if [ "$(uci_get 'dhcp' "$cfg" 'serversfile')" != "$dnsmasqServersFile" ]; then
- uci_set 'dhcp' "$cfg" 'serversfile' "$dnsmasqServersFile"
+ if [ -s "/etc/config/smartdns" ]; then
+ config_load 'smartdns'
+ config_foreach _smartdns_instance_config 'smartdns' 'cleanup'
+ [ -n "$(uci_changes 'smartdns')" ] && uci_commit 'smartdns'
fi
;;
- esac
-}
-
-dns() {
- local param output_text i
- case $1 in
on_start)
if [ ! -s "$outputFile" ]; then
- json set status "statusFail"
- json add error "errorOutputFileCreate"
+ json set status 'statusFail'
+ json add error 'errorOutputFileCreate'
output "${_ERROR_}: $(get_text 'errorOutputFileCreate')!\\n"
return 1
fi
config_load 'dhcp'
if [ "$dnsmasq_instance" = "*" ]; then
- config_foreach resolver_config 'dnsmasq' "$dns"
+ config_foreach _dnsmasq_instance_config 'dnsmasq' "$dns"
elif [ -n "$dnsmasq_instance" ]; then
for i in $dnsmasq_instance; do
- resolver_config "@dnsmasq[$i]" "$dns" || resolver_config "$i" "$dns"
+ _dnsmasq_instance_config "@dnsmasq[$i]" "$dns" || _dnsmasq_instance_config "$i" "$dns"
+ done
+ fi
+ config_load 'smartdns'
+ if [ "$smartdns_instance" = "*" ]; then
+ config_foreach _smartdns_instance_config 'smartdns' "$dns"
+ elif [ -n "$smartdns_instance" ]; then
+ for i in $smartdns_instance; do
+ _smartdns_instance_config "@smartdns[$i]" "$dns" || _smartdns_instance_config "$i" "$dns"
done
fi
case "$dns" in
- dnsmasq.addnhosts|dnsmasq.servers)
- chmod 660 "$outputFile"
- chown root:dnsmasq "$outputFile"
- param=dnsmasq_restart
- output_text='Reloading dnsmasq'
- ;;
- dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset)
+ dnsmasq.*)
chmod 660 "$outputFile"
chown root:dnsmasq "$outputFile"
- param=dnsmasq_restart
+ param='dnsmasq_restart'
output_text='Restarting dnsmasq'
;;
- unbound.adb_list)
- param=unbound_restart
+ smartdns.*)
+ chmod 660 "$outputFile" "$outputConfig"
+ chown root:root "$outputFile" "$outputConfig"
+ param='smartdns_restart'
+ output_text='Restarting SmartDNS'
+ ;;
+ unbound.*)
+ chmod 660 "$outputFile"
+ chown root:unbound "$outputFile"
+ param='unbound_restart'
output_text='Restarting Unbound'
;;
esac
- if [ -n "$(uci_changes dhcp)" ]; then
- uci_commit dhcp
- if [ "$param" = 'unbound_restart' ]; then
- param='dnsmasq_restart; unbound_restart;'
- output_text='Restarting Unbound/dnsmasq'
- else
- param=dnsmasq_restart
- output_text='Restarting dnsmasq'
+ if [ -n "$(uci_changes dhcp)" ]; then
+ uci_commit 'dhcp'
+ if ! str_contains "$param" 'dnsmasq_restart'; then
+ param="${param:+"$param; dnsmasq_restart"}"
+ output_text="${output_text}/dnsmasq"
+ fi
+ fi
+ if [ -n "$(uci_changes smartdns)" ]; then
+ uci_commit 'smartdns'
+ if ! str_contains "$param" 'smartdns_restart'; then
+ param="${param:+"$param; "}smartdns_restart"
+ output_text="${output_text}/smartDNS"
fi
fi
output 1 "$output_text "
output 2 "$output_text "
json set message "$output_text"
if eval "$param"; then
- json set status "statusSuccess"
+ json set status 'statusSuccess'
led_on "$led"
output_okn
else
output_fail
- json set status "statusFail"
- json add error "errorDNSReload"
+ json set status 'statusFail'
+ json add error 'errorDNSReload'
output "${_ERROR_}: $(get_text 'errorDNSReload')!\\n"
return 1
fi
;;
on_stop)
case "$dns" in
- dnsmasq.addnhosts|dnsmasq.servers)
- param=dnsmasq_restart
+ dnsmasq.*)
+ param='dnsmasq_restart'
;;
- dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset)
- param=dnsmasq_restart
+ smartdns.*)
+ param='smartdns_restart'
;;
- unbound.adb_list)
- param=unbound_restart
+ unbound.*)
+ param='unbound_restart'
;;
esac
if [ -n "$(uci_changes dhcp)" ]; then
- uci_commit dhcp
- if [ "$param" = 'unbound_restart' ]; then
- param='dnsmasq_restart; unbound_restart;'
- else
- param=dnsmasq_restart
- fi
+ uci_commit 'dhcp'
+ str_contains "$param" 'dnsmasq_restart' || param="${param:+"$param; dnsmasq_restart"}"
+ fi
+ if [ -n "$(uci_changes smartdns)" ]; then
+ uci_commit 'smartdns'
+ str_contains "$param" 'smartdns_restart' || param="${param:+"$param; "}smartdns_restart"
fi
eval "$param"
return $?
;;
- quiet)
+ quiet|quiet_restart)
case "$dns" in
- dnsmasq.addnhosts|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|dnsmasq.servers)
- param=dnsmasq_restart
+ dnsmasq.*)
+ param='dnsmasq_restart'
+ ;;
+ smartdns.*)
+ param='smartdns_restart'
;;
- unbound.adb_list)
- param=unbound_restart
+ unbound.*)
+ param='unbound_restart'
;;
esac
eval "$param"
esac
}
-json() {
-# shellcheck disable=SC2034
- local action="$1" param="$2" value="$3"
- shift 3
-# shellcheck disable=SC2124
- local extras="$@" line
- local status message error stats
- local reload restart curReload curRestart ret i
- if [ -s "$jsonFile" ]; then
- json_load_file "$jsonFile" 2>/dev/null
- json_select 'data' 2>/dev/null
- for i in status message error stats reload restart; do
- json_get_var "$i" "$i" 2>/dev/null
- done
- fi
- case "$action" in
- get)
- case "$param" in
- triggers)
- curReload="$parallel_downloads $debug $download_timeout \
- $allowed_domain $blocked_domain $allowed_url $blocked_url $dns \
- $config_update_enabled $config_update_url $dnsmasq_config_file_url \
- $curl_additional_param $curl_max_file_size $curl_retry"
- curRestart="$compressed_cache $compressed_cache_dir $force_dns $led \
- $force_dns_port"
- if [ ! -s "$jsonFile" ]; then
- ret='on_boot'
- elif [ "$curReload" != "$reload" ]; then
- ret='download'
- elif [ "$curRestart" != "$restart" ]; then
- ret='restart'
- fi
- printf "%b" "$ret"
- return;;
- *)
- printf "%b" "$(eval echo "\$$param")"; return;;
- esac
- ;;
- add)
- line="$(eval echo "\$$param")"
- eval "$param"='${line:+$line }${value}${extras:+|$extras}'
- ;;
- del)
- case "$param" in
- all)
- unset status message error stats;;
- triggers)
- unset reload restart;;
- *)
- unset "$param";;
- esac
- ;;
- set)
- case "$param" in
- triggers)
- reload="$parallel_downloads $debug $download_timeout \
- $allowed_domain $blocked_domain $allowed_url $blocked_url $dns \
- $config_update_enabled $config_update_url $dnsmasq_config_file_url \
- $curl_additional_param $curl_max_file_size $curl_retry"
- restart="$compressed_cache $compressed_cache_dir $force_dns $led \
- $force_dns_port"
- ;;
- *)
- eval "$param"='${value}${extras:+|$extras}';;
- esac
- ;;
- esac
- json_init
- json_add_object 'data'
- json_add_string version "$PKG_VERSION"
- json_add_string status "$status"
- json_add_string message "$message"
- json_add_string error "$error"
- json_add_string stats "$stats"
- json_add_string reload "$reload"
- json_add_string restart "$restart"
- json_close_object
- mkdir -p "$(dirname "$jsonFile")"
- json_dump > "$jsonFile"
- sync
-}
-
cache() {
local R_TMP
case "$1" in
esac
}
-_process_file_url() {
+process_file_url_wrapper() {
if [ "$2" != '0' ]; then
- json add error "errorConfigValidationFail"
+ json add error 'errorConfigValidationFail'
output "${_ERROR_}: $(get_text 'errorConfigValidationFail')!\\n"
output "Please check if the '$packageConfigFile' contains correct values for config options.\\n"
fi
file) type='File'; D_TMP="$B_TMP"
;;
esac
- if [ "${1:0:5}" = "https" ] && [ -z "$isSSLSupported" ]; then
+ if is_https_url "$url" && [ -z "$isSSLSupported" ]; then
output 1 "$_FAIL_"
output 2 "[DL] $type $label $__FAIL__\\n"
echo "errorNoSSLSupport|${1}" >> "$sharedMemoryError"
output 2 "[DL] $type $label $__FAIL__\\n"
echo "errorDownloadingList|${url}" >> "$sharedMemoryError"
else
+ append_newline "$R_TMP"
[ -n "$cfg" ] && new_size="$(get_local_filesize "$R_TMP")"
if [ -n "$new_size" ] && [ "$size" != "$new_size" ]; then
- uci set "${packageName}.${cfg}.size=$size"
+ uci_set "$packageName" "$cfg" 'size' "$size"
fi
format="$(detect_file_type "$R_TMP")"
case "$format" in
output 2 "[DL] $type $label ($format) $__FAIL__\\n"
echo "errorParsingList|${url}" >> "$sharedMemoryError"
else
+ append_newline "$R_TMP"
cat "${R_TMP}" >> "$D_TMP"
output 1 "$_OK_"
output 2 "[DL] $type $label ($format) $__OK__\\n"
}
download_dnsmasq_file() {
- local hf allow_filter j=0 R_TMP
+ json set message "$(get_text 'statusDownloading')..."
+ json set status 'statusDownloading'
- json set message "$(get_text "statusDownloading")..."
- json set status "statusDownloading"
-
- rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip"
- if [ "$($awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo")" -lt 32 ]; then
+ rm -f "$A_TMP" "$B_TMP" "$SED_TMP" "$outputFile" "$outputCache" "$outputGzip"
+ if [ "$(get_ram_free)" -lt 32 ]; then
output 3 'Low free memory, restarting resolver '
- if dns 'quiet'; then
+ if resolver 'quiet_restart'; then
output_okn
else
output_failn
fi
fi
- touch $A_TMP; touch $B_TMP;
+ touch "$A_TMP" "$B_TMP" "$SED_TMP"
output 1 'Downloading dnsmasq file '
rm -f "$sharedMemoryError"
process_file_url '' "$dnsmasq_config_file_url" 'file'
output 2 "$__OK__\\n"
else
output 2 "$__FAIL__\\n"
- json add error "errorMovingDataFile"
+ json add error 'errorMovingDataFile'
fi
output 1 '\n'
}
download_lists() {
- local hf allow_filter j=0 R_TMP
+ _ram_check() {
+ _config_calculate_sizes() {
+ local cfg="$1"
+ local en size url
+ config_get_bool en "$cfg" enabled '1'
+ config_get size "$cfg" size
+ config_get url "$cfg" url
+ [ "$en" = '0' ] && return 0
+ [ -n "$size" ] || size="$(get_url_filesize "$url")"
+ [ -n "$size" ] && total_sizes=$((total_sizes+size))
+ }
+ local i free_mem total_sizes
+ free_mem="$(get_ram_free)"
+ if [ -z "$free_mem" ]; then
+ json add warnning 'warningFreeRamCheckFail'
+ output "${_WARNING_}: $(get_text 'warningFreeRamCheckFail')!\\n"
+ return 0
+ fi
+ config_load "$packageName"
+ config_foreach _config_calculate_sizes 'file_url'
+ if [ $((free_mem)) -lt $((total_sizes * 2)) ]; then
+ json add error 'errorTooLittleRam' "$free_mem"
+ output "${_ERROR_}: $(get_text 'errorTooLittleRam' "$free_mem")!\\n"
+ return 1
+ else
+ return 0
+ fi
+ }
+ local hf j=0 R_TMP
- json set message "$(get_text "statusDownloading")..."
- json set status "statusDownloading"
+ _ram_check || return 1
- rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip"
- if [ "$($awk '/^MemFree/ {print int($2/1000)}' "/proc/meminfo")" -lt 32 ]; then
+ json set message "$(get_text 'statusDownloading')..."
+ json set status 'statusDownloading'
+
+ rm -f "$A_TMP" "$B_TMP" "$SED_TMP" "$outputFile" "$outputCache" "$outputGzip"
+ if [ "$(get_ram_total)" -lt 33554432 ]; then
output 3 'Low free memory, restarting resolver '
- if dns 'quiet'; then
+ if resolver 'quiet_restart'; then
output_okn
else
output_failn
fi
fi
- touch $A_TMP; touch $B_TMP;
+ touch "$A_TMP" "$B_TMP" "$SED_TMP"
output 1 'Downloading lists '
rm -f "$sharedMemoryError"
config_load "$packageName"
- config_foreach load_validate_file_url_section 'file_url' _process_file_url
+ config_foreach load_validate_file_url_section 'file_url' process_file_url_wrapper
wait
- if [ -n "$(uci changes "$packageName")" ]; then
+ if [ -n "$(uci_changes "$packageName")" ]; then
output 2 "Saving updated file size(s) "
- uci commit "$packageName" && output_okn || output_failn
+ if uci_commit "$packageName"; then output_okn; else output_failn; fi
fi
output 1 '\n'
rm -f "$sharedMemoryError"
fi
- if [ "$canary_domains_icloud" -ne 0 ]; then
+ if [ "$canary_domains_icloud" -ne '0' ]; then
canaryDomains="${canaryDomains:+$canaryDomains }${canaryDomainsiCloud}"
fi
- if [ "$canary_domains_mozilla" -ne 0 ]; then
+ if [ "$canary_domains_mozilla" -ne '0' ]; then
canaryDomains="${canaryDomains:+$canaryDomains }${canaryDomainsMozilla}"
fi
- for hf in $blocked_domain $canaryDomains; do echo "$hf" | sed "$domainsFilter" >> $B_TMP; done
+ append_newline "$B_TMP"
+ for hf in $blocked_domain $canaryDomains; do
+ printf "%s\n" "$(echo "$hf" | sed "$domainsFilter")" >> "$B_TMP"
+ done
allowed_domain="${allowed_domain}
-$(cat $A_TMP)"
- for hf in ${allowed_domain}; do hf="$(echo "$hf" | sed 's/\./\\./g')"; allow_filter="$allow_filter/(^|\.)${hf}$/d;"; done
+$(sed '/^[[:space:]]*$/d' "$A_TMP")"
+ for hf in ${allowed_domain}; do
+ hf="$(echo "$hf" | sed 's/\./\\./g')"
+ echo "/(^|\.)${hf}$/d;" >> "$SED_TMP"
+ done
+ sed -i '/^[[:space:]]*$/d' "$B_TMP"
[ ! -s "$B_TMP" ] && return 1
output 1 'Processing downloads '
output 2 'Sorting combined list '
- json set status "statusProcessing"
- json set message "$(get_text "statusProcessing"): sorting combined list"
+ json set status 'statusProcessing'
+ json set message "$(get_text 'statusProcessing'): sorting combined list"
if [ "$allow_non_ascii" -gt 0 ]; then
if sort -u "$B_TMP" > "$A_TMP"; then
output_ok
else
output_failn
- json add error "errorSorting"
+ json add error 'errorSorting'
fi
else
if sort -u "$B_TMP" | grep -E -v '[^a-zA-Z0-9=/.-]' > "$A_TMP"; then
output_ok
else
output_failn
- json add error "errorSorting"
+ json add error 'errorSorting'
fi
fi
[ "$dns" = 'dnsmasq.ipset' ] || \
[ "$dns" = 'dnsmasq.nftset' ] || \
[ "$dns" = 'dnsmasq.servers' ] || \
+ [ "$dns" = 'smartdns.domainset' ] || \
+ [ "$dns" = 'smartdns.ipset' ] || \
+ [ "$dns" = 'smartdns.nftset' ] || \
[ "$dns" = 'unbound.adb_list' ]; then
# TLD optimization written by Dirk Brenken (dev@brenken.org)
output 2 'Optimizing combined list '
- json set message "$(get_text "statusProcessing"): optimizing combined list"
+ json set message "$(get_text 'statusProcessing'): optimizing combined list"
# sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/' is actually slower than command below
+# shellcheck disable=SC2016
if $awk -F "." '{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "$A_TMP" > "$B_TMP"; then
if sort "$B_TMP" > "$A_TMP"; then
if $awk '{if(NR=1){tld=$NF};while(getline){if($NF!~tld"\\."){print tld;tld=$NF}}print tld}' "$A_TMP" > "$B_TMP"; then
output_ok
else
output_failn
- json add error "errorOptimization"
+ json add error 'errorOptimization'
mv "$A_TMP" "$B_TMP"
fi
else
output_failn
- json add error "errorOptimization"
+ json add error 'errorOptimization'
fi
else
output_failn
- json add error "errorOptimization"
+ json add error 'errorOptimization'
mv "$A_TMP" "$B_TMP"
fi
else
output_failn
- json add error "errorOptimization"
+ json add error 'errorOptimization'
fi
else
output_failn
- json add error "errorOptimization"
+ json add error 'errorOptimization'
mv "$A_TMP" "$B_TMP"
fi
else
mv "$A_TMP" "$B_TMP"
fi
- if [ -n "$allow_filter" ]; then
+ if [ -s "$SED_TMP" ]; then
output 2 'Allowing domains '
- json set message "$(get_text "statusProcessing"): allowing domains"
- if sed -i -E "$allow_filter" "$B_TMP"; then
+ json set message "$(get_text 'statusProcessing'): allowing domains"
+ if sed -i -E -f "$SED_TMP" "$B_TMP"; then
output_ok
else
output_failn
- json add error "errorAllowListProcessing"
+ json add error 'errorAllowListProcessing'
fi
fi
output 2 'Formatting merged file '
- json set message "$(get_text "statusProcessing"): formatting merged file"
+ json set message "$(get_text 'statusProcessing'): formatting merged file"
if [ -z "$outputFilterIPv6" ]; then
if sed "$outputFilter" "$B_TMP" > "$A_TMP"; then
output_ok
else
- output_failn
- json add error "errorDataFileFormatting"
+ output_failn
+ json add error 'errorDataFileFormatting'
fi
else
case "$dns" in
output_ok
else
output_failn
- json add error "errorDataFileFormatting"
+ json add error 'errorDataFileFormatting'
fi
;;
esac
case "$dns" in
dnsmasq.addnhosts)
output 2 'Creating dnsmasq addnhosts file '
- json set message "$(get_text "statusProcessing"): creating dnsmasq addnhosts file"
+ json set message "$(get_text 'statusProcessing'): creating dnsmasq addnhosts file"
;;
dnsmasq.conf)
output 2 'Creating dnsmasq config file '
- json set message "$(get_text "statusProcessing"): creating dnsmasq config file"
+ json set message "$(get_text 'statusProcessing'): creating dnsmasq config file"
;;
dnsmasq.ipset)
output 2 'Creating dnsmasq ipset file '
- json set message "$(get_text "statusProcessing"): creating dnsmasq ipset file"
+ json set message "$(get_text 'statusProcessing'): creating dnsmasq ipset file"
;;
dnsmasq.nftset)
output 2 'Creating dnsmasq nft set file '
- json set message "$(get_text "statusProcessing"): creating dnsmasq nft set file"
+ json set message "$(get_text 'statusProcessing'): creating dnsmasq nft set file"
;;
dnsmasq.servers)
output 2 'Creating dnsmasq servers file '
- json set message "$(get_text "statusProcessing"): creating dnsmasq servers file"
+ json set message "$(get_text 'statusProcessing'): creating dnsmasq servers file"
+ ;;
+ smartdns.domainset)
+ output 2 'Creating smartdns domain-set file '
+ json set message "$(get_text 'statusProcessing'): creating smartdns domain-set file"
+ ;;
+ smartdns.ipset)
+ output 2 'Creating smartdns domain-set file '
+ json set message "$(get_text 'statusProcessing'): creating smartdns ipset file"
+ ;;
+ smartdns.nftset)
+ output 2 'Creating smartdns domain-set file '
+ json set message "$(get_text 'statusProcessing'): creating smartdns nft set file"
;;
unbound.adb_list)
output 2 'Creating Unbound adb_list file '
- json set message "$(get_text "statusProcessing"): creating Unbound adb_list file"
+ json set message "$(get_text 'statusProcessing'): creating Unbound adb_list file"
;;
esac
output_ok
else
output_failn
- json add error "errorMovingDataFile"
+ json add error 'errorMovingDataFile'
fi
if [ "$compressed_cache" -gt 0 ]; then
output 2 'Creating compressed cache '
- json set message "$(get_text "statusProcessing"): creating compressed cache"
+ json set message "$(get_text 'statusProcessing'): creating compressed cache"
if cache 'create_gzip'; then
output_ok
else
output_failn
- json add error "errorCreatingCompressedCache"
+ json add error 'errorCreatingCompressedCache'
fi
else
rm -f "$outputGzip"
fi
output 2 'Removing temporary files '
- json set message "$(get_text "statusProcessing"): removing temporary files"
- rm -f "/tmp/${packageName}_tmp.*" "$A_TMP" "$B_TMP" "$outputCache" || j=1
+ json set message "$(get_text 'statusProcessing'): removing temporary files"
+ rm -f "/tmp/${packageName}_tmp.*" "$A_TMP" "$B_TMP" "$SED_TMP" "$outputCache" || j=1
if [ $j -eq 0 ]; then
output_ok
else
output_failn
- json add error "errorRemovingTempFiles"
+ json add error 'errorRemovingTempFiles'
fi
output 1 '\n'
}
return 0
fi
case "$dns" in
- dnsmasq.addnhosts|dnsmasq.conf|dnsmasq.ipset|dnsmasq.nftset|dnsmasq.servers)
+ dnsmasq.*)
output 1 "Allowing domain(s) and restarting dnsmasq "
output 2 "Allowing domain(s) \\n"
for c in $string; do
output 2 " $c "
hf="$(echo "$c" | sed 's/\./\\./g')"
- if sed -i "/\(^\|\.\)${hf}$/d;" "$outputFile" && \
+ if sed -i "\:\(/\|\.\)${hf}/:d" "$outputFile" && \
uci_add_list_if_new "${packageName}" 'config' 'allowed_domain' "$c"; then
output_ok
else
fi
fi
output 2 "Committing changes to config "
- if [ -n "$(uci_changes "$packageName")" ] && uci_commit "$packageName"; then
+ if uci_commit "$packageName"; then
allowed_domain="$(uci_get "$packageName" 'config' 'allowed_domain')"
json set triggers
json set stats "$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
output_fail;
fi
;;
- unbound.adb_list)
+ smartdns.*)
+ output 1 "Allowing domain(s) and restarting smartdns "
+ output 2 "Allowing domain(s) \\n"
+ for c in $string; do
+ output 2 " $c "
+ hf="$(echo "$c" | sed 's/\./\\./g')"
+ if sed -i "\:\(\"\|\.\)${hf}\":d" "$outputFile" && \
+ uci_add_list_if_new "$packageName" 'config' 'allowed_domain' "$string"; then
+ output_ok
+ else
+ output_fail
+ fi
+ done
+ if [ "$compressed_cache" -gt 0 ]; then
+ output 2 'Creating compressed cache '
+ if cache 'create_gzip'; then
+ output_ok
+ else
+ output_failn
+ fi
+ fi
+ output 2 "Committing changes to config "
+ if uci_commit "$packageName"; then
+ allowed_domain="$(uci_get "$packageName" 'config' 'allowed_domain')"
+ json set triggers
+ json set stats "$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
+ output_ok;
+ output 2 "Restarting Unbound "
+ if unbound_restart; then output_okn; else output_failn; fi
+ else
+ output_fail;
+ fi
+ ;;
+ unbound.*)
output 1 "Allowing domain(s) and restarting Unbound "
output 2 "Allowing domain(s) \\n"
for c in $string; do
output 2 " $c "
- if sed -i "/${string}/d" "$outputFile" && \
+ hf="$(echo "$c" | sed 's/\./\\./g')"
+ if sed -i "\:\(\"\|\.\)${hf}\":d" "$outputFile" && \
uci_add_list_if_new "$packageName" 'config' 'allowed_domain' "$string"; then
output_ok
else
fi
fi
output 2 "Committing changes to config "
- if [ -n "$(uci_changes "$packageName")" ] && uci_commit "$packageName"; then
+ if uci_commit "$packageName"; then
allowed_domain="$(uci_get "$packageName" 'config' 'allowed_domain')"
json set triggers
json set stats "$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
grep "$string" "$outputFile" | sed 's|nftset=/||;s|/4#inet#adb#adb4||;';;
dnsmasq.servers)
grep "$string" "$outputFile" | sed 's|server=/||;s|/$||;';;
+ smartdns.*)
+ grep "$string" "$outputFile";;
unbound.adb_list)
grep "$string" "$outputFile" | sed 's|^local-zone: "||;s|" static$||;';;
esac
done
}
+adb_check_lists() {
+ _check_list() {
+ local cfg="$1"
+ local en size url R_TMP string c
+ config_get_bool en "$cfg" enabled '1'
+ config_get action "$cfg" action 'block'
+ config_get url "$cfg" url
+ [ "$en" = '0' ] && return 0
+ [ "$action" != 'block' ] && return 0
+ if is_https_url "$url" && [ -z "$isSSLSupported" ]; then
+ output "[DL] $url $__FAIL__\\n"
+ fi
+ while [ -z "$R_TMP" ] || [ -e "$R_TMP" ]; do
+ R_TMP="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
+ done
+ if [ -z "$url" ] || ! $dl_command "$url" "$dl_flag" "$R_TMP" 2>/dev/null || \
+ [ ! -s "$R_TMP" ]; then
+ output "[DL] $url $__FAIL__\\n"
+ else
+ append_newline "$R_TMP"
+ for string in ${param}; do
+ c="$(grep -c "$string" "$R_TMP")"
+ if [ "$c" -gt 0 ]; then
+ if [ "$c" -eq 1 ]; then
+ output "Found 1 match for '$string' in '$url'.\\n"
+ else
+ output "Found $c matches for '$string' in '$url'.\\n"
+ fi
+ grep "$string" "$R_TMP"
+ else
+ output "The '$string' is not found in '$url'.\\n"
+ fi
+ done
+ rm -f "$R_TMP"
+ fi
+ }
+ local param="$1"
+ local validation_result="$3"
+ load_environment "$validation_result" 'quiet' || return 1
+ if [ -z "$param" ]; then
+ output "Usage: /etc/init.d/${packageName} check_lists 'domain' ...\\n"
+ return 0
+ fi
+ config_load "$packageName"
+ config_foreach _check_list 'file_url'
+ return 0
+}
+
adb_config_update() {
local R_TMP label
local param validation_result="$3"
load_environment "$validation_result" "$param" || return 1
label="${config_update_url##*//}"
label="${label%%/*}";
- [ "$config_update_enabled" -ne 0 ] || return 0
+ [ "$config_update_enabled" -ne '0' ] || return 0
if [ "$param" != 'download' ]; then
cache 'test' && return 0
R_TMP="$(mktemp -u -q -t ${packageName}_tmp.XXXXXXXX)"
done
if ! $dl_command "$config_update_url" "$dl_flag" "$R_TMP" 2>/dev/null || [ ! -s "$R_TMP" ]; then
+ append_newline "$R_TMP"
output 1 "$_FAIL_\\n"
output 2 "[DL] Config Update: $label $__FAIL__\\n"
- json add error "errorDownloadingConfigUpdate"
+ json add error 'errorDownloadingConfigUpdate'
else
if [ -s "$R_TMP" ] && sed -f "$R_TMP" -i "$packageConfigFile" 2>/dev/null; then
output 1 "$_OK_\\n"
else
output 1 "$_FAIL_\\n"
output 2 "[DL] Config Update: $label $__FAIL__\\n"
- json add error "errorParsingConfigUpdate"
+ json add error 'errorParsingConfigUpdate'
fi
fi
rm -f "$R_TMP"
return 0
}
-_config_add_url_size() {
- local cfg="$1" url size
- config_get url "$cfg" url
- size="$(get_url_filesize "$url")"
- output "$url${size:+: $size} "
- if [ -n "$size" ]; then
- uci set "${packageName}.${cfg}.size=$size"
- output_okn
- else
- output_failn
- fi
-}
-
adb_sizes() {
+ _config_add_url_size() {
+ local cfg="$1" url size
+ config_get url "$cfg" url
+ size="$(get_url_filesize "$url")"
+ output "$url${size:+: $size} "
+ if [ -n "$size" ]; then
+ uci_set "$packageName" "$cfg" 'size' "$size"
+ output_okn
+ else
+ output_failn
+ fi
+ }
local i
local validation_result="$3"
load_environment "$validation_result" 'quiet' || return 1
config_load "$packageName"
config_foreach _config_add_url_size 'file_url'
- uci commit "$packageName"
+ uci_commit "$packageName"
}
# shellcheck disable=SC2120
elif [ "$action" = 'restart' ] || [ "$param" = 'restart' ]; then
action='restart'
elif [ -s "$outputFile" ] && [ "$status" = "statusSuccess" ] && [ -z "$error" ]; then
- status_service
+ status_service 'quiet'
return 0
else
action='download'
if [ "$action" = 'restore' ]; then
output 0 "Starting $serviceName... "
output 3 "Starting $serviceName...\\n"
- json set status "statusStarting"
+ json set status 'statusStarting'
if cache 'test_gzip' && ! cache 'test' && [ ! -s "$outputFile" ]; then
output 3 'Found compressed cache file, unpacking it '
json set message 'found compressed cache file, unpacking it.'
output_okn
else
output_failn
- json add error "errorRestoreCompressedCache"
+ json add error 'errorRestoreCompressedCache'
output "${_ERROR_}: $(get_text 'errorRestoreCompressedCache')!\\n"
action='download'
fi
json set message 'found cache file, reusing it.'
if cache 'restore'; then
output_okn
- dns 'on_start'
+ resolver 'on_start'
else
output_failn
- json add error "errorRestoreCache"
+ json add error 'errorRestoreCache'
output "${_ERROR_}: $(get_text 'errorRestoreCache')!\\n"
action='download'
fi
fi
if [ "$action" = 'download' ]; then
if [ -z "$blocked_url" ] && [ -z "$blocked_domain" ]; then
- json set status "statusFail"
- json add error "errorNothingToDo"
+ json set status 'statusFail'
+ json add error 'errorNothingToDo'
output "${_ERROR_}: $(get_text 'errorNothingToDo')!\\n"
else
if [ -s "$outputFile" ] || cache 'test' || cache 'test_gzip'; then
output 0 "Force-reloading $serviceName... "
output 3 "Force-reloading $serviceName...\\n"
- json set status "statusForceReloading"
+ json set status 'statusForceReloading'
else
output 0 "Starting $serviceName... "
output 3 "Starting $serviceName...\\n"
- json set status "statusStarting"
+ json set status 'statusStarting'
fi
+ resolver 'cleanup'
if [ "$dns" = 'dnsmasq.conf' ] && [ -n "$dnsmasq_config_file_url" ]; then
download_dnsmasq_file
else
download_lists
fi
- dns 'on_start'
+ resolver 'on_start'
fi
fi
if [ "$action" = 'restart' ]; then
output 0 "Restarting $serviceName... "
output 3 "Restarting $serviceName...\\n"
- json set status "statusRestarting"
- dns 'on_start'
+ json set status 'statusRestarting'
+ resolver 'on_start'
fi
if [ "$action" = 'start' ]; then
output 0 "Starting $serviceName... "
output 3 "Starting $serviceName...\\n"
- json set status "statusStarting"
- dns 'on_start'
+ json set status 'statusStarting'
+ resolver 'on_start'
fi
if [ -s "$outputFile" ] && [ "$(json get status)" != "statusFail" ]; then
output 0 "$__OK__\\n";
json del message
- json set status "statusSuccess"
+ json set status 'statusSuccess'
json set stats "$serviceName is blocking $(wc -l < "$outputFile") domains (with ${dns})"
- status_service
+ status_service 'quiet'
+
else
output 0 "$__FAIL__\\n";
- json set status "statusFail"
- json add error "errorOhSnap"
- status_service
+ json set status 'statusFail'
+ json add error 'errorOhSnap'
+ status_service 'quiet'
fi
procd_open_instance 'main'
json_add_int 'entries' '0'
fi
json_add_array firewall
- if [ "$force_dns" -ne 0 ]; then
+ if [ "$force_dns" -ne '0' ]; then
+# shellcheck disable=SC3060
for c in ${force_dns_port/,/ }; do
if netstat -tuln | grep LISTEN | grep ":${c}" >/dev/null 2>&1; then
json_add_object ""
done
fi
case "$dns" in
- dnsmasq.ipset)
+ dnsmasq.ipset|smartdns.ipset)
json_add_object ""
json_add_string type ipset
json_add_string name adb
json_add_string target REJECT
json_close_object
;;
- dnsmasq.nftset)
+ dnsmasq.nftset|smartdns.nftset)
json_add_object ""
json_add_string type ipset
json_add_string name adb4
json_add_string proto "tcp udp"
json_add_string target REJECT
json_close_object
- if [ "$ipv6_enabled" -ne 0 ]; then
+ if [ "$ipv6_enabled" -ne '0' ]; then
json_add_object ""
json_add_string type ipset
json_add_string name adb6
}
adb_status() {
- local c url status message error stats
- local validation_result="$3"
- load_environment "$validation_result" 'quiet' || return 1
+ local param="$1"
+ local c status message error warning stats text
status="$(json get status)"
message="$(json get message)"
error="$(json get error)"
+ warning="$(json get warning)"
stats="$(json get stats)"
if [ "$status" = "statusSuccess" ]; then
output "$stats "; output_okn;
if [ -n "$status" ] && [ -n "$message" ]; then
status="${status}: $message"
fi
- [ -n "$status" ] && output "$serviceName $status\\n"
+ [ -n "$status" ] && output "$serviceName $status!\\n"
fi
- if [ -n "$error" ]; then
+ if [ "$param" != 'quiet' ] && [ -n "$error" ]; then
for c in $error; do
- url="${c##*|}"
- c="${c%|*}"
- case "$c" in
- errorDownloadingList|errorParsingList)
- output "${_ERROR_}: $(get_text "$c") $url!\\n";;
- *)
- output "${_ERROR_}: $(get_text "$c")!\\n";;
- esac
- n=$((n+1))
+ local error_param="${c##*|}"
+ local error_code="${c%|*}"
+ output "${_ERROR_}: $(get_text "$error_code" "$error_param")!\\n"
+ done
+ fi
+ if [ "$param" != 'quiet' ] && [ -n "$warning" ]; then
+ for c in $warning; do
+ local warning_param="${c##*|}"
+ local warning_code="${c%|*}"
+ output "${_WARNING_}: $(get_text "$warning_code" "$warning_param").\\n"
done
fi
return 0
if [ -s "$outputFile" ]; then
output "Stopping $serviceName... "
cache 'create'
- if dns 'on_stop'; then
+ if resolver 'on_stop'; then
ipset -q -! flush adb
ipset -q -! destroy adb
nft delete set inet fw4 adb4
nft delete set inet fw4 adb6
led_off "$led"
output 0 "$__OK__\\n"; output_okn;
- json set status "statusStopped"
+ json set status 'statusStopped'
json del message
else
output 0 "$__FAIL__\\n"; output_fail;
- json set status "statusFail"
- json add error "errorStopping"
+ json set status 'statusFail'
+ json add error 'errorStopping'
output "${_ERROR_}: $(get_text 'errorStopping')!\\n"
fi
fi
local validation_result="$3"
adb_stop 'on_pause' '' "$validation_result"
output "Sleeping for $timeout seconds... "
- if sleep "$timeout"; then
+ if is_integer "$timeout" && sleep "$timeout"; then
output_okn
else
output_failn
allow() { load_validate_config 'config' adb_allow "'$*'"; }
boot() {
+ local procd_boot_delay
ubus -t 30 wait_for network.interface 2>/dev/null
- rc_procd start_service 'on_boot'
+ config_load "$packageName"
+ config_get procd_boot_delay 'config' 'procd_boot_delay' '0'
+# shellcheck disable=SC2154
+ { is_integer "$procd_boot_delay" && sleep "$procd_boot_delay"; \
+ rc_procd start_service 'on_boot' && service_started 'on_boot'; } &
}
check() { load_validate_config 'config' adb_check "'$*'"; }
+check_lists() { load_validate_config 'config' adb_check_lists "'$*'"; }
dl() { rc_procd start_service 'download'; }
killcache() {
local compressed_cache_dir
rm -f "$dnsmasqIpsetCache" "${compressed_cache_dir}/${dnsmasqIpsetGzip}"
rm -f "$dnsmasqNftsetCache" "${compressed_cache_dir}/${dnsmasqNftsetGzip}"
rm -f "$dnsmasqServersCache" "${compressed_cache_dir}/${dnsmasqServersGzip}"
- rm -f "$unboundCache" "$unboundGzip"
- config_load 'dhcp'
- config_foreach resolver_config 'dnsmasq' 'cleanup'
- uci_commit 'dhcp'
+ rm -f "$smartdnsDomainSetCache" "${compressed_cache_dir}/${smartdnsDomainSetGzip}"
+ rm -f "$smartdnsIpsetCache" "${compressed_cache_dir}/${smartdnsIpsetGzip}"
+ rm -f "$smartdnsNftsetCache" "${compressed_cache_dir}/${smartdnsNftsetGzip}"
+ rm -f "$unboundCache" "${compressed_cache_dir}/${unboundGzip}"
+ resolver 'cleanup'
return 0
}
reload_service() { rc_procd start_service 'restart'; }
restart_service() { rc_procd start_service 'restart'; }
-service_started() { procd_set_config_changed firewall; }
-service_stopped() { procd_set_config_changed firewall; }
+service_started() { is_fw4_restart_needed && procd_set_config_changed firewall; }
+service_stopped() { is_fw4_restart_needed && procd_set_config_changed firewall; }
service_triggers() {
local wan wan6 i
local procd_trigger_wan6
config_load "$packageName"
config_get_bool procd_trigger_wan6 'config' 'procd_trigger_wan6' '0'
- . /lib/functions/network.sh
network_flush_cache
network_find_wan wan
wan="${wan:-wan}"
- if [ "$procd_trigger_wan6" -ne 0 ]; then
+ if [ "$procd_trigger_wan6" -ne '0' ]; then
network_find_wan6 wan6
wan6="${wan6:-wan6}"
fi
load_validate_config 'config' adb_config_update "'$*'"
load_validate_config 'config' adb_start "'$*'"
}
-status_service() { load_validate_config 'config' adb_status "''"; }
+status_service() { adb_status "$@"; }
stop_service() { load_validate_config 'config' adb_stop "'$*'"; }
pause() { load_validate_config 'config' adb_pause "'$*'"; }
version() { echo "$PKG_VERSION"; }
}
load_validate_config() {
- . /lib/functions/network.sh
- . /usr/share/libubox/jshn.sh
local enabled
local force_dns
local force_dns_port
'canary_domains_icloud:bool:0' \
'canary_domains_mozilla:bool:0' \
'config_update_enabled:bool:0' \
- 'config_update_url:string:https://cdn.jsdelivr.net/gh/openwrt/packages/net/adblock-fast/files/adblock-fast.conf.update' \
+ 'config_update_url:string:https://cdn.jsdelivr.net/gh/openwrt/packages/net/adblock-fast/files/adblock-fast.config.update' \
'download_timeout:range(1,60):20' \
- 'pause_timeout:range(10,120):60' \
+ 'pause_timeout:range(1,60):20' \
'curl_additional_param:or("", string)' \
'curl_max_file_size:or("", uinteger)' \
'curl_retry:range(0,30):3' \
'procd_trigger_wan6:bool:0' \
'procd_boot_wan_timeout:integer:60' \
'led:or("", "none", file, device, string)' \
- 'dns:or("dnsmasq.addnhosts", "dnsmasq.conf", "dnsmasq.ipset", "dnsmasq.nftset", "dnsmasq.servers", "unbound.adb_list"):dnsmasq.servers' \
+ 'dns:or("dnsmasq.addnhosts", "dnsmasq.conf", "dnsmasq.ipset", "dnsmasq.nftset", "dnsmasq.servers", "smartdns.domainset", "smartdns.ipset", "smartdns.nftset", "unbound.adb_list"):dnsmasq.servers' \
'dnsmasq_instance:list(or(integer, string)):*' \
+ 'smartdns_instance:list(or(integer, string)):*' \
'allowed_domain:list(string)' \
'blocked_domain:list(string)' \
'dnsmasq_config_file_url:string'
#!/bin/sh
# Copyright 2023 MOSSDeF, Stan Grishin (stangri@melmac.ca)
-# shellcheck disable=SC1091,SC2015,SC3037,SC3043,SC2317,SC3060
+# shellcheck disable=SC2015,SC3043,SC3060
-readonly packageName='adblock-fast'
-readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m'
-readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m'
-readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m'
-readonly __FAIL__='\033[0;31m[\xe2\x9c\x97]\033[0m'
-readonly _ERROR_='\033[0;31mERROR\033[0m'
-readonly _WARNING_='\033[0;33mWARNING\033[0m'
-output() {
-# Can take a single parameter (text) to be output at any verbosity
-# Or target verbosity level and text to be output at specifc verbosity
- local msg memmsg logmsg
- local sharedMemoryOutput="/dev/shm/$packageName-output"
- verbosity="${verbosity:-2}"
- if [ "$#" -ne 1 ]; then
- if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then
- shift
- else
- return 0
- fi
- fi
- [ -t 1 ] && printf "%b" "$1"
- msg="$1";
- if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then
- [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")"
- logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')"
- logger -t "${packageName:-service}" "$(printf "%b" "$logmsg")"
- rm -f "$sharedMemoryOutput"
- else
- printf "%b" "$msg" >> "$sharedMemoryOutput"
- fi
-}
-output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; }
-output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; }
-output_fail() { output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; }
-output_failn() { output 1 "$_FAIL_\\n"; output 2 "$__FAIL__\\n"; }
-is_present() { command -v "$1" >/dev/null 2>&1; }
-get_url_filesize() {
- local url="$1" size size_command
- [ -n "$1" ] || return 0
- is_present 'curl' || return 0
- size_command='curl --silent --insecure --fail --head --request GET'
- size="$($size_command "$url" | grep -Po '^[cC]ontent-[lL]ength: \K\w+')"
- echo -en "$size"
-}
+readonly adbFunctionsFile='/etc/init.d/adblock-fast'
+if [ -s "$adbFunctionsFile" ]; then
+# shellcheck source=../../etc/init.d/adblock-fast
+ . "$adbFunctionsFile"
+else
+ printf "%b: adblock-fast init.d file (%s) not found! \n" '\033[0;31mERROR\033[0m' "$adbFunctionsFile"
+fi
# Transition from simple-adblock
_enable_url() {
config_get u "$cfg" 'url'
config_get a "$cfg" 'action' 'block'
if [ "$u" = "$url" ] && [ "$a" = "$action" ]; then
- uci del "${packageName}.${cfg}.enabled" && _found=1
+ uci_remove "$packageName" "$cfg" 'enabled' && _found=1
fi
}
config_load "$packageName"
config_foreach _enable_url 'file_url' "$url" "$action"
if [ -z "$_found" ]; then
- uci add "${packageName}" 'file_url' >/dev/null 2>&1
- uci set "${packageName}.@file_url[-1].url=$url"
- uci set "${packageName}.@file_url[-1].size=$(get_url_filesize "$url")"
- uci set "${packageName}.@file_url[-1].action=$action"
+ uci_add "$packageName" 'file_url'
+ uci_set "$packageName" '@file_url[-1]' 'url' "$url"
+ uci_set "$packageName" '@file_url[-1]' 'size' "$(get_url_filesize "$url")"
+ uci_set "$packageName" '@file_url[-1]' 'action' "$action"
fi
}
if [ -s '/etc/config/simple-adblock' ] \
&& [ ! -s '/etc/config/adblock-fast-opkg' ] \
- && [ "$(uci get adblock-fast.config.enabled)" = '0' ]; then
+ && [ "$(uci_get adblock-fast config enabled)" = '0' ]; then
cp -f '/etc/config/adblock-fast' '/etc/config/adblock-fast-opkg'
- enabled="$(uci get simple-adblock.config.enabled)"
+ enabled="$(uci_get simple-adblock config enabled)"
if [ -x '/etc/init.d/simple-adblock' ]; then
output "Stopping and disabling simple-adblock "
if /etc/init.d/simple-adblock stop >/dev/null 2>&1 \
&& /etc/init.d/simple-adblock disable \
- && uci set simple-adblock.config.enabled=0 \
- && uci commit simple-adblock; then
+ && uci_set simple-adblock config enabled 0 \
+ && uci_commit simple-adblock; then
output_okn
else
output_failn
fi
else
output "Disabling simple-adblock."
- if uci set simple-adblock.config.enabled=0 \
- && uci commit simple-adblock; then
+ if uci_set simple-adblock config enabled 0 \
+ && uci_commit simple-adblock; then
output_okn
else
output_failn
curl_additional_param curl_max_file_size curl_retry download_timeout \
debug dns dns_instance dnsmasq_config_file_url force_dns led \
parallel_downloads procd_trigger_wan6 procd_boot_wan_timeout verbosity; do
- j="$(uci -q get simple-adblock.config.${i})"
- [ -n "$j" ] && uci set "${packageName}.config.${i}=${j}"
+ j="$(uci_get simple-adblock.config.${i})"
+ [ -n "$j" ] && uci_set "$packageName" config "$i" "$j"
done
- [ -n "$enabled" ] && uci set "${packageName}.config.enabled=${enabled}"
- j="$(uci -q get simple-adblock.config.config_update_url)"
+ [ -n "$enabled" ] && uci_set "$packageName" config enabled "$enabled"
+ j="$(uci_get simple-adblock config config_update_url)"
if [ "${j//simple-adblock/}" = "$j" ]; then
- uci set "${packageName}.config.config_update_url=$j"
+ uci_set "$packageName" config config_update_url "$j"
fi
- ccd="$(uci get simple-adblock.config.compressed_cache_dir)"
- ccd="${ccd:-/etc}"
- for j in $(uci -q get simple-adblock.config.allowed_domain); do
- [ -n "$j" ] && uci add_list "${packageName}.config.allowed_domain=${j}"
+ ccd="$(uci_get simple-adblock config compressed_cache_dir '/etc')"
+ for j in $(uci_get simple-adblock config allowed_domain); do
+ [ -n "$j" ] && uci_add_list "$packageName" config allowed_domain "$j"
done
- for j in $(uci -q get simple-adblock.config.blocked_domain); do
- [ -n "$j" ] && uci add_list "${packageName}.config.blocked_domain=${j}"
+ for j in $(uci_get simple-adblock config blocked_domain); do
+ [ -n "$j" ] && uci_add_list "$packageName" config blocked_domain "$j"
done
- for j in $(uci -q get simple-adblock.config.force_dns_port); do
- [ -n "$j" ] && uci add_list "${packageName}.config.force_dns_port=${j}"
+ for j in $(uci_get simple-adblock config force_dns_port); do
+ [ -n "$j" ] && uci_add_list "$packageName" config force_dns_port "$j"
done
output_okn
for i in allowed_domains_url blocked_adblockplus_url blocked_domains_url \
blocked_hosts_url; do
output "Migrating simple-adblock ${i} "
- for j in $(uci -q get simple-adblock.config.${i}); do
+ for j in $(uci_get simple-adblock config "$i"); do
if [ "$i" = 'allowed_domains_url' ]; then
enable_add_url "$j" 'allow'
else
done
output_okn
done
- uci commit "$packageName"
+ uci_commit "$packageName"
output "Migrating simple-adblock cache file(s) "
for i in '/var/run/simple-adblock/dnsmasq.addnhosts.cache' \
'/var/run/simple-adblock/dnsmasq.conf.cache' \
include $(TOPDIR)/rules.mk
PKG_NAME:=adguardhome
-PKG_VERSION:=0.107.36
+PKG_VERSION:=0.107.42
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
PKG_SOURCE_URL:=https://github.com/AdguardTeam/AdGuardHome
-PKG_MIRROR_HASH:=6f32717df3654432d0c50ee730f0eef3ec806a966508f5cd82899077f1e086c8
+PKG_MIRROR_HASH:=a3ab5470960b2ba8645d6889f5b4d229e6b21201503e61e2c485666540b33806
PKG_LICENSE:=GPL-3.0-only
PKG_LICENSE_FILES:=LICENSE.txt
+++ /dev/null
-From 61c2e12116147fab716221009b3a14fa5792a72d Mon Sep 17 00:00:00 2001
-From: Dobroslaw Kijowski <dobo90@gmail.com>
-Date: Mon, 21 Aug 2023 10:22:27 +0200
-Subject: [PATCH] go get github.com/quic-go/quic-go@v0.37.6
-
----
- go.mod | 4 ++--
- go.sum | 4 ++++
- 2 files changed, 6 insertions(+), 2 deletions(-)
-
---- a/go.mod
-+++ b/go.mod
-@@ -28,7 +28,7 @@ require (
- github.com/mdlayher/raw v0.1.0
- github.com/miekg/dns v1.1.55
- // TODO(a.garipov): Update to ≥ v0.37.0 once we update to Go 1.20.
-- github.com/quic-go/quic-go v0.36.2
-+ github.com/quic-go/quic-go v0.37.6
- github.com/stretchr/testify v1.8.4
- github.com/ti-mo/netfilter v0.5.0
- go.etcd.io/bbolt v1.3.7
-@@ -60,7 +60,7 @@ require (
- github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/quic-go/qpack v0.4.0 // indirect
- github.com/quic-go/qtls-go1-19 v0.3.2 // indirect
-- github.com/quic-go/qtls-go1-20 v0.2.2 // indirect
-+ github.com/quic-go/qtls-go1-20 v0.3.1 // indirect
- github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
- golang.org/x/mod v0.12.0 // indirect
- golang.org/x/sync v0.3.0 // indirect
---- a/go.sum
-+++ b/go.sum
-@@ -108,8 +108,12 @@ github.com/quic-go/qtls-go1-19 v0.3.2 h1
- github.com/quic-go/qtls-go1-19 v0.3.2/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
- github.com/quic-go/qtls-go1-20 v0.2.2 h1:WLOPx6OY/hxtTxKV1Zrq20FtXtDEkeY00CGQm8GEa3E=
- github.com/quic-go/qtls-go1-20 v0.2.2/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
-+github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg=
-+github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
- github.com/quic-go/quic-go v0.36.2 h1:ZX/UNQ4gvpCv2RmwdbA6lrRjF6EBm5yZ7TMoT4NQVrA=
- github.com/quic-go/quic-go v0.36.2/go.mod h1:zPetvwDlILVxt15n3hr3Gf/I3mDf7LpLKPhR4Ez0AZQ=
-+github.com/quic-go/quic-go v0.37.6 h1:2IIUmQzT5YNxAiaPGjs++Z4hGOtIR0q79uS5qE9ccfY=
-+github.com/quic-go/quic-go v0.37.6/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
- github.com/shirou/gopsutil/v3 v3.21.8 h1:nKct+uP0TV8DjjNiHanKf8SAuub+GNsbrOtM9Nl9biA=
- github.com/shirou/gopsutil/v3 v3.21.8/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ=
- github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
--with-libpcap-include=$(STAGING_DIR)/usr/include \
--with-libpcap-lib=$(STAGING_DIR)/usr/lib \
--without-opt \
+ --with-libbsd=no \
\
PYTHON=$(PYTHON) \
\
--- /dev/null
+From 0265e79f3c9a27a3ffd186e7d3bcd2f744052605 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sat, 28 Oct 2023 17:30:09 +0200
+Subject: [PATCH] build: add option to disable bsd library inclusion
+
+It might be needed to disable bsd inclusion and fallback to the compat
+functions even if bsd headers are detected.
+
+This is the case when multiple library are cross-compiled and someone
+wants to explicitly compile aircrack-ng without linking to bsd library.
+
+With the current implementation, if a bsd header is detected, the bsd
+library is always linked even if unwanted. Add option to configure this
+with the combo --with-libbsd=yes|no|auto with auto set by default.
+
+Also add an extra featurw with introducing the possibility of requiring
+the bsd library and fail the configure phase.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ build/m4/aircrack_ng_compat.m4 | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+--- a/build/m4/aircrack_ng_compat.m4
++++ b/build/m4/aircrack_ng_compat.m4
+@@ -38,11 +38,29 @@ dnl If you delete this exception stateme
+ dnl program, then also delete it here.
+
+ AC_DEFUN([AIRCRACK_NG_COMPAT], [
++AC_ARG_WITH(libbsd,
++ [AS_HELP_STRING([--with-libbsd[[=auto|yes|no]]], [use BSD library, [default=auto]])])
++
++case $with_libbsd in
++ yes | "" | auto)
++ AC_CHECK_HEADERS([bsd/string.h], [HAVE_BSD_STRING_H=yes])
++ AC_CHECK_LIB([bsd], [strlcpy], [:])
++ AC_CHECK_FUNCS([strlcpy strlcat], [:])
++ ;;
++esac
+
+-AC_CHECK_HEADERS([bsd/string.h], [HAVE_BSD_STRING_H=yes], [HAVE_BSD_STRING_H=no])
+ AM_CONDITIONAL([HAVE_BSD_STRING_H], [test "$HAVE_BSD_STRING_H" = yes])
+-AC_CHECK_LIB([bsd], [strlcpy], [ LIBS="$LIBS -lbsd" ], [:])
+-AC_CHECK_FUNCS([strlcpy strlcat], [:])
++
++if test $with_libbsd != no
++then
++ if test $ac_cv_lib_bsd_strlcpy = yes
++ then
++ LIBS="$LIBS -lbsd"
++ elif test $with_libbsd = yes
++ then
++ AC_MSG_ERROR([cannot configure required bsd library])
++ fi
++fi
+
+ have_bsd=no
+ if test "$cross_compiling" != yes
--- /dev/null
+From 6317063da827732dbc5cc0dd1650ed016bd2927c Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sun, 29 Oct 2023 14:41:18 +0100
+Subject: [PATCH] build: support strlcat/strlcpy from musl or recent glibc
+
+Musl or recent glibc added support for these additional string function,
+strlcat and strlcpy hence the compat function are not needed and the
+builtin version can be used instead.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ build/m4/aircrack_ng_compat.m4 | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/build/m4/aircrack_ng_compat.m4
++++ b/build/m4/aircrack_ng_compat.m4
+@@ -41,11 +41,12 @@ AC_DEFUN([AIRCRACK_NG_COMPAT], [
+ AC_ARG_WITH(libbsd,
+ [AS_HELP_STRING([--with-libbsd[[=auto|yes|no]]], [use BSD library, [default=auto]])])
+
++AC_CHECK_FUNCS([strlcpy strlcat], [:])
++
+ case $with_libbsd in
+ yes | "" | auto)
+ AC_CHECK_HEADERS([bsd/string.h], [HAVE_BSD_STRING_H=yes])
+ AC_CHECK_LIB([bsd], [strlcpy], [:])
+- AC_CHECK_FUNCS([strlcpy strlcat], [:])
+ ;;
+ esac
+
PKG_NAME:=apinger
PKG_SOURCE_DATE:=2015-04-09
PKG_SOURCE_VERSION:=78eb328721ba1a10571c19df95acddcb5f0c17c8
-PKG_RELEASE:=5
+PKG_RELEASE:=6
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/Jajcus/apinger
config_get_bool rrd "$target" rrd 0
[ -z "$address" ] && return 0
-
- srcip=$(uci_get network "$interface" ipaddr)
- [ -z "$srcip" ] && network_get_ipaddr srcip "$interface"
- srcip="${srcip:-0.0.0.0}"
+ if [ -z $(echo "$address"|sed "/:/d") ]; then
+ srcip=$(uci_get network "$interface" ip6addr)
+ [ -z "$srcip"] && network_get_ipaddr6 srcip "$interface"
+ srcip="${srcip:-::}"
+ else
+ srcip=$(uci_get network "$interface" ipaddr)
+ [ -z "$srcip"] && network_get_ipaddr srcip "$interface"
+ srcip="${srcip:-0.0.0.0}"
+ fi
alarms=${alarm_down:+\"${alarm_down}\"}
alarms=${alarm_delay:+${alarms:+${alarms}, }}${alarm_delay:+\"${alarm_delay}\"}
local percent_low percent_high
config_get percent_low "$alarm" percent_low
- config_get percent_high "$alarm" percent_low
+ config_get percent_high "$alarm" percent_high
if [ -z "$percent_low" ] || [ -z "$percent_high" ]; then
return
local debug status_interval rrd_interval instance
instance=$1
- config_get_bool debug apinger debug 0
- config_get status_interval apinger status_interval 1
- config_get rrd_interval apinger rrd_interval 30
+ config_get_bool debug "$instance" debug 0
+ config_get status_interval "$instance" status_interval 1
+ config_get rrd_interval "$instance" rrd_interval 30
[ "$debug" = "1" ] && debug=on || debug=off
if [ -f "$status_file" ]; then
_IFS="$IFS"
IFS="|"
- while read -r address srcip target received sent timestamp latency loss alarm; do
+ while read -r address srcip target sent received timestamp latency loss alarm; do
json_add_object targets
json_add_string interface "$iface"
json_add_string target "$target"
include $(TOPDIR)/rules.mk
PKG_NAME:=aria2
-PKG_VERSION:=1.36.0
-PKG_RELEASE:=2
+PKG_VERSION:=1.37.0
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/aria2/aria2/releases/download/release-$(PKG_VERSION)/
-PKG_HASH:=58d1e7608c12404f0229a3d9a4953d0d00c18040504498b483305bcb3de907a5
+PKG_HASH:=60a420ad7085eb616cb6e2bdf0a7206d68ff3d37fb5a956dc44242eb2f79b66b
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=gc-sections lto
include $(TOPDIR)/rules.mk
PKG_NAME:=ariang
-PKG_VERSION:=1.3.2
+PKG_VERSION:=1.3.6
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).zip
PKG_SOURCE_URL:=https://github.com/mayswind/AriaNg/releases/download/$(PKG_VERSION)
-PKG_HASH:=2186dacf57c9d1650e00084c0454f2227e910f3203d89c6190f547b40cac7243
+PKG_HASH:=2d36e1a39d95867b8e0cdb3cde96d04d40117bd37e8742d639da92496e07cc7b
UNPACK_CMD=unzip -q -d $(1) $(DL_DIR)/$(PKG_SOURCE)
PKG_MAINTAINER:=Ansuel Smith <ansuelsmth@gmail.com>
$(PKG_BUILD_DIR)/LICENSE \
$(PKG_BUILD_DIR)/favicon.* \
$(PKG_BUILD_DIR)/robots.txt \
+ $(PKG_BUILD_DIR)/tileicon.png \
+ $(PKG_BUILD_DIR)/touchicon.png \
$(1)/www/ariang
endef
include $(TOPDIR)/rules.mk
PKG_NAME:=banip
-PKG_VERSION:=0.9.1
+PKG_VERSION:=0.9.3
PKG_RELEASE:=1
PKG_LICENSE:=GPL-3.0-or-later
PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
SECTION:=net
CATEGORY:=Network
TITLE:=banIP blocks IPs via named nftables Sets
- DEPENDS:=+jshn +jsonfilter +firewall4 +ca-bundle +logd +rpcd +rpcd-mod-rpcsys
+ DEPENDS:=+jshn +jsonfilter +firewall4 +ca-bundle +rpcd +rpcd-mod-rpcsys
PKGARCH:=all
endef
$(INSTALL_CONF) ./files/banip.countries $(1)/etc/banip
$(INSTALL_CONF) ./files/banip.feeds $(1)/etc/banip
$(INSTALL_CONF) ./files/banip.custom.feeds $(1)/etc/banip
+
+ $(INSTALL_DIR) $(1)/www/cgi-bin
+ $(INSTALL_BIN) ./files/banip.cgi $(1)/www/cgi-bin/banip
endef
$(eval $(call BuildPackage,banip))
* Add new or edit existing banIP feeds on your own with the LuCI integrated custom feed editor
* Supports external allowlist URLs to reference additional IPv4/IPv6 feeds
* Supports allowing / blocking of certain VLAN forwards
+* Provides an option to transfer logging events on remote servers via cgi interface
## Prerequisites
-* **[OpenWrt](https://openwrt.org)**, latest stable release or a snapshot with nft/firewall 4 and logd/logread support
+* **[OpenWrt](https://openwrt.org)**, latest stable release or a snapshot with nft/firewall 4 support
* A download utility with SSL support: 'aria2c', 'curl', full 'wget' or 'uclient-fetch' with one of the 'libustream-*' SSL libraries, the latter one doesn't provide support for ETag HTTP header
* A certificate store like 'ca-bundle', as banIP checks the validity of the SSL certificates of all download sites by default
* For E-Mail notifications you need to install and setup the additional 'msmtp' package
## banIP config options
-| Option | Type | Default | Description |
-| :---------------------- | :----- | :---------------------------- | :----------------------------------------------------------------------------------------------------------- |
-| ban_enabled | option | 0 | enable the banIP service |
-| ban_nicelimit | option | 0 | ulimit nice level of the banIP service (range 0-19) |
-| ban_filelimit | option | 1024 | ulimit max open/number of files (range 1024-4096) |
-| ban_loglimit | option | 100 | scan only the last n log entries permanently. A value of '0' disables the monitor |
-| ban_logcount | option | 1 | how many times the IP must appear in the log to be considered as suspicious |
-| ban_logterm | list | regex | various regex for logfile parsing (default: dropbear, sshd, luci, nginx, asterisk) |
-| ban_autodetect | option | 1 | auto-detect wan interfaces, devices and subnets |
-| ban_debug | option | 0 | enable banIP related debug logging |
-| ban_loginput | option | 1 | log drops in the wan-input chain |
-| ban_logforwardwan | option | 1 | log drops in the wan-forward chain |
-| ban_logforwardlan | option | 0 | log rejects in the lan-forward chain |
-| ban_autoallowlist | option | 1 | add wan IPs/subnets and resolved domains automatically to the local allowlist (not only to the Sets) |
-| ban_autoblocklist | option | 1 | add suspicious attacker IPs and resolved domains automatically to the local blocklist (not only to the Sets) |
-| ban_autoblocksubnet | option | 0 | add entire subnets to the blocklist Sets based on an additional RDAP request with the suspicious IP |
-| ban_autoallowuplink | option | subnet | limit the uplink autoallow function to: 'subnet', 'ip' or 'disable' it at all |
-| ban_allowlistonly | option | 0 | restrict the internet access from/to a given number of secure websites/IPs |
-| ban_basedir | option | /tmp | base working directory while banIP processing |
-| ban_reportdir | option | /tmp/banIP-report | directory where banIP stores the report files |
-| ban_backupdir | option | /tmp/banIP-backup | directory where banIP stores the compressed backup files |
-| ban_protov4 | option | - / autodetect | enable IPv4 support |
-| ban_protov6 | option | - / autodetect | enable IPv4 support |
-| ban_ifv4 | list | - / autodetect | logical wan IPv4 interfaces, e.g. 'wan' |
-| ban_ifv6 | list | - / autodetect | logical wan IPv6 interfaces, e.g. 'wan6' |
-| ban_dev | list | - / autodetect | wan device(s), e.g. 'eth2' |
-| ban_vlanallow | list | - | always allow certain VLAN forwards, e.g. br-lan.20 |
-| ban_vlanblock | list | - | always block certain VLAN forwards, e.g. br-lan.10 |
-| ban_trigger | list | - | logical reload trigger interface(s), e.g. 'wan' |
-| ban_triggerdelay | option | 10 | trigger timeout during interface reload and boot |
-| ban_deduplicate | option | 1 | deduplicate IP addresses across all active Sets |
-| ban_splitsize | option | 0 | split ext. Sets after every n lines/members (saves RAM) |
-| ban_cores | option | - / autodetect | limit the cpu cores used by banIP (saves RAM) |
-| ban_nftloglevel | option | warn | nft loglevel, values: emerg, alert, crit, err, warn, notice, info, debug |
-| ban_nftpriority | option | -200 | nft priority for the banIP table (default is the prerouting table priority) |
-| ban_nftpolicy | option | memory | nft policy for banIP-related Sets, values: memory, performance |
-| ban_nftexpiry | option | - | expiry time for auto added blocklist members, e.g. '5m', '2h' or '1d' |
-| ban_feed | list | - | external download feeds, e.g. 'yoyo', 'doh', 'country' or 'talos' (see feed table) |
-| ban_asn | list | - | ASNs for the 'asn' feed, e.g.'32934' |
-| ban_country | list | - | country iso codes for the 'country' feed, e.g. 'ru' |
-| ban_blockpolicy | option | - | limit the default block policy to a certain chain, e.g. 'input', 'forwardwan' or 'forwardlan' |
-| ban_blocktype | option | drop | 'drop' packets silently on input and forwardwan chains or actively 'reject' the traffic |
-| ban_blockinput | list | - | limit a feed to the wan-input chain, e.g. 'country' |
-| ban_blockforwardwan | list | - | limit a feed to the wan-forward chain, e.g. 'debl' |
-| ban_blockforwardlan | list | - | limit a feed to the lan-forward chain, e.g. 'doh' |
-| ban_fetchcmd | option | - / autodetect | 'uclient-fetch', 'wget', 'curl' or 'aria2c' |
-| ban_fetchparm | option | - / autodetect | set the config options for the selected download utility |
-| ban_fetchretry | option | 5 | number of download attempts in case of an error (not supported by uclient-fetch) |
-| ban_fetchinsecure | option | 0 | don't check SSL server certificates during download |
-| ban_mailreceiver | option | - | receiver address for banIP related notification E-Mails |
-| ban_mailsender | option | no-reply@banIP | sender address for banIP related notification E-Mails |
-| ban_mailtopic | option | banIP notification | topic for banIP related notification E-Mails |
-| ban_mailprofile | option | ban_notify | mail profile used in 'msmtp' for banIP related notification E-Mails |
-| ban_mailnotification | option | 0 | receive E-Mail notifications with every banIP run |
-| ban_reportelements | option | 1 | count Set elements in the report, disable this option to speed up the report significantly |
-| ban_resolver | option | - | external resolver used for DNS lookups |
+| Option | Type | Default | Description |
+| :---------------------- | :----- | :---------------------------- | :---------------------------------------------------------------------------------------------------------------- |
+| ban_enabled | option | 0 | enable the banIP service |
+| ban_nicelimit | option | 0 | ulimit nice level of the banIP service (range 0-19) |
+| ban_filelimit | option | 1024 | ulimit max open/number of files (range 1024-4096) |
+| ban_loglimit | option | 100 | scan only the last n log entries permanently. A value of '0' disables the monitor |
+| ban_logcount | option | 1 | how many times the IP must appear in the log to be considered as suspicious |
+| ban_logterm | list | regex | various regex for logfile parsing (default: dropbear, sshd, luci, nginx, asterisk and cgi-remote events) |
+| ban_logreadfile | option | /var/log/messages | alternative location for parsing the log file, e.g. via syslog-ng, to deactivate the standard parsing via logread |
+| ban_autodetect | option | 1 | auto-detect wan interfaces, devices and subnets |
+| ban_debug | option | 0 | enable banIP related debug logging |
+| ban_loginput | option | 1 | log drops in the wan-input chain |
+| ban_logforwardwan | option | 1 | log drops in the wan-forward chain |
+| ban_logforwardlan | option | 0 | log rejects in the lan-forward chain |
+| ban_autoallowlist | option | 1 | add wan IPs/subnets and resolved domains automatically to the local allowlist (not only to the Sets) |
+| ban_autoblocklist | option | 1 | add suspicious attacker IPs and resolved domains automatically to the local blocklist (not only to the Sets) |
+| ban_autoblocksubnet | option | 0 | add entire subnets to the blocklist Sets based on an additional RDAP request with the suspicious IP |
+| ban_autoallowuplink | option | subnet | limit the uplink autoallow function to: 'subnet', 'ip' or 'disable' it at all |
+| ban_allowlistonly | option | 0 | restrict the internet access from/to a given number of secure websites/IPs |
+| ban_basedir | option | /tmp | base working directory while banIP processing |
+| ban_reportdir | option | /tmp/banIP-report | directory where banIP stores the report files |
+| ban_backupdir | option | /tmp/banIP-backup | directory where banIP stores the compressed backup files |
+| ban_protov4 | option | - / autodetect | enable IPv4 support |
+| ban_protov6 | option | - / autodetect | enable IPv4 support |
+| ban_ifv4 | list | - / autodetect | logical wan IPv4 interfaces, e.g. 'wan' |
+| ban_ifv6 | list | - / autodetect | logical wan IPv6 interfaces, e.g. 'wan6' |
+| ban_dev | list | - / autodetect | wan device(s), e.g. 'eth2' |
+| ban_vlanallow | list | - | always allow certain VLAN forwards, e.g. br-lan.20 |
+| ban_vlanblock | list | - | always block certain VLAN forwards, e.g. br-lan.10 |
+| ban_trigger | list | - | logical reload trigger interface(s), e.g. 'wan' |
+| ban_triggerdelay | option | 10 | trigger timeout during interface reload and boot |
+| ban_deduplicate | option | 1 | deduplicate IP addresses across all active Sets |
+| ban_splitsize | option | 0 | split ext. Sets after every n lines/members (saves RAM) |
+| ban_cores | option | - / autodetect | limit the cpu cores used by banIP (saves RAM) |
+| ban_nftloglevel | option | warn | nft loglevel, values: emerg, alert, crit, err, warn, notice, info, debug |
+| ban_nftpriority | option | -200 | nft priority for the banIP table (default is the prerouting table priority) |
+| ban_nftpolicy | option | memory | nft policy for banIP-related Sets, values: memory, performance |
+| ban_nftexpiry | option | - | expiry time for auto added blocklist members, e.g. '5m', '2h' or '1d' |
+| ban_feed | list | - | external download feeds, e.g. 'yoyo', 'doh', 'country' or 'talos' (see feed table) |
+| ban_asn | list | - | ASNs for the 'asn' feed, e.g.'32934' |
+| ban_country | list | - | country iso codes for the 'country' feed, e.g. 'ru' |
+| ban_blockpolicy | option | - | limit the default block policy to a certain chain, e.g. 'input', 'forwardwan' or 'forwardlan' |
+| ban_blocktype | option | drop | 'drop' packets silently on input and forwardwan chains or actively 'reject' the traffic |
+| ban_blockinput | list | - | limit a feed to the wan-input chain, e.g. 'country' |
+| ban_blockforwardwan | list | - | limit a feed to the wan-forward chain, e.g. 'debl' |
+| ban_blockforwardlan | list | - | limit a feed to the lan-forward chain, e.g. 'doh' |
+| ban_fetchcmd | option | - / autodetect | 'uclient-fetch', 'wget', 'curl' or 'aria2c' |
+| ban_fetchparm | option | - / autodetect | set the config options for the selected download utility |
+| ban_fetchretry | option | 5 | number of download attempts in case of an error (not supported by uclient-fetch) |
+| ban_fetchinsecure | option | 0 | don't check SSL server certificates during download |
+| ban_mailreceiver | option | - | receiver address for banIP related notification E-Mails |
+| ban_mailsender | option | no-reply@banIP | sender address for banIP related notification E-Mails |
+| ban_mailtopic | option | banIP notification | topic for banIP related notification E-Mails |
+| ban_mailprofile | option | ban_notify | mail profile used in 'msmtp' for banIP related notification E-Mails |
+| ban_mailnotification | option | 0 | receive E-Mail notifications with every banIP run |
+| ban_reportelements | option | 1 | count Set elements in the report, disable this option to speed up the report significantly |
+| ban_resolver | option | - | external resolver used for DNS lookups |
+| ban_remotelog | option | 0 | enable the cgi interface to receive remote logging events |
+| ban_remotetoken | option | - | unique token to communicate with the cgi interface |
## Examples
**banIP report information**
list ban_logterm 'error: maximum authentication attempts exceeded'
list ban_logterm 'sshd.*Connection closed by.*\[preauth\]'
list ban_logterm 'SecurityEvent=\"InvalidAccountID\".*RemoteAddress='
+list ban_logterm 'received a suspicious remote IP '\''.*'\'''
```
**allow-/blocklist handling**
C8:C2:9B:F7:80:12 192.168.1.10 => this will be populated to v4MAC-Set with the certain IP
C8:C2:9B:F7:80:12 => this will be populated to v6MAC-Set with the IP-wildcard ::/0
```
+**enable the cgi interface to receive remote logging events**
+banIP ships a basic cgi interface in '/www/cgi-bin/banip' to receive remote logging events (disabled by default). The cgi interface evaluates logging events via GET or POST request (see examples below). To enable the cgi interface set the following options:
+
+ * set 'ban_remotelog' to '1' to enbale the cgi interface
+ * set 'ban_remotetoken' to a secret transfer token, allowed token characters consist of '[A-Za-z]', '[0-9]', '.' and ':'
+
+ Examples to transfer remote logging events from an internal server to banIP via cgi interface:
+
+ * POST request: curl --insecure --data "<ban_remotetoken>=<suspicious IP>" https://192.168.1.1/cgi-bin/banip
+ * GET request: wget --no-check-certificate https://192.168.1.1/cgi-bin/banip?<ban_remotetoken>=<suspicious IP>
+
+Please note: for security reasons use this cgi interface only internally and only encrypted via https transfer protocol.
**redirect Asterisk security logs to lodg/logread**
banIP only supports logfile scanning via logread, so to monitor attacks on Asterisk, its security log must be available via logread. To do this, edit '/etc/asterisk/logger.conf' and add the line 'syslog.local0 = security', then run 'asterisk -rx reload logger' to update the running Asterisk configuration.
ban_rdapfile="/var/run/banip_rdap.json"
ban_rdapurl="https://rdap.db.ripe.net/ip/"
ban_lock="/var/run/banip.lock"
-ban_logreadcmd="$(command -v logread)"
+ban_logreadfile="/var/log/messages"
+ban_logreadcmd=""
ban_logcmd="$(command -v logger)"
ban_ubuscmd="$(command -v ubus)"
ban_nftcmd="$(command -v nft)"
ban_mailprofile="ban_notify"
ban_mailnotification="0"
ban_reportelements="1"
+ban_remotelog="0"
+ban_remotetoken=""
ban_nftloglevel="warn"
ban_nftpriority="-200"
ban_nftpolicy="memory"
local ppid pid pids
ppid="$("${ban_catcmd}" "${ban_pidfile}" 2>/dev/null)"
- [ -n "${ppid}" ] && pids="$(pgrep -P "${ppid}" 2>/dev/null)"
- for pid in ${pids}; do
- kill -INT "${pid}" >/dev/null 2>&1
- done
+ if [ -n "${ppid}" ]; then
+ pids="$(pgrep -P "${ppid}" 2>/dev/null)"
+ for pid in ${pids}; do
+ pids="${pids} $(pgrep -P "${pid}" 2>/dev/null)"
+ done
+ for pid in ${pids}; do
+ kill -INT "${pid}" >/dev/null 2>&1
+ done
+ fi
: >"${ban_rdapfile}"
: >"${ban_pidfile}"
}
}
}
config_load banip
+ [ -f "${ban_logreadfile}" ] && ban_logreadcmd="$(command -v tail)" || ban_logreadcmd="$(command -v logread)"
}
# get nft/monitor actuals
#
f_actual() {
- local nft monitor
+ local nft monitor ppid pid
if "${ban_nftcmd}" -t list set inet banIP allowlistv4MAC >/dev/null 2>&1; then
nft="$(f_char "1")"
else
nft="$(f_char "0")"
fi
- if pgrep -f "${ban_logreadcmd##*/}" -P "$("${ban_catcmd}" "${ban_pidfile}" 2>/dev/null)" >/dev/null 2>&1; then
+
+ ppid="$("${ban_catcmd}" "${ban_pidfile}" 2>/dev/null)"
+ if [ -n "${ppid}" ]; then
+ pid="$(pgrep -oP "${ppid}" 2>/dev/null)"
+ fi
+ if pgrep -f "${ban_logreadcmd##*/}" -P "${pid}" >/dev/null 2>&1; then
monitor="$(f_char "1")"
else
monitor="$(f_char "0")"
# restore local backups
#
- if { [ "${ban_action}" != "reload" ] || [ "${feed_url}" = "local" ] || [ -n "${ban_etagparm}" ]; } && [ "${feed%v*}" != "allowlist" ] && [ "${feed%v*}" != "blocklist" ]; then
- if [ -n "${ban_etagparm}" ] && [ "${ban_action}" = "reload" ] && [ "${feed_url}" != "local" ]; then
+ if [ "${feed%v*}" != "blocklist" ]; then
+ if [ -n "${ban_etagparm}" ] && [ "${ban_action}" = "reload" ] && [ "${feed_url}" != "local" ] && [ "${feed%v*}" != "allowlist" ]; then
etag_rc="0"
if [ "${feed%v*}" = "country" ]; then
for country in ${ban_country}; do
fi
fi
if [ "${etag_rc}" = "0" ] || [ "${ban_action}" != "reload" ] || [ "${feed_url}" = "local" ]; then
- f_restore "${feed}" "${feed_url}" "${tmp_load}" "${etag_rc}"
+ if [ "${feed%v*}" = "allowlist" ] && [ ! -f "${tmp_allow}" ]; then
+ f_restore "allowlist" "-" "${tmp_allow}" "${etag_rc}"
+ else
+ f_restore "${feed}" "${feed_url}" "${tmp_load}" "${etag_rc}"
+ fi
restore_rc="${?}"
feed_rc="${restore_rc}"
fi
fi
- # prepare local allowlist
+ # prepare local/remote allowlist
#
if [ "${feed%v*}" = "allowlist" ] && [ ! -f "${tmp_allow}" ]; then
"${ban_catcmd}" "${ban_allowlist}" 2>/dev/null >"${tmp_allow}"
+ feed_rc="${?}"
for feed_url in ${ban_allowurl}; do
feed_log="$("${ban_fetchcmd}" ${ban_fetchparm} "${tmp_load}" "${feed_url}" 2>&1)"
feed_rc="${?}"
"${ban_catcmd}" "${tmp_load}" 2>/dev/null >>"${tmp_allow}"
else
f_log "info" "download for feed '${feed%v*}' failed (rc: ${feed_rc:-"-"}/log: ${feed_log})"
+ break
fi
done
+ if [ "${feed_rc}" = "0" ]; then
+ f_backup "allowlist" "${tmp_allow}"
+ elif [ -z "${restore_rc}" ] && [ "${feed_rc}" != "0" ]; then
+ f_restore "allowlist" "-" "${tmp_allow}" "${feed_rc}"
+ fi
+ feed_rc="${?}"
fi
# handle local feeds
# load generated nft file in banIP table
#
if [ "${feed_rc}" = "0" ]; then
- cnt_dl="$("${ban_awkcmd}" 'END{printf "%d",NR}' "${tmp_split}" 2>/dev/null)"
+ if [ "${feed%v*}" = "allowlist" ]; then
+ cnt_dl="$("${ban_awkcmd}" 'END{printf "%d",NR}' "${tmp_allow}" 2>/dev/null)"
+ else
+ cnt_dl="$("${ban_awkcmd}" 'END{printf "%d",NR}' "${tmp_split}" 2>/dev/null)"
+ fi
if [ "${cnt_dl:-"0"}" -gt "0" ] || [ "${feed_url}" = "local" ] || [ "${feed%v*}" = "allowlist" ] || [ "${feed%v*}" = "blocklist" ]; then
feed_log="$("${ban_nftcmd}" -f "${tmp_nft}" 2>&1)"
feed_rc="${?}"
cnt_elements="$((cnt_elements + $("${ban_nftcmd}" -j list set inet banIP "${object}" 2>/dev/null | "${ban_jsoncmd}" -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)))"
done
fi
- runtime="action: ${ban_action:-"-"}, fetch: ${ban_fetchcmd##*/}, duration: ${duration:-"-"}, date: $(date "+%Y-%m-%d %H:%M:%S")"
+ runtime="action: ${ban_action:-"-"}, log: ${ban_logreadcmd##*/}, fetch: ${ban_fetchcmd##*/}, duration: ${duration:-"-"}, date: $(date "+%Y-%m-%d %H:%M:%S")"
fi
[ -s "${ban_customfeedfile}" ] && custom_feed="1"
[ "${ban_splitsize:-"0"}" -gt "0" ] && split="1"
# log monitor
#
f_monitor() {
- local nft_expiry line proto ip log_raw log_count rdap_log rdap_rc rdap_elements rdap_info
+ local logread_cmd loglimit_cmd nft_expiry line proto ip log_raw log_count rdap_log rdap_rc rdap_elements rdap_info
+
+ if [ -f "${ban_logreadfile}" ]; then
+ logread_cmd="${ban_logreadcmd} -qf ${ban_logreadfile} 2>/dev/null | ${ban_grepcmd} -e \"${ban_logterm%%??}\" 2>/dev/null"
+ loglimit_cmd="${ban_logreadcmd} -qn ${ban_loglimit} ${ban_logreadfile} 2>/dev/null"
+ elif printf "%s" "${ban_packages}" | "${ban_grepcmd}" -q '"logd'; then
+ logread_cmd="${ban_logreadcmd} -fe \"${ban_logterm%%??}\" 2>/dev/null"
+ loglimit_cmd="${ban_logreadcmd} -l ${ban_loglimit} 2>/dev/null"
+ fi
- if [ -x "${ban_logreadcmd}" ] && [ -n "${ban_logterm%%??}" ] && [ "${ban_loglimit}" != "0" ]; then
- f_log "info" "start detached banIP log service"
+ if [ -x "${ban_logreadcmd}" ] && [ -n "${logread_cmd}" ] && [ -n "${loglimit_cmd}" ] && [ -n "${ban_logterm%%??}" ] && [ "${ban_loglimit}" != "0" ]; then
+ f_log "info" "start detached banIP log service (${ban_logreadcmd})"
[ -n "${ban_nftexpiry}" ] && nft_expiry="timeout $(printf "%s" "${ban_nftexpiry}" | "${ban_grepcmd}" -oE "([0-9]+[d|h|m|s])+$")"
- "${ban_logreadcmd}" -fe "${ban_logterm%%??}" 2>/dev/null |
+ eval "${logread_cmd}" |
while read -r line; do
: >"${ban_rdapfile}"
proto=""
ip="${ip##* }"
[ -n "${ip}" ] && proto="v6"
fi
- if [ -n "${proto}" ] && ! "${ban_nftcmd}" get element inet banIP blocklist"${proto}" "{ ${ip} }" >/dev/null 2>&1 && ! "${ban_grepcmd}" -q "^${ip}" "${ban_allowlist}"; then
+ if [ -n "${proto}" ] && ! "${ban_nftcmd}" get element inet banIP allowlist"${proto}" "{ ${ip} }" >/dev/null 2>&1 && ! "${ban_nftcmd}" get element inet banIP blocklist"${proto}" "{ ${ip} }" >/dev/null 2>&1; then
f_log "info" "suspicious IP '${ip}'"
- log_raw="$("${ban_logreadcmd}" -l "${ban_loglimit}" 2>/dev/null)"
+ log_raw="$(eval ${loglimit_cmd})"
log_count="$(printf "%s\n" "${log_raw}" | "${ban_grepcmd}" -c "suspicious IP '${ip}'")"
if [ "${log_count}" -ge "${ban_logcount}" ]; then
if [ "${ban_autoblocksubnet}" = "1" ]; then
--- /dev/null
+#!/bin/sh
+# banIP cgi remote logging script - ban incoming and outgoing IPs via named nftables Sets
+# Copyright (c) 2018-2023 Dirk Brenken (dev@brenken.org)
+# This is free software, licensed under the GNU General Public License v3.
+
+# (s)hellcheck exceptions
+# shellcheck disable=all
+
+# handle post/get requests
+#
+post_string="$(cat)"
+request="${post_string//[^[:alnum:]=\.\:]/}"
+[ -z "${request}" ] && request="${QUERY_STRING//[^[:alnum:]=\.\:]/}"
+
+request_decode() {
+ local key value token
+
+ key="${request%=*}"
+ value="${request#*=}"
+ token="$(uci -q get banip.global.ban_remotetoken)"
+
+ if [ -n "${key}" ] && [ -n "${value}" ] && [ "${key}" = "${token}" ] && /etc/init.d/banip running; then
+ [ -r "/usr/lib/banip-functions.sh" ] && { . "/usr/lib/banip-functions.sh"; f_conf; }
+ if [ "${ban_remotelog}" = "1" ] && [ -x "${ban_logreadcmd}" ] && [ -n "${ban_logterm%%??}" ] && [ "${ban_loglimit}" != "0" ]; then
+ f_log "info" "received a suspicious remote IP '${value}'"
+ fi
+ fi
+}
+
+cat <<EOF
+Status: 202 Accepted
+Content-Type: text/plain; charset=UTF-8
+
+EOF
+
+request_decode
list ban_logterm 'error: maximum authentication attempts exceeded'
list ban_logterm 'sshd.*Connection closed by.*\[preauth\]'
list ban_logterm 'SecurityEvent=\"InvalidAccountID\".*RemoteAddress='
+ list ban_logterm 'received a suspicious remote IP '\''.*'\'''
},
"urlhaus":{
"url_4": "https://urlhaus.abuse.ch/downloads/ids/",
- "rule_4": "match($0,/(([0-9]{1,3}\\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5]))/){printf \"%s,\\n\",substr($0,RSTART,RLENGTH)}",
+ "rule_4": "match($0,/(content:\"([0-9]{1,3}\\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5]))/){printf \"%s,\\n\",substr($0,RSTART+9,RLENGTH-9)}",
"descr": "urlhaus IDS IPs"
},
"urlvir":{
[ "${action}" = "boot" ] && "${ban_init}" running && exit 0
{ [ "${action}" = "stop" ] || [ "${action}" = "report" ] || [ "${action}" = "search" ] || [ "${action}" = "survey" ] || [ "${action}" = "lookup" ]; } && ! "${ban_init}" running && exit 0
+[ ! -r "${ban_funlib}" ] && { [ "${action}" = "boot" ] || [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "stop" ] || [ "${action}" = "report" ] || [ "${action}" = "search" ] || [ "${action}" = "lookup" ] || [ "${action}" = "status" ]; } && exit 1
[ -d "${ban_lock}" ] && { [ "${action}" = "boot" ] || [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "lookup" ]; } && exit 1
[ ! -d "${ban_lock}" ] && { [ "${action}" = "boot" ] || [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "lookup" ]; } && mkdir -p "${ban_lock}"
}
start_service() {
+ [ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
if "${ban_init}" enabled; then
- [ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
f_rmpid
procd_open_instance "banip-service"
procd_set_param command "${ban_service}" "${@:-"${action}"}"
procd_set_param stderr 1
procd_close_instance
else
- [ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
f_log "err" "banIP service autostart is disabled"
rm -rf "${ban_lock}"
fi
include $(TOPDIR)/rules.mk
PKG_NAME:=cloudreve
-PKG_VERSION:=3.8.1
+PKG_VERSION:=3.8.3
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/cloudreve/Cloudreve.git
PKG_SOURCE_VERSION:=$(PKG_VERSION)
-PKG_MIRROR_HASH:=463e8580131c8a021b95ef7014f66556c7fdedad2c1b71627f9efaa86a758f03
+PKG_MIRROR_HASH:=b7945292c73993d47f251135c8dd06c8ecd8d22902594391213f446123d9fced
PKG_LICENSE:=GPL-3.0-only
PKG_LICENSE_FILES:=LICENSE
+++ /dev/null
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=cni-protocol
-PKG_VERSION:=20231008
-PKG_RELEASE:=1
-
-PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/cni-protocol
- SECTION:=net
- CATEGORY:=Network
- TITLE:=cni netifd protocol
- PKGARCH:=all
-endef
-
-define Package/cni-protocol/description
- protocol support for netavark/cni networks for netifd
- makes defining networks for podman and other similar
- systems easier and simple.
-
- with protocol, a network where firewall and portmapper
- management is disabled, control of firewalling, whether
- it was exposing ports, and forwarding to them from wan,
- or limiting/accepting access to other networks such
- as lan can made through openwrt's own firewalling
- configuration.
-
- example configuration could be as following:
- - lan network: 10.0.0.0/16 (255.255.0.0)
- - container network: 10.129.0.1/24 (255.255.255.0)
-
- Add a network configuration for your container network
- using cni protocol. Then create firewall zone for it.
-
- You could create a new container/pod with static ip
- address 10.129.0.2 (as 10.129.0.1 as container network's
- gateway).
-
- Easily define permissions so that local networks can
- connect to cni network, but not the other way around.
- Also you want to allow forwarding from/to wan.
-
- Now, as cni cannot access local dns, make a rule for
- your firewall to accept connections from cni network
- to port 53 (dns).
-
- Now all you have to do, is make redirects to your firewall
- and point them to 10.129.0.2 and connections from wan are
- redirectered to containers/pods.
-
- Protocol has 2 settings: device and delay. Sometimes polling
- interfaces takes some time, and in that case you might want
- to add few seconds to delay. Otherwise, it can be excluded
- from configuration.
-endef
-
-define Build/Configure
-endef
-
-define Build/Compile
-endef
-
-define Package/cni-protocol/install
- $(INSTALL_DIR) $(1)/lib/netifd/proto
- $(INSTALL_BIN) ./files/cni.sh $(1)/lib/netifd/proto/cni.sh
-endef
-
-$(eval $(call BuildPackage,cni-protocol))
+++ /dev/null
-#!/bin/sh
-
-[ -n "$INCLUDE_ONLY" ] || {
- . /lib/functions.sh
- . ../netifd-proto.sh
- init_proto "$@"
-}
-
-proto_cni_init_config() {
- no_device=0
- available=0
-
- proto_config_add_string "device:device"
- proto_config_add_int "delay"
-}
-
-proto_cni_setup() {
- local cfg="$1"
- local iface="$2"
- local device delay
-
- json_get_vars device delay
-
- [ -n "$device" ] || {
- echo "No cni interface specified"
- proto_notify_error "$cfg" NO_DEVICE
- proto_set_available "$cfg" 0
- return 1
- }
-
- [ -n "$delay" ] && sleep "$delay"
-
- [ -L "/sys/class/net/${iface}" ] || {
- echo "The specified interface $iface is not present"
- proto_notify_error "$cfg" NO_DEVICE
- proto_set_available "$cfg" 0
- return 1
- }
-
- local ipaddr netmask broadcast route routemask routesrc
-
- ipaddr=$(ip -4 -o a show "$iface" | awk '{ print $4 }' | cut -d '/' -f1)
- netmask=$(ip -4 -o a show "$iface" | awk '{ print $4 }' | cut -d '/' -f2)
- broadcast=$(ip -4 -o a show "$iface" | awk '{ print $6 }')
- route=$(ip -4 -o r show dev "$iface" | awk '{ print $1 }' | cut -d '/' -f1)
- routemask=$(ip -4 -o r show dev "$iface" | awk '{ print $1 }' | cut -d '/' -f2)
- routesrc=$(ip -4 -o r show dev "$iface" | awk '{ print $7 }')
-
- [ -z "$ipaddr" ] && {
- echo "interface $iface does not have ip address"
- proto_notify_error "$cfg" NO_IPADDRESS
- return 1
- }
-
- proto_init_update "$iface" 1
- [ -n "$ipaddr" ] && proto_add_ipv4_address "$ipaddr" "$netmask" "$broadcast" ""
- [ -n "$route" ] && proto_add_ipv4_route "$route" "$routemask" "" "$routesrc" ""
- proto_send_update "$cfg"
-}
-
-proto_cni_teardown() {
- local cfg="$1"
- return 0
-}
-
-[ -n "$INCLUDE_ONLY" ] || {
- add_protocol cni
-}
include $(TOPDIR)/rules.mk
PKG_NAME:=conntrack-tools
-PKG_VERSION:=1.4.7
+PKG_VERSION:=1.4.8
PKG_RELEASE:=1
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://www.netfilter.org/projects/conntrack-tools/files
-PKG_HASH:=099debcf57e81690ced57f516b493588a73518f48c14d656f823b29b4fc24b5d
+PKG_HASH:=067677f4c5f6564819e78ed3a9d4a8980935ea9273f3abb22a420ea30ab5ded6
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_LICENSE:=GPL-2.0-or-later
include $(TOPDIR)/rules.mk
PKG_NAME:=croc
-PKG_VERSION:=9.6.5
+PKG_VERSION:=9.6.6
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/schollz/croc/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=2d3ba7bae3c49e3870e2f8523c6be00e92fe6e46828269a8cea34d4034102cad
+PKG_HASH:=9dd954e0068df2be416c71161665bfc283f150d30ba0bf96cee723701e93616f
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_NAME:=crowdsec-firewall-bouncer
PKG_VERSION:=0.0.28
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/crowdsecurity/cs-firewall-bouncer/tar.gz/v$(PKG_VERSION)?
procd_set_param command "$PROG" -c "$VARCONFIG"
procd_set_param stdout 1
procd_set_param stderr 1
+ procd_set_param nice 10
+ if [ -x "/sbin/ujail" ]; then
+ procd_add_jail cs-bouncer log
+ procd_add_jail_mount $VARCONFIG
+ procd_add_jail_mount_rw /var/log/
+ procd_set_param no_new_privs 1
+ fi
procd_close_instance
fi
}
include $(TOPDIR)/rules.mk
PKG_NAME:=crowdsec
-PKG_VERSION:=1.5.4
+PKG_VERSION:=1.5.5
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/crowdsecurity/crowdsec/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=afa4021f77e9cb87d7fd11cd86146770836dc15cad1ae8a4edce1314b14be98a
+PKG_HASH:=ec7b2815405be4c3a1c9c3dcb1110030c29b7408dbf2a82d25537843c8831329
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
bool "HTTP2 protocol"
default y
+config LIBCURL_NGHTTP3
+ bool "HTTP/3 protocol"
+ depends on LIBCURL_OPENSSL
+ default n
+
+config LIBCURL_NGTCP2
+ bool "QUIC protocol"
+ depends on LIBCURL_OPENSSL
+ default n
+
comment "Miscellaneous"
config LIBCURL_PROXY
include $(INCLUDE_DIR)/nls.mk
PKG_NAME:=curl
-PKG_VERSION:=8.3.0
+PKG_VERSION:=8.5.0
PKG_RELEASE:=1
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://github.com/curl/curl/releases/download/curl-$(subst .,_,$(PKG_VERSION))/ \
https://dl.uxnr.de/mirror/curl/ \
https://curl.askapache.com/download/ \
https://curl.se/download/
-PKG_HASH:=376d627767d6c4f05105ab6d497b0d9aba7111770dd9d995225478209c37ea63
+PKG_HASH:=ce4b6a6655431147624aaf582632a36fe1ade262d5fab385c60f78942dd8d87b
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=COPYING
CONFIG_LIBCURL_TELNET \
CONFIG_LIBCURL_TFTP \
CONFIG_LIBCURL_NGHTTP2 \
+ CONFIG_LIBCURL_NGHTTP3 \
+ CONFIG_LIBCURL_NGTCP2 \
\
CONFIG_LIBCURL_COOKIES \
CONFIG_LIBCURL_CRYPTO_AUTH \
CATEGORY:=Libraries
DEPENDS:= +LIBCURL_WOLFSSL:libwolfssl +LIBCURL_OPENSSL:libopenssl +LIBCURL_GNUTLS:libgnutls +LIBCURL_MBEDTLS:libmbedtls
DEPENDS += +LIBCURL_ZLIB:zlib +LIBCURL_ZSTD:libzstd +LIBCURL_THREADED_RESOLVER:libpthread +LIBCURL_LDAP:libopenldap
- DEPENDS += +LIBCURL_LIBIDN2:libidn2 +LIBCURL_SSH2:libssh2 +LIBCURL_NGHTTP2:libnghttp2 +ca-bundle
+ DEPENDS += +LIBCURL_LIBIDN2:libidn2 +LIBCURL_SSH2:libssh2 +LIBCURL_NGHTTP2:libnghttp2 +LIBCURL_NGHTTP3:libnghttp3 +LIBCURL_NGTCP2:libngtcp2 +ca-bundle
TITLE:=A client-side URL transfer library
MENU:=1
ABI_VERSION:=4
$(if $(CONFIG_LIBCURL_ZLIB),--with-zlib="$(STAGING_DIR)/usr",--without-zlib) \
$(if $(CONFIG_LIBCURL_ZSTD),--with-zstd="$(STAGING_DIR)/usr",--without-zstd) \
$(if $(CONFIG_LIBCURL_NGHTTP2),--with-nghttp2="$(STAGING_DIR)/usr",--without-nghttp2) \
+ $(if $(CONFIG_LIBCURL_NGHTTP3),--with-nghttp3="$(STAGING_DIR)/usr",--without-nghttp3) \
+ $(if $(CONFIG_LIBCURL_NGTCP2),--with-ngtcp2="$(STAGING_DIR)/usr",--without-ngtcp2) \
\
$(call autoconf_bool,CONFIG_LIBCURL_DICT,dict) \
$(call autoconf_bool,CONFIG_LIBCURL_FILE,file) \
--- a/Makefile.am
+++ b/Makefile.am
-@@ -159,7 +159,7 @@ CLEANFILES = $(VC10_LIBVCXPROJ) $(VC10_S
+@@ -134,7 +134,7 @@ CLEANFILES = $(VC14_LIBVCXPROJ) \
bin_SCRIPTS = curl-config
SUBDIRS = lib src
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libcurl.pc
-@@ -273,8 +273,6 @@ cygwinbin:
+@@ -248,8 +248,6 @@ cygwinbin:
# We extend the standard install with a custom hook:
install-data-hook:
(cd include && $(MAKE) install)
PKG_NAME:=ddns-scripts
PKG_VERSION:=2.8.2
-PKG_RELEASE:=40
+PKG_RELEASE:=42
PKG_LICENSE:=GPL-2.0
ENDPOINT="route53.amazonaws.com"
RECORD_TTL=300
RECORD_NAME="${lookup_host}."
+RECORD_VALUE="${__IP}"
[ ${use_ipv6} -eq 0 ] && RECORD_TYPE="A"
[ ${use_ipv6} -eq 1 ] && RECORD_TYPE="AAAA"
-RECORD_VALUE="${LOCAL_IP}"
+
HOSTED_ZONE_ID="${domain}"
API_PATH="/2013-04-01/hostedzone/${HOSTED_ZONE_ID}/rrset/"
--- /dev/null
+{
+ "name": "ipnodns.ru",
+ "ipv4": {
+ "url": "https://ipnodns.ru/cgi-bin/dyndns.cgi?login=[USERNAME]&secret=[PASSWORD]",
+ "answer": "ok"
+ }
+}
he.net
hosting.de
infomaniak.com
+ipnodns.ru
inwx.de
joker.com
loopia.se
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=dhtd
+PKG_VERSION:=0.2.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/mwarning/dhtd/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=4d9d88dc9cb035742a86c451c6bd40a7e44161709cd962933516ef6c5170683d
+
+PKG_MAINTAINER:=Moritz Warning <moritzwarning@web.de>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/dhtd
+ SECTION:=net
+ CATEGORY:=Network
+ SUBMENU:=IP Addresses and Names
+ TITLE:=DHT Daemon
+ URL:=https://github.com/mwarning/dhtd
+endef
+
+define Package/dhtd/description
+ Standalone BitTorrent DHT daemon. Lookup and announce
+ hash identifiers via command line interface.
+endef
+
+MAKE_FLAGS += FEATURES="cli lpd"
+
+define Package/dhtd/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/build/dhtd $(1)/usr/bin/
+ $(LN) /usr/bin/dhtd $(1)/usr/bin/dhtd-ctl
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) files/dhtd.init $(1)/etc/init.d/dhtd
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_CONF) files/dhtd.config $(1)/etc/config/dhtd
+endef
+
+$(eval $(call BuildPackage,dhtd))
--- /dev/null
+##
+## DHTd is a distributed hash table daemon that uses the BitTorrent network.
+##
+
+config dhtd
+ option enabled 1
+
+## Add hashes to announce them to the network
+# list announce '00112233445566778899aabbcceeff0011223344'
+
+## Load and store good nodes every 24h and on start/shutdown.
+# option peerfile '/etc/dhtd/peers.txt'
+
+## Add static peer addresses.
+ list peer 'bttracker.debian.org:6881'
+ list peer 'router.bittorrent.com:6881'
+
+## Execute a script for each result
+# option execute '/root/on_result.sh'
+
+## Bind the DHT to this port.
+# option port '6881'
+
+## Limit DHT communication to this interface.
+# option ifname 'lan'
+
+## Verbosity: quiet, verbose or debug
+# option verbosity 'quiet'
+
+## Disable multicast peer discovery on the LAN.
+# option lpd_disable '1'
+
+## Path for dhtd-cli to connect to.
+# option cli_path '/tmp/dhtd.sock'
--- /dev/null
+#!/bin/sh /etc/rc.common
+
+START=95
+USE_PROCD=1
+PROG=/usr/bin/dhtd
+OPTS=""
+
+
+boot() {
+ # Wait for the loopback interface to be ready
+ ubus -t 30 wait_for network.interface network.loopback 2>/dev/null
+ rc_procd start_service
+}
+
+xappend() {
+ local name="$2" value="$1"
+ OPTS="$OPTS\n--${name//_/-} ${value//'/\\'}"
+}
+
+append_opts_list() {
+ local name cfg="$1"; shift
+ for name in $*; do
+ config_list_foreach "$cfg" "$name" xappend "$name"
+ done
+}
+
+append_opts() {
+ local name value cfg="$1"; shift
+ for name in $*; do
+ config_get value "$cfg" "$name"
+ [ -n "$value" ] && xappend "$value" "$name"
+ done
+}
+
+append_opts_boolean() {
+ local name value cfg="$1"; shift
+ for name in $*; do
+ config_get_bool value "$cfg" "$name" 0
+ [ $value -gt 0 ] && xappend '' $name
+ done
+}
+
+section_enabled() {
+ config_get_bool enabled "$1" 'enabled' 0
+ [ $enabled -gt 0 ]
+}
+
+start_instance() {
+ local cfg="$1"
+ local CONFIG_FILE=/tmp/dhtd.${cfg}.conf
+
+ section_enabled "$cfg" || return
+ . /lib/functions/network.sh
+
+ OPTS=""
+
+ append_opts "$cfg" verbosity peerfile port execute
+
+ config_get ifname "$cfg" "ifname"
+ if network_get_device IFNAME "$ifname";then
+ xappend "$IFNAME" "ifname"
+ else
+ [ -n "$ifname" ] && xappend "$ifname" "ifname"
+ fi
+
+ append_opts_list "$cfg" announce peer
+
+ append_opts_boolean "$cfg" lpd_disable ipv4 ipv6
+
+ # Close stdin when command line interface is present
+ if [ $($PROG --version | grep -c cli) -eq 1 ]; then
+ xappend "" "cli_disable_stdin"
+ fi
+
+ echo -e "$OPTS" > $CONFIG_FILE
+
+ procd_open_instance
+ procd_set_param command $PROG
+ procd_set_param file $CONFIG_FILE
+ procd_set_param stderr 1
+ procd_set_param stdout 1
+ procd_append_param command --config $CONFIG_FILE
+ procd_close_instance
+}
+
+stop_instance() {
+ local cfg="$1"
+ local CONFIG_FILE=/tmp/dhtd.${cfg}.conf
+
+ rm -f $CONFIG_FILE
+}
+
+add_interface_trigger() {
+ local ifname
+
+ config_get ifname "$1" ifname
+
+ [ -n "$ifname" ] && procd_add_interface_trigger "interface.*" "$ifname" /etc/init.d/dhtd restart
+}
+
+service_triggers() {
+ procd_add_reload_trigger "dhtd"
+
+ config_load dhtd
+ config_foreach add_interface_trigger dhtd
+}
+
+start_service() {
+ config_load 'dhtd'
+ config_foreach start_instance 'dhtd'
+}
+
+stop_service() {
+ config_load 'dhtd'
+ config_foreach stop_instance 'dhtd'
+}
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsdist
-PKG_VERSION:=1.8.1
+PKG_VERSION:=1.8.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://downloads.powerdns.com/releases/
-PKG_HASH:=05f356fcce29c4ece03c2d8df046adff3aaab0b036d6801c1a311c6d5bb3c07f
+PKG_HASH:=6688f09b2c52f9bf935f0769f4ee28dd0760e5622dade7b3f4e6fa3776f07ab8
PKG_MAINTAINER:=Peter van Dijk <peter.van.dijk@powerdns.com>
PKG_LICENSE:=GPL-2.0-only
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsproxy
-PKG_VERSION:=0.56.0
+PKG_VERSION:=0.60.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/AdguardTeam/dnsproxy/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=841a83d2bc7f186fb83d5187993ebb21855afa827a9cdc6f976201feb7fcf3f7
+PKG_HASH:=4af8d4b0fd5522c41b9370bd2fe102af8fcaa2b48bd6664d1252b55a6d2fe8d4
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
PKG_LICENSE:=Apache-2.0
$(INSTALL_CONF) $(CURDIR)/files/dnsproxy.config $(1)/etc/config/dnsproxy
$(INSTALL_DIR) $(1)/etc/init.d/
$(INSTALL_BIN) $(CURDIR)/files/dnsproxy.init $(1)/etc/init.d/dnsproxy
+ $(INSTALL_DIR) $(1)/etc/uci-defaults/
+ $(INSTALL_BIN) $(CURDIR)/files/dnsproxy.defaults $(1)/etc/uci-defaults/80-dnsproxy-migration
endef
define Package/dnsproxy/conffiles
config dnsproxy 'global'
option enabled '0'
- option listen_addr '127.0.0.1'
- option listen_port '5353'
+ list listen_addr '127.0.0.1'
+ list listen_addr '::1'
+ list listen_port '5353'
option log_file ''
option all_servers '0'
option fastest_addr '0'
+ option http3 '0'
option insecure '0'
option ipv6_disabled '0'
+ option timeout ''
option max_go_routines ''
option rate_limit ''
option refuse_any '0'
--- /dev/null
+#!/bin/sh
+
+[ -s "/etc/config/dnsproxy" ] || exit 0
+
+#Migrate options 'listen_addr' 'listen_port' to list type
+sed -i -e "s,option listen_addr,list listen_addr,g" \
+ -e "s,option listen_port,list listen_port,g" "/etc/config/dnsproxy"
+exit 0
load_config_arg() {
append_param_bool "$1" "all_servers"
append_param_bool "$1" "fastest_addr"
+ append_param_bool "$1" "http3"
append_param_bool "$1" "insecure"
append_param_bool "$1" "ipv6_disabled"
append_param_bool "$1" "refuse_any"
}
load_config_list() {
+ if is_empty "global" "listen_addr"; then
+ append_param "--listen" "127.0.0.1"
+ else
+ config_list_foreach "global" "listen_addr" "append_param '--listen'"
+ fi
+
+ if is_empty "global" "listen_port"; then
+ append_param "--port" "5353"
+ else
+ config_list_foreach "global" "listen_port" "append_param '--port'"
+ fi
+
is_empty "bogus_nxdomain" "ip_addr" || config_list_foreach "bogus_nxdomain" "ip_addr" "append_param '--bogus-nxdomain'"
for i in "bootstrap" "fallback" "upstream"; do
}
load_config_param() {
- append_param_arg "global" "listen_addr" "--listen" "127.0.0.1"
- append_param_arg "global" "listen_port" "--port" "5353"
append_param_arg "global" "log_file" "--output"
+ append_param_arg "global" "timeout" "--timeout"
append_param_arg "global" "max_go_routines" "--max-go-routines"
append_param_arg "global" "rate_limit" "--ratelimit"
append_param_arg "global" "udp_buf_size" "--udp-buf-size"
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=external-protocol
+PKG_VERSION:=20231119
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/external-protocol
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=externally managed protocol
+ PKGARCH:=all
+endef
+
+define Package/external-protocol/description
+ external protocol is a general protocol for assisting
+ setup of many virtual devices that lack proper
+ protocol support in openwrt. Such as netavark, cni and
+ netbird for example. External protocol is supposed
+ to be managed with external software, not directly.
+
+ external protocol works automaticly on the background
+ and sets up netifd details when interface comes up or
+ goes down. This allows one to easily add interface to
+ a firewall zone.
+
+ as a example use case, podman, with network where it's
+ internal firewall and portmapper are disabled, control
+ of firewalling, whether it was exposing ports or
+ limiting/accepting access between networks, such as
+ lan can be made through openwrt's own firewalling
+ configuration if you used external protocol.
+
+ podman example configuration could be as following:
+ - lan network: 10.0.0.0/16 (255.255.0.0)
+ - container network: 10.129.0.1/24 (255.255.255.0)
+
+ Add a network configuration for your container network
+ using external protocol. Then create firewall zone for it.
+
+ You could create a new container/pod with static ip
+ address 10.129.0.2 (as 10.129.0.1 as container network's
+ gateway).
+
+ Easily define permissions so that local networks can
+ connect to container network, but not the other way around.
+ Also you want to allow forwarding from/to wan.
+
+ Now, as container cannot access local dns, make a rule for
+ your firewall to accept connections from container network
+ to port 53 (dns).
+
+ Now all you have to do, is make redirects to your firewall
+ and point them to 10.129.0.2 and connections from wan are
+ redirectered to containers/pods.
+
+ external protocol also works for other applications as
+ well that are using veth/tun/etc devices and don't have
+ a hand-tailored protocol available, such as vpn service
+ netbird.
+
+ Protocol has 3 settings: device, searchdomain and delay.
+ Sometimes polling interfaces takes some time, and in
+ that case you might want to add few seconds to delay.
+ Otherwise, it can be excluded from configuration.
+ Option for searchdomain is also completely optional.
+
+ package was previously known as cni protocol but as
+ it can be used on so many other things, naming became
+ mis-leading and it was renamed to external protocol.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/external-protocol/install
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/external.sh $(1)/lib/netifd/proto/external.sh
+endef
+
+$(eval $(call BuildPackage,external-protocol))
--- /dev/null
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_external_init_config() {
+ no_device=0
+ available=0
+
+ proto_config_add_string "device:device"
+ proto_config_add_string "searchdomain"
+ proto_config_add_int "delay"
+}
+
+proto_external_setup() {
+ local cfg="$1"
+ local iface="$2"
+ local device searchdomain delay
+
+ json_get_vars device searchdomain delay
+
+ [ -n "$device" ] || {
+ echo "External protocol interface is not specified"
+ proto_notify_error "$cfg" NO_DEVICE
+ proto_set_available "$cfg" 0
+ return 1
+ }
+
+ [ -n "$delay" ] && sleep "$delay"
+
+ [ -L "/sys/class/net/${iface}" ] || {
+ echo "External protocol interface $iface is not present"
+ proto_notify_error "$cfg" NO_DEVICE
+ proto_set_available "$cfg" 0
+ return 1
+ }
+
+ IP4ADDRS=
+ IP6ADDRS=
+
+ local addresses="$(ip -json address list dev "$iface")"
+ json_init
+ json_load "{\"addresses\":${addresses}}"
+
+ if json_is_a addresses array; then
+ json_select addresses
+ json_select 1
+
+ if json_is_a addr_info array; then
+ json_select addr_info
+
+ local i=1
+ while json_is_a ${i} object; do
+ json_select ${i}
+ json_get_vars scope family local prefixlen broadcast
+
+ if [ "${scope}" == "global" ]; then
+ case "${family}" in
+ inet)
+ append IP4ADDRS "$local/$prefixlen/$broadcast/"
+ ;;
+
+ inet6)
+ append IP6ADDRS "$local/$prefixlen/$broadcast///"
+ ;;
+ esac
+ fi
+
+ json_select ..
+ i=$(( i + 1 ))
+ done
+ fi
+ fi
+
+ IP4ROUTES=
+ IP6ROUTES=
+
+ local routes="$(ip -json route list dev "$iface")"
+ json_init
+ json_load "{\"routes\":${routes}}"
+
+ if json_is_a routes array;then
+ json_select routes
+
+ local i=1
+ while json_is_a ${i} object; do
+ json_select ${i}
+ json_get_vars dst gateway metric prefsrc
+
+ case "${dst}" in
+ *:*/*)
+ append IP6ROUTES "$dst/$gateway/$metric///$prefsrc"
+ ;;
+ *.*/*)
+ append IP4ROUTES "$dst/$gateway/$metric///$prefsrc"
+ ;;
+ *:*)
+ append IP6ROUTES "$dst/128/$gateway/$metric///$prefsrc"
+ ;;
+ *.*)
+ append IP4ROUTES "$dst/32/$gateway/$metric///$prefsrc"
+ ;;
+ esac
+
+ json_select ..
+ i=$(( i + 1 ))
+ done
+ fi
+
+ [ -z "${IP4ADDRS}" -a -z "${IP6ADDRS}" ] && {
+ echo "interface $iface does not have ip address"
+ proto_notify_error "$cfg" NO_IPADDRESS
+ return 1
+ }
+
+ proto_init_update "$iface" 1
+
+ PROTO_IPADDR="${IP4ADDRS}"
+ PROTO_IP6ADDR="${IP6ADDRS}"
+
+ PROTO_ROUTE="${IP4ROUTES}"
+ PROTO_ROUTE6="${IP6ROUTES}"
+
+ [ -n "$searchdomain" ] && proto_add_dns_search "$searchdomain"
+
+ echo "$iface is up"
+
+ proto_send_update "$cfg"
+}
+
+proto_external_teardown() {
+ local cfg="$1"
+ return 0
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol external
+}
PKG_NAME:=fail2ban
PKG_VERSION:=0.11.2
-PKG_RELEASE:=8
+PKG_RELEASE:=9
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/fail2ban/fail2ban/tar.gz/$(PKG_VERSION)?
--- /dev/null
+From 7e2ab36d86998575853150c0a57de5e22518cf66 Mon Sep 17 00:00:00 2001
+From: sebres <info@sebres.de>
+Date: Tue, 21 Jun 2022 16:55:57 +0200
+Subject: [PATCH] move global groups to start of expression (python 3.11
+ compat)
+
+[remove change to regex not in 0.11.2]
+Signed-off-by: Jeffery To <jeffery.to@gmail.com>
+---
+ fail2ban/client/fail2banregex.py | 2 +-
+ fail2ban/server/datetemplate.py | 8 ++++++++
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+--- a/fail2ban/server/datetemplate.py
++++ b/fail2ban/server/datetemplate.py
+@@ -35,6 +35,7 @@ logSys = getLogger(__name__)
+ # check already grouped contains "(", but ignores char "\(" and conditional "(?(id)...)":
+ RE_GROUPED = re.compile(r'(?<!(?:\(\?))(?<!\\)\((?!\?)')
+ RE_GROUP = ( re.compile(r'^((?:\(\?\w+\))?\^?(?:\(\?\w+\))?)(.*?)(\$?)$'), r"\1(\2)\3" )
++RE_GLOBALFLAGS = re.compile(r'((?:^|(?!<\\))\(\?[a-z]+\))')
+
+ RE_EXLINE_NO_BOUNDS = re.compile(r'^\{UNB\}')
+ RE_EXLINE_BOUND_BEG = re.compile(r'^\{\^LN-BEG\}')
+@@ -110,6 +111,11 @@ class DateTemplate(object):
+ # because it may be very slow in negative case (by long log-lines not matching pattern)
+
+ regex = regex.strip()
++ # cut global flags like (?iu) from RE in order to pre-set it after processing:
++ gf = RE_GLOBALFLAGS.search(regex)
++ if gf:
++ regex = RE_GLOBALFLAGS.sub('', regex, count=1)
++ # check word boundaries needed:
+ boundBegin = wordBegin and not RE_NO_WRD_BOUND_BEG.search(regex)
+ boundEnd = wordEnd and not RE_NO_WRD_BOUND_END.search(regex)
+ # if no group add it now, should always have a group(1):
+@@ -135,6 +141,8 @@ class DateTemplate(object):
+ self.flags |= DateTemplate.LINE_END
+ # remove possible special pattern "**" in front and end of regex:
+ regex = RE_DEL_WRD_BOUNDS[0].sub(RE_DEL_WRD_BOUNDS[1], regex)
++ if gf: # restore global flags:
++ regex = gf.group(1) + regex
+ self._regex = regex
+ logSys.log(7, ' constructed regex %s', regex)
+ self._cRegex = None
--- /dev/null
+From 4337e366163278815ea9fc6c952bffb579e885a0 Mon Sep 17 00:00:00 2001
+From: sebres <info@sebres.de>
+Date: Tue, 21 Jun 2022 16:56:57 +0200
+Subject: [PATCH] wrap global flags like ((?i)xxx) or (?:(?i)xxx) to local
+ flags (?i:xxx) if supported by RE-engine in the python version
+
+---
+ fail2ban/server/failregex.py | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/fail2ban/server/failregex.py
++++ b/fail2ban/server/failregex.py
+@@ -91,6 +91,13 @@ R_MAP = {
+ "port": "fport",
+ }
+
++# map global flags like ((?i)xxx) or (?:(?i)xxx) to local flags (?i:xxx) if supported by RE-engine in this python version:
++try:
++ re.search("^re(?i:val)$", "reVAL")
++ R_GLOB2LOCFLAGS = ( re.compile(r"(?<!\\)\((?:\?:)?(\(\?[a-z]+)\)"), r"\1:" )
++except:
++ R_GLOB2LOCFLAGS = ()
++
+ def mapTag2Opt(tag):
+ tag = tag.lower()
+ return R_MAP.get(tag, tag)
+@@ -128,6 +135,9 @@ class Regex:
+ #
+ if regex.lstrip() == '':
+ raise RegexException("Cannot add empty regex")
++ # special handling wrapping global flags to local flags:
++ if R_GLOB2LOCFLAGS:
++ regex = R_GLOB2LOCFLAGS[0].sub(R_GLOB2LOCFLAGS[1], regex)
+ try:
+ self._regexObj = re.compile(regex, re.MULTILINE if multiline else 0)
+ self._regex = regex
include $(TOPDIR)/rules.mk
PKG_NAME:=freeradius3
-PKG_VERSION:=3.0.26
-PKG_RELEASE:=1
+PKG_VERSION:=3_0_26
+PKG_RELEASE:=4
-PKG_SOURCE:=freeradius-server-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=https://github.com/FreeRADIUS/freeradius-server/releases/download/release_$(subst .,_,$(PKG_VERSION))/
-PKG_HASH:=9a65314c462da4d4c4204df72c45f210de671f89317299b01f78549ac4503f59
+PKG_SOURCE:=release_$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/FreeRADIUS/freeradius-server/tar.gz/release_$(PKG_VERSION)?
+PKG_HASH:=6aea98d6126035e7ccca483d8b3faea447030169639807017ec98985b78fb2ca
PKG_MAINTAINER:=
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYRIGHT LICENSE
PKG_CPE_ID:=cpe:/a:freeradius:freeradius
-PKG_BUILD_DIR:=$(BUILD_DIR)/freeradius-server-$(PKG_VERSION)
+PKG_BUILD_DIR:=$(BUILD_DIR)/freeradius-server-release_$(PKG_VERSION)
PKG_FIXUP:=autoreconf
PYTHON3_PKG_BUILD:=0
define Package/freeradius3-common
$(call Package/freeradius3/Default)
TITLE:=common files
- DEPENDS:=+USE_GLIBC:libpthread +USE_GLIBC:libbsd +FREERADIUS3_OPENSSL:libopenssl +libcap +libpcap +libncurses +libpcre +libreadline +libtalloc +libatomic
+ DEPENDS:=+USE_GLIBC:libpthread +USE_GLIBC:libbsd +FREERADIUS3_OPENSSL:libopenssl +libcap +libpcap +libncurses +libreadline +libtalloc +libatomic
endef
define Package/freeradius3-default
/etc/freeradius3/mods-config/attr_filter/access_challenge
/etc/freeradius3/mods-config/attr_filter/access_reject
/etc/freeradius3/mods-config/attr_filter/accounting_response
+/etc/freeradius3/mods-config/attr_filter/coa
/etc/freeradius3/mods-config/attr_filter/post-proxy
/etc/freeradius3/mods-config/attr_filter/pre-proxy
endef
-define Package/freeradius3-mod-attr-rewrite
- $(call Package/freeradius3/Default)
- DEPENDS:=freeradius3
- TITLE:=ATTR rewrite module
-endef
-
define Package/freeradius3-mod-chap
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3
/etc/freeradius3/mods-enabled/chap
endef
+define Package/freeradius3-mod-counter
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3 +libgdbm
+ TITLE:=Module counter
+endef
+
+define Package/freeradius3-mod-counter/conffiles
+/etc/freeradius3/mods-available/counter
+endef
+
+define Package/freeradius3-mod-date
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=Module date
+endef
+
+define Package/freeradius3-mod-date/conffiles
+/etc/freeradius3/mods-available/date
+endef
+
define Package/freeradius3-mod-detail
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3
/etc/freeradius3/mods-enabled/digest
endef
+define Package/freeradius3-mod-dynamic-clients
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=Dynamic Clients Authentication
+endef
+
+define Package/freeradius3-mod-dynamic-clients/conffiles
+/etc/freeradius3/mods-available/dynamic_clients
+/etc/freeradius3/sites-available/dynamic-clients
+endef
+
define Package/freeradius3-mod-eap
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3
/etc/freeradius3/sites-available/inner-tunnel
endef
+define Package/freeradius3-mod-eap-fast
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3-mod-eap @FREERADIUS3_OPENSSL
+ TITLE:=EAP/FAST module
+endef
+
define Package/freeradius3-mod-eap-gtc
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3-mod-eap
/etc/freeradius3/mods-config/files/pre-proxy
endef
+define Package/freeradius3-mod-ippool
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3 +libgdbm
+ TITLE:=Radius IP Pool module
+endef
+
+define Package/freeradius3-mod-ippool/conffiles
+/etc/freeradius3/mods-available/ippool
+endef
+
+define Package/freeradius3-mod-krb5
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3 +krb5-libs
+ TITLE:=Krb5 module
+endef
+
+define Package/freeradius3-mod-krb5/conffiles
+/etc/freeradius3/mods-available/krb5
+endef
+
define Package/freeradius3-mod-ldap
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3 +libopenldap @FREERADIUS3_OPENSSL
/etc/freeradius3/mods-available/ldap
endef
+define Package/freeradius3-mod-linelog
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=Linelog module
+endef
+
+define Package/freeradius3-mod-linelog/conffiles
+/etc/freeradius3/mods-available/linelog
+endef
+
define Package/freeradius3-mod-logintime
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3
/etc/freeradius3/mods-enabled/mschap
endef
+define Package/freeradius3-mod-pam
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3 +libpam
+ TITLE:=PAM module
+endef
+
+define Package/freeradius3-mod-pam/conffiles
+/etc/freeradius3/mods-available/pam
+endef
+
define Package/freeradius3-mod-pap
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3
/etc/freeradius3/mods-enabled/realm
endef
+define Package/freeradius3-mod-redis
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3 +libhiredis
+ TITLE:=Redis module
+endef
+
+define Package/freeradius3-mod-redis/conffiles
+/etc/freeradius3/mods-available/redis
+endef
+
+define Package/freeradius3-mod-rediswho
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3 freeradius3-mod-redis
+ TITLE:=Rediswho module
+endef
+
+define Package/freeradius3-mod-rediswho/conffiles
+/etc/freeradius3/mods-available/rediswho
+endef
+
+define Package/freeradius3-mod-replicate
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=Replicate module
+endef
+
+define Package/freeradius3-mod-replicate/conffiles
+/etc/freeradius3/mods-available/replicate
+endef
+
define Package/freeradius3-mod-rest
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3 +libcurl +libjson-c
/etc/freeradius3/mods-available/rest
endef
+define Package/freeradius3-mod-soh
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=SoH module
+endef
+
+define Package/freeradius3-mod-soh/conffiles
+/etc/freeradius3/mods-available/soh
+/etc/freeradius3/sites-available/soh
+endef
+
+define Package/freeradius3-mod-sometimes
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=Sometimes module
+endef
+
+define Package/freeradius3-mod-sometimes/conffiles
+/etc/freeradius3/mods-available/sometimes
+endef
+
define Package/freeradius3-mod-sql
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3
/etc/freeradius3/mods-available/sql
endef
+define Package/freeradius3-mod-sql-map
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=Map module
+endef
+
+define Package/freeradius3-mod-map/conffiles
+/etc/freeradius3/mods-available/sql_map
+endef
+
define Package/freeradius3-mod-sql-mysql
$(call Package/freeradius3/Default)
DEPENDS:=freeradius3-mod-sql +libmysqlclient
define Package/freeradius3-mod-sqlcounter
$(call Package/freeradius3/Default)
DEPENDS:=+freeradius3-mod-sql
- TITLE:=Packet counter using accounting records written into an SQL database
+ TITLE:=Module sqlcounter
endef
define Package/freeradius3-mod-sqlcounter/conffiles
/etc/freeradius3/mods-enabled/unix
endef
+define Package/freeradius3-mod-unpack
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=Unpack module
+endef
+
+define Package/freeradius3-mod-unpack/conffiles
+/etc/freeradius3/mods-available/unpack
+endef
+
+define Package/freeradius3-mod-utf8
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=UTF8 module
+endef
+
+define Package/freeradius3-mod-utf8/conffiles
+/etc/freeradius3/mods-available/utf8
+endef
+
+define Package/freeradius3-mod-wimax
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3
+ TITLE:=Wimax Authentication
+endef
+
+define Package/freeradius3-mod-wimax/conffiles
+/etc/freeradius3/mods-available/wimax
+endef
+
+define Package/freeradius3-mod-yubikey
+ $(call Package/freeradius3/Default)
+ DEPENDS:=freeradius3 +libyubikey +ykclient
+ TITLE:=Yubikey Authentication
+endef
+
+define Package/freeradius3-mod-yubikey/conffiles
+/etc/freeradius3/mods-available/yubikey
+endef
+
define Package/freeradius3-utils
$(call Package/freeradius3/Default)
DEPENDS:=+freeradius3-common
--with-raddbdir=/etc/freeradius3 \
--with-radacctdir=/var/db/radacct \
--with-logdir=/var/log \
- --without-edir \
- --without-snmp \
+ --without-pcre \
--without-rlm_cache \
--without-rlm_cache_memcached \
--without-rlm_couchbase \
- --without-rlm_counter \
--without-rlm_eap_ikev2 \
--without-rlm_eap_sim \
--without-rlm_eap_tnc \
- --without-rlm_example \
- --without-rlm_idn \
- --without-rlm_ippool \
- --without-rlm_krb5 \
- --without-rlm_opendirectory \
- --without-rlm_pam \
--without-rlm_perl \
--without-rlm_python \
- --without-rlm_redis \
- --without-rlm_rediswho \
- --without-rlm_ruby \
- --without-rlm_securid \
- --without-rlm_smsotp \
--without-rlm_sql_db2 \
--without-rlm_sql_firebird \
--without-rlm_sql_freetds \
--without-rlm_sql_iodbc \
--without-rlm_sql_oracle \
--without-rlm_sql_unixodbc \
- --without-rlm_unbound \
- --without-rlm_yubikey \
CONFIGURE_LIBS+= -latomic
compat \
freeradius freeradius.internal \
rfc2865 rfc2866 rfc2867 rfc2868 rfc2869 rfc3162 rfc3576 rfc3580 \
- rfc4372 rfc4675 rfc4679 rfc5580\
+ rfc4072 rfc4372 rfc4675 rfc4679 rfc5580 rfc6911 \
microsoft \
wispr \
+ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius3-mod-eap-fast),)
+ CONFIGURE_ARGS+= \
+ --with-rlm_eap_fast \
+ --with-rlm_eap_fast-include-dir="$(STAGING_DIR)/usr/include" \
+ --with-rlm_eap_fast-lib-dir="$(STAGING_DIR)/usr/lib"
+ CONFIGURE_LIBS+= -lcrypto -lssl
+else
+ CONFIGURE_ARGS+= --without-rlm_eap_fast
+endif
+
ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius3-mod-eap-peap),)
CONFIGURE_ARGS+= \
--with-rlm_eap_peap \
CONFIGURE_ARGS+= --without-rlm_eap_ttls
endif
+ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius3-mod-ippool),)
+ CONFIGURE_ARGS+= --with-rlm_ippool \
+ --with-rlm_ippool-include-dir="$(STAGING_DIR)/usr/include" \
+ --with-rlm_ippool-lib-dir="$(STAGING_DIR)/usr/lib"
+else
+ CONFIGURE_ARGS+= --without-rlm_ippool
+endif
+
ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius3-mod-ldap),)
CONFIGURE_ARGS+= --with-rlm_ldap \
--with-rlm_ldap-include-dir="$(STAGING_DIR)/usr/include" \
CONFIGURE_ARGS+= --without-rlm_radutmp
endif
+ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius3-mod-redis),)
+ CONFIGURE_ARGS+= \
+ --with-rlm_redis \
+ --with-rlm_redis-include-dir="$(STAGING_DIR)/usr/include" \
+ --with-rlm_redis-lib-dir="$(STAGING_DIR)/usr/lib"
+else
+ CONFIGURE_ARGS+= --without-rlm_redis
+endif
+
+ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius3-mod-rediswho),)
+ CONFIGURE_ARGS+= \
+ --with-rlm_rediswho \
+ --with-rlm_rediswho-include-dir="$(STAGING_DIR)/usr/include" \
+ --with-rlm_rediswho-lib-dir="$(STAGING_DIR)/usr/lib"
+else
+ CONFIGURE_ARGS+= --without-rlm_rediswho
+endif
+
ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius3-mod-rest),)
CONFIGURE_ARGS+= --with-rlm_rest
else
CONFIGURE_ARGS+= --without-rlm_unix
endif
+ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius3-mod-yubikey),)
+ CONFIGURE_ARGS+= \
+ --with-rlm_yubikey \
+ --with-rlm_yubikey-include-dir="$(STAGING_DIR)/usr/include" \
+ --with-rlm_yubikey-lib-dir="$(STAGING_DIR)/usr/lib"
+else
+ CONFIGURE_ARGS+= --without-rlm_yubikey
+endif
+
ifeq ($(CONFIG_USE_GLIBC),y)
TARGET_CFLAGS+= -DLIBBSD_OVERLAY -I$(STAGING_DIR)/usr/include/bsd \
-D_RPC_NETDB_H
$(eval $(call BuildPlugin,freeradius3-mod-always,rlm_always,))
$(eval $(call BuildPlugin,freeradius3-mod-attr-filter,rlm_attr_filter,))
$(eval $(call BuildPlugin,freeradius3-mod-chap,rlm_chap,))
+$(eval $(call BuildPlugin,freeradius3-mod-counter,rlm_counter,))
+$(eval $(call BuildPlugin,freeradius3-mod-date,rlm_date,))
$(eval $(call BuildPlugin,freeradius3-mod-detail,rlm_detail,))
$(eval $(call BuildPlugin,freeradius3-mod-digest,rlm_digest,))
+$(eval $(call BuildPlugin,freeradius3-mod-dynamic-clients,rlm_dynamic_clients,))
$(eval $(call BuildPlugin,freeradius3-mod-eap,rlm_eap,))
+$(eval $(call BuildPlugin,freeradius3-mod-eap-fast,rlm_eap_fast,))
$(eval $(call BuildPlugin,freeradius3-mod-eap-gtc,rlm_eap_gtc,))
$(eval $(call BuildPlugin,freeradius3-mod-eap-md5,rlm_eap_md5,))
$(eval $(call BuildPlugin,freeradius3-mod-eap-mschapv2,rlm_eap_mschapv2,))
$(eval $(call BuildPlugin,freeradius3-mod-expiration,rlm_expiration,))
$(eval $(call BuildPlugin,freeradius3-mod-expr,rlm_expr,))
$(eval $(call BuildPlugin,freeradius3-mod-files,rlm_files,))
+$(eval $(call BuildPlugin,freeradius3-mod-ippool,rlm_ippool,))
+$(eval $(call BuildPlugin,freeradius3-mod-krb5,rlm_krb5,))
$(eval $(call BuildPlugin,freeradius3-mod-ldap,rlm_ldap,))
+$(eval $(call BuildPlugin,freeradius3-mod-linelog,rlm_linelog,))
$(eval $(call BuildPlugin,freeradius3-mod-logintime,rlm_logintime,))
$(eval $(call BuildPlugin,freeradius3-mod-mschap,rlm_mschap,))
+$(eval $(call BuildPlugin,freeradius3-mod-pam,rlm_pam,))
$(eval $(call BuildPlugin,freeradius3-mod-pap,rlm_pap,))
$(eval $(call BuildPlugin,freeradius3-mod-passwd,rlm_passwd,))
$(eval $(call BuildPlugin,freeradius3-mod-preprocess,rlm_preprocess,))
$(eval $(call BuildPlugin,freeradius3-mod-python3,rlm_python3,))
$(eval $(call BuildPlugin,freeradius3-mod-radutmp,rlm_radutmp,))
$(eval $(call BuildPlugin,freeradius3-mod-realm,rlm_realm,))
+$(eval $(call BuildPlugin,freeradius3-mod-redis,rlm_redis,))
+$(eval $(call BuildPlugin,freeradius3-mod-rediswho,rlm_rediswho,))
+$(eval $(call BuildPlugin,freeradius3-mod-replicate,rlm_replicate,))
$(eval $(call BuildPlugin,freeradius3-mod-rest,rlm_rest,))
+$(eval $(call BuildPlugin,freeradius3-mod-soh,rlm_soh,))
+$(eval $(call BuildPlugin,freeradius3-mod-sometimes,rlm_sometimes,))
$(eval $(call BuildPlugin,freeradius3-mod-sql,rlm_sql,))
+$(eval $(call BuildPlugin,freeradius3-mod-sql-map,rlm_sql_map,))
$(eval $(call BuildPlugin,freeradius3-mod-sql-mysql,rlm_sql_mysql,))
$(eval $(call BuildPlugin,freeradius3-mod-sql-null,rlm_sql_null,))
$(eval $(call BuildPlugin,freeradius3-mod-sql-postgresql,rlm_sql_postgresql,))
$(eval $(call BuildPlugin,freeradius3-mod-sqlcounter,rlm_sqlcounter,))
$(eval $(call BuildPlugin,freeradius3-mod-sqlippool,rlm_sqlippool,))
$(eval $(call BuildPlugin,freeradius3-mod-unix,rlm_unix,))
+$(eval $(call BuildPlugin,freeradius3-mod-unpack,rlm_unpack,))
+$(eval $(call BuildPlugin,freeradius3-mod-utf8,rlm_utf8,))
+$(eval $(call BuildPlugin,freeradius3-mod-wimax,rlm_wimax,))
+$(eval $(call BuildPlugin,freeradius3-mod-yubikey,rlm_yubikey,))
$(eval $(call BuildPackage,freeradius3-utils))
--- /dev/null
+--- a/src/modules/rlm_krb5/configure
++++ b/src/modules/rlm_krb5/configure
+@@ -1,10 +1,11 @@
+ #! /bin/sh
+ # From configure.ac Revision.
+ # Guess values for system-dependent variables and create Makefiles.
+-# Generated by GNU Autoconf 2.69.
++# Generated by GNU Autoconf 2.71.
+ #
+ #
+-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
++# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
++# Inc.
+ #
+ #
+ # This configure script is free software; the Free Software Foundation
+@@ -15,14 +16,16 @@
+
+ # Be more Bourne compatible
+ DUALCASE=1; export DUALCASE # for MKS sh
+-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
++as_nop=:
++if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
++then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+-else
++else $as_nop
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+@@ -32,46 +35,46 @@ esac
+ fi
+
+
++
++# Reset variables that may have inherited troublesome values from
++# the environment.
++
++# IFS needs to be set, to space, tab, and newline, in precisely that order.
++# (If _AS_PATH_WALK were called with IFS unset, it would have the
++# side effect of setting IFS to empty, thus disabling word splitting.)
++# Quoting is to prevent editors from complaining about space-tab.
+ as_nl='
+ '
+ export as_nl
+-# Printing a long string crashes Solaris 7 /usr/bin/printf.
+-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+-# Prefer a ksh shell builtin over an external printf program on Solaris,
+-# but without wasting forks for bash or zsh.
+-if test -z "$BASH_VERSION$ZSH_VERSION" \
+- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+- as_echo='print -r --'
+- as_echo_n='print -rn --'
+-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+- as_echo='printf %s\n'
+- as_echo_n='printf %s'
+-else
+- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+- as_echo_n='/usr/ucb/echo -n'
+- else
+- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+- as_echo_n_body='eval
+- arg=$1;
+- case $arg in #(
+- *"$as_nl"*)
+- expr "X$arg" : "X\\(.*\\)$as_nl";
+- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+- esac;
+- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+- '
+- export as_echo_n_body
+- as_echo_n='sh -c $as_echo_n_body as_echo'
+- fi
+- export as_echo_body
+- as_echo='sh -c $as_echo_body as_echo'
+-fi
++IFS=" "" $as_nl"
++
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# Ensure predictable behavior from utilities with locale-dependent output.
++LC_ALL=C
++export LC_ALL
++LANGUAGE=C
++export LANGUAGE
++
++# We cannot yet rely on "unset" to work, but we need these variables
++# to be unset--not just set to an empty or harmless value--now, to
++# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct
++# also avoids known problems related to "unset" and subshell syntax
++# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
++for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
++do eval test \${$as_var+y} \
++ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
++done
++
++# Ensure that fds 0, 1, and 2 are open.
++if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
++if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
++if (exec 3>&2) ; then :; else exec 2>/dev/null; fi
+
+ # The user is always right.
+-if test "${PATH_SEPARATOR+set}" != set; then
++if ${PATH_SEPARATOR+false} :; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+@@ -80,13 +83,6 @@ if test "${PATH_SEPARATOR+set}" != set;
+ fi
+
+
+-# IFS
+-# We need space, tab and new line, in precisely that order. Quoting is
+-# there to prevent editors from complaining about space-tab.
+-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+-# splitting by setting IFS to empty value.)
+-IFS=" "" $as_nl"
+-
+ # Find who we are. Look in the path if we contain no directory separator.
+ as_myself=
+ case $0 in #((
+@@ -95,8 +91,12 @@ case $0 in #((
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
+- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
++ test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+ done
+ IFS=$as_save_IFS
+
+@@ -108,30 +108,10 @@ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
++ printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+ fi
+
+-# Unset variables that we do not need and which cause bugs (e.g. in
+-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+-# suppresses any "Segmentation fault" message there. '((' could
+-# trigger a bug in pdksh 5.2.14.
+-for as_var in BASH_ENV ENV MAIL MAILPATH
+-do eval test x\${$as_var+set} = xset \
+- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+-done
+-PS1='$ '
+-PS2='> '
+-PS4='+ '
+-
+-# NLS nuisances.
+-LC_ALL=C
+-export LC_ALL
+-LANGUAGE=C
+-export LANGUAGE
+-
+-# CDPATH.
+-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+ # Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+@@ -153,20 +133,22 @@ esac
+ exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+ # Admittedly, this is quite paranoid, since all the known shells bail
+ # out after a failed `exec'.
+-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+-as_fn_exit 255
++printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
++exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+ if test "x$CONFIG_SHELL" = x; then
+- as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
++ as_bourne_compatible="as_nop=:
++if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
++then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+-else
++else \$as_nop
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+@@ -186,41 +168,52 @@ as_fn_success || { exitcode=1; echo as_f
+ as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+ as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+ as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
++if ( set x; as_fn_ret_success y && test x = \"\$1\" )
++then :
+
+-else
++else \$as_nop
+ exitcode=1; echo positional parameters were not saved.
+ fi
+ test x\$exitcode = x0 || exit 1
++blah=\$(echo \$(echo blah))
++test x\"\$blah\" = xblah || exit 1
+ test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+- if (eval "$as_required") 2>/dev/null; then :
++ if (eval "$as_required") 2>/dev/null
++then :
+ as_have_required=yes
+-else
++else $as_nop
+ as_have_required=no
+ fi
+- if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
++ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
++then :
+
+-else
++else $as_nop
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ as_found=false
+ for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+- as_shell=$as_dir/$as_base
++ as_shell=$as_dir$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
++ as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
++then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+- if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
++ if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
++then :
+ break 2
+ fi
+ fi
+@@ -228,14 +221,21 @@ fi
+ esac
+ as_found=false
+ done
+-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+- CONFIG_SHELL=$SHELL as_have_required=yes
+-fi; }
+ IFS=$as_save_IFS
++if $as_found
++then :
++
++else $as_nop
++ if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
++ as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
++then :
++ CONFIG_SHELL=$SHELL as_have_required=yes
++fi
++fi
+
+
+- if test "x$CONFIG_SHELL" != x; then :
++ if test "x$CONFIG_SHELL" != x
++then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+@@ -253,18 +253,19 @@ esac
+ exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+ # Admittedly, this is quite paranoid, since all the known shells bail
+ # out after a failed `exec'.
+-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
++printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+ exit 255
+ fi
+
+- if test x$as_have_required = xno; then :
+- $as_echo "$0: This script requires a shell more modern than all"
+- $as_echo "$0: the shells that I found on your system."
+- if test x${ZSH_VERSION+set} = xset ; then
+- $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+- $as_echo "$0: be upgraded to zsh 4.3.4 or later."
++ if test x$as_have_required = xno
++then :
++ printf "%s\n" "$0: This script requires a shell more modern than all"
++ printf "%s\n" "$0: the shells that I found on your system."
++ if test ${ZSH_VERSION+y} ; then
++ printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
++ printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
+ else
+- $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
++ printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system,
+ $0: including any error possibly output before this
+ $0: message. Then install a modern shell, or manually run
+ $0: the script under such a shell if you do have one."
+@@ -291,6 +292,7 @@ as_fn_unset ()
+ }
+ as_unset=as_fn_unset
+
++
+ # as_fn_set_status STATUS
+ # -----------------------
+ # Set $? to STATUS, without forking.
+@@ -308,6 +310,14 @@ as_fn_exit ()
+ as_fn_set_status $1
+ exit $1
+ } # as_fn_exit
++# as_fn_nop
++# ---------
++# Do nothing but, unlike ":", preserve the value of $?.
++as_fn_nop ()
++{
++ return $?
++}
++as_nop=as_fn_nop
+
+ # as_fn_mkdir_p
+ # -------------
+@@ -322,7 +332,7 @@ as_fn_mkdir_p ()
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
++ *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+@@ -331,7 +341,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+-$as_echo X"$as_dir" |
++printf "%s\n" X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+@@ -370,12 +380,13 @@ as_fn_executable_p ()
+ # advantage of any shell optimizations that allow amortized linear growth over
+ # repeated appends, instead of the typical quadratic growth present in naive
+ # implementations.
+-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
++if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
++then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+-else
++else $as_nop
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+@@ -387,18 +398,27 @@ fi # as_fn_append
+ # Perform arithmetic evaluation on the ARGs, and store the result in the
+ # global $as_val. Take advantage of shells that can avoid forks. The arguments
+ # must be portable across $(()) and expr.
+-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
++if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
++then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+-else
++else $as_nop
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+ fi # as_fn_arith
+
++# as_fn_nop
++# ---------
++# Do nothing but, unlike ":", preserve the value of $?.
++as_fn_nop ()
++{
++ return $?
++}
++as_nop=as_fn_nop
+
+ # as_fn_error STATUS ERROR [LINENO LOG_FD]
+ # ----------------------------------------
+@@ -410,9 +430,9 @@ as_fn_error ()
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+- $as_echo "$as_me: error: $2" >&2
++ printf "%s\n" "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+ } # as_fn_error
+
+@@ -439,7 +459,7 @@ as_me=`$as_basename -- "$0" ||
+ $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+-$as_echo X/"$0" |
++printf "%s\n" X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+@@ -483,7 +503,7 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
++ { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+@@ -497,6 +517,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
+ exit
+ }
+
++
++# Determine whether it's possible to make 'echo' print without a newline.
++# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
++# for compatibility with existing Makefiles.
+ ECHO_C= ECHO_N= ECHO_T=
+ case `echo -n x` in #(((((
+ -n*)
+@@ -510,6 +534,13 @@ case `echo -n x` in #(((((
+ ECHO_N='-n';;
+ esac
+
++# For backward compatibility with old third-party macros, we provide
++# the shell variables $as_echo and $as_echo_n. New code should use
++# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
++as_echo='printf %s\n'
++as_echo_n='printf %s'
++
++
+ rm -f conf$$ conf$$.exe conf$$.file
+ if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+@@ -575,19 +606,19 @@ MFLAGS=
+ MAKEFLAGS=
+
+ # Identity of this package.
+-PACKAGE_NAME=
+-PACKAGE_TARNAME=
+-PACKAGE_VERSION=
+-PACKAGE_STRING=
+-PACKAGE_BUGREPORT=
+-PACKAGE_URL=
++PACKAGE_NAME=''
++PACKAGE_TARNAME=''
++PACKAGE_VERSION=''
++PACKAGE_STRING=''
++PACKAGE_BUGREPORT=''
++PACKAGE_URL=''
+
+ ac_unique_file="rlm_krb5.c"
+ ac_subst_vars='LTLIBOBJS
+ LIBOBJS
+-targetname
+ mod_cflags
+ mod_ldflags
++targetname
+ krb5_config
+ CPP
+ OBJEXT
+@@ -616,6 +647,7 @@ infodir
+ docdir
+ oldincludedir
+ includedir
++runstatedir
+ localstatedir
+ sharedstatedir
+ sysconfdir
+@@ -688,6 +720,7 @@ datadir='${datarootdir}'
+ sysconfdir='${prefix}/etc'
+ sharedstatedir='${prefix}/com'
+ localstatedir='${prefix}/var'
++runstatedir='${localstatedir}/run'
+ includedir='${prefix}/include'
+ oldincludedir='/usr/include'
+ docdir='${datarootdir}/doc/${PACKAGE}'
+@@ -717,8 +750,6 @@ do
+ *) ac_optarg=yes ;;
+ esac
+
+- # Accept the important Cygnus configure options, so we can diagnose typos.
+-
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+@@ -759,9 +790,9 @@ do
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+- as_fn_error $? "invalid feature name: $ac_useropt"
++ as_fn_error $? "invalid feature name: \`$ac_useropt'"
+ ac_useropt_orig=$ac_useropt
+- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
++ ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+ "enable_$ac_useropt"
+@@ -785,9 +816,9 @@ do
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+- as_fn_error $? "invalid feature name: $ac_useropt"
++ as_fn_error $? "invalid feature name: \`$ac_useropt'"
+ ac_useropt_orig=$ac_useropt
+- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
++ ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+ "enable_$ac_useropt"
+@@ -940,6 +971,15 @@ do
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
++ -runstatedir | --runstatedir | --runstatedi | --runstated \
++ | --runstate | --runstat | --runsta | --runst | --runs \
++ | --run | --ru | --r)
++ ac_prev=runstatedir ;;
++ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
++ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
++ | --run=* | --ru=* | --r=*)
++ runstatedir=$ac_optarg ;;
++
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+@@ -989,9 +1029,9 @@ do
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+- as_fn_error $? "invalid package name: $ac_useropt"
++ as_fn_error $? "invalid package name: \`$ac_useropt'"
+ ac_useropt_orig=$ac_useropt
+- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
++ ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+ "with_$ac_useropt"
+@@ -1005,9 +1045,9 @@ do
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+- as_fn_error $? "invalid package name: $ac_useropt"
++ as_fn_error $? "invalid package name: \`$ac_useropt'"
+ ac_useropt_orig=$ac_useropt
+- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
++ ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+ "with_$ac_useropt"
+@@ -1051,9 +1091,9 @@ Try \`$0 --help' for more information"
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+- $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
++ printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+- $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
++ printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+@@ -1069,7 +1109,7 @@ if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+- *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
++ *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+ fi
+
+@@ -1077,7 +1117,7 @@ fi
+ for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+- libdir localedir mandir
++ libdir localedir mandir runstatedir
+ do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+@@ -1133,7 +1173,7 @@ $as_expr X"$as_myself" : 'X\(.*[^/]\)//*
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+-$as_echo X"$as_myself" |
++printf "%s\n" X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+@@ -1230,6 +1270,7 @@ Fine tuning of the installation director
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
++ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+@@ -1256,8 +1297,8 @@ if test -n "$ac_init_help"; then
+ Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+- --with-rlm_krb5 build rlm_krb5. (default=yes)
+- --with-rlm-krb5-dir=DIR Directory for krb5 files
++ --without-rlm_krb5 build without Kerberos support
++ --with-rlm-krb5-dir=DIR directory where krb5 files are installed
+
+ Some influential environment variables:
+ CC C compiler command
+@@ -1288,9 +1329,9 @@ if test "$ac_init_help" = "recursive"; t
+ case "$ac_dir" in
+ .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *)
+- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
++ ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
++ ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+@@ -1318,7 +1359,8 @@ esac
+ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+- # Check for guested configure.
++ # Check for configure.gnu first; this name is used for a wrapper for
++ # Metaconfig's "Configure" on case-insensitive file systems.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+@@ -1326,7 +1368,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+- $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
++ printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+@@ -1336,9 +1378,9 @@ test -n "$ac_init_help" && exit $ac_stat
+ if $ac_init_version; then
+ cat <<\_ACEOF
+ configure
+-generated by GNU Autoconf 2.69
++generated by GNU Autoconf 2.71
+
+-Copyright (C) 2012 Free Software Foundation, Inc.
++Copyright (C) 2021 Free Software Foundation, Inc.
+ This configure script is free software; the Free Software Foundation
+ gives unlimited permission to copy, distribute and modify it.
+ _ACEOF
+@@ -1349,20 +1391,25 @@ fi
+ ## Autoconf initialization. ##
+ ## ------------------------ ##
+
++echo
++echo Running tests for rlm_krb5
++echo
++
++
+ # ac_fn_c_try_compile LINENO
+ # --------------------------
+ # Try to compile conftest.$ac_ext, and return whether this succeeded.
+ ac_fn_c_try_compile ()
+ {
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+- rm -f conftest.$ac_objext
++ rm -f conftest.$ac_objext conftest.beam
+ if { { ac_try="$ac_compile"
+ case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+@@ -1370,14 +1417,15 @@ $as_echo "$ac_try_echo"; } >&5
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+- } && test -s conftest.$ac_objext; then :
++ } && test -s conftest.$ac_objext
++then :
+ ac_retval=0
+-else
+- $as_echo "$as_me: failed program was:" >&5
++else $as_nop
++ printf "%s\n" "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+@@ -1399,7 +1447,7 @@ case "(($ac_try" in
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+@@ -1407,14 +1455,15 @@ $as_echo "$ac_try_echo"; } >&5
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+- }; then :
++ }
++then :
+ ac_retval=0
+-else
+- $as_echo "$as_me: failed program was:" >&5
++else $as_nop
++ printf "%s\n" "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+@@ -1430,14 +1479,14 @@ fi
+ ac_fn_c_try_link ()
+ {
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+- rm -f conftest.$ac_objext conftest$ac_exeext
++ rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
+ if { { ac_try="$ac_link"
+ case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+@@ -1445,17 +1494,18 @@ $as_echo "$ac_try_echo"; } >&5
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+- }; then :
++ }
++then :
+ ac_retval=0
+-else
+- $as_echo "$as_me: failed program was:" >&5
++else $as_nop
++ printf "%s\n" "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+@@ -1476,11 +1526,12 @@ fi
+ ac_fn_c_check_func ()
+ {
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+-$as_echo_n "checking for $2... " >&6; }
+-if eval \${$3+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
++printf %s "checking for $2... " >&6; }
++if eval test \${$3+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ /* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+@@ -1488,16 +1539,9 @@ else
+ #define $2 innocuous_$2
+
+ /* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char $2 (); below.
+- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+- <limits.h> exists even on freestanding compilers. */
+-
+-#ifdef __STDC__
+-# include <limits.h>
+-#else
+-# include <assert.h>
+-#endif
++ which can conflict with char $2 (); below. */
+
++#include <limits.h>
+ #undef $2
+
+ /* Override any GCC internal prototype to avoid an error.
+@@ -1515,32 +1559,33 @@ choke me
+ #endif
+
+ int
+-main ()
++main (void)
+ {
+ return $2 ();
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
++if ac_fn_c_try_link "$LINENO"
++then :
+ eval "$3=yes"
+-else
++else $as_nop
+ eval "$3=no"
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+ fi
+ eval ac_res=\$$3
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+-$as_echo "$ac_res" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
++printf "%s\n" "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+ } # ac_fn_c_check_func
+
+ # ac_fn_c_try_run LINENO
+ # ----------------------
+-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+-# that executables *can* be run.
++# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
++# executables *can* be run.
+ ac_fn_c_try_run ()
+ {
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+@@ -1550,25 +1595,26 @@ case "(($ac_try" in
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+- test $ac_status = 0; }; }; then :
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ test $ac_status = 0; }; }
++then :
+ ac_retval=0
+-else
+- $as_echo "$as_me: program exited with status $ac_status" >&5
+- $as_echo "$as_me: failed program was:" >&5
++else $as_nop
++ printf "%s\n" "$as_me: program exited with status $ac_status" >&5
++ printf "%s\n" "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+@@ -1578,14 +1624,34 @@ fi
+ as_fn_set_status $ac_retval
+
+ } # ac_fn_c_try_run
++ac_configure_args_raw=
++for ac_arg
++do
++ case $ac_arg in
++ *\'*)
++ ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
++ esac
++ as_fn_append ac_configure_args_raw " '$ac_arg'"
++done
++
++case $ac_configure_args_raw in
++ *$as_nl*)
++ ac_safe_unquote= ;;
++ *)
++ ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab.
++ ac_unsafe_a="$ac_unsafe_z#~"
++ ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
++ ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
++esac
++
+ cat >config.log <<_ACEOF
+ This file contains any messages produced by compilers while
+ running configure, to aid debugging if configure makes a mistake.
+
+ It was created by $as_me, which was
+-generated by GNU Autoconf 2.69. Invocation command line was
++generated by GNU Autoconf 2.71. Invocation command line was
+
+- $ $0 $@
++ $ $0$ac_configure_args_raw
+
+ _ACEOF
+ exec 5>>config.log
+@@ -1618,8 +1684,12 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
+- $as_echo "PATH: $as_dir"
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
++ printf "%s\n" "PATH: $as_dir"
+ done
+ IFS=$as_save_IFS
+
+@@ -1654,7 +1724,7 @@ do
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+- ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
++ ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+@@ -1689,11 +1759,13 @@ done
+ # WARNING: Use '\'' to represent an apostrophe within the trap.
+ # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+ trap 'exit_status=$?
++ # Sanitize IFS.
++ IFS=" "" $as_nl"
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+- $as_echo "## ---------------- ##
++ printf "%s\n" "## ---------------- ##
+ ## Cache variables. ##
+ ## ---------------- ##"
+ echo
+@@ -1704,8 +1776,8 @@ trap 'exit_status=$?
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
++ *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
++printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+@@ -1729,7 +1801,7 @@ $as_echo "$as_me: WARNING: cache variabl
+ )
+ echo
+
+- $as_echo "## ----------------- ##
++ printf "%s\n" "## ----------------- ##
+ ## Output variables. ##
+ ## ----------------- ##"
+ echo
+@@ -1737,14 +1809,14 @@ $as_echo "$as_me: WARNING: cache variabl
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
++ *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+- $as_echo "$ac_var='\''$ac_val'\''"
++ printf "%s\n" "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+- $as_echo "## ------------------- ##
++ printf "%s\n" "## ------------------- ##
+ ## File substitutions. ##
+ ## ------------------- ##"
+ echo
+@@ -1752,15 +1824,15 @@ $as_echo "$as_me: WARNING: cache variabl
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
++ *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+- $as_echo "$ac_var='\''$ac_val'\''"
++ printf "%s\n" "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+- $as_echo "## ----------- ##
++ printf "%s\n" "## ----------- ##
+ ## confdefs.h. ##
+ ## ----------- ##"
+ echo
+@@ -1768,8 +1840,8 @@ $as_echo "$as_me: WARNING: cache variabl
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+- $as_echo "$as_me: caught signal $ac_signal"
+- $as_echo "$as_me: exit $exit_status"
++ printf "%s\n" "$as_me: caught signal $ac_signal"
++ printf "%s\n" "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+@@ -1783,63 +1855,48 @@ ac_signal=0
+ # confdefs.h avoids OS command line length limits that DEFS can exceed.
+ rm -f -r conftest* confdefs.h
+
+-$as_echo "/* confdefs.h */" > confdefs.h
++printf "%s\n" "/* confdefs.h */" > confdefs.h
+
+ # Predefined preprocessor variables.
+
+-cat >>confdefs.h <<_ACEOF
+-#define PACKAGE_NAME "$PACKAGE_NAME"
+-_ACEOF
++printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
+
+-cat >>confdefs.h <<_ACEOF
+-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+-_ACEOF
++printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
+
+-cat >>confdefs.h <<_ACEOF
+-#define PACKAGE_VERSION "$PACKAGE_VERSION"
+-_ACEOF
++printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
+
+-cat >>confdefs.h <<_ACEOF
+-#define PACKAGE_STRING "$PACKAGE_STRING"
+-_ACEOF
++printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
+
+-cat >>confdefs.h <<_ACEOF
+-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+-_ACEOF
++printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
+
+-cat >>confdefs.h <<_ACEOF
+-#define PACKAGE_URL "$PACKAGE_URL"
+-_ACEOF
++printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
+
+
+ # Let the site file select an alternate cache file if it wants to.
+ # Prefer an explicitly selected file to automatically selected ones.
+-ac_site_file1=NONE
+-ac_site_file2=NONE
+ if test -n "$CONFIG_SITE"; then
+- # We do not want a PATH search for config.site.
+- case $CONFIG_SITE in #((
+- -*) ac_site_file1=./$CONFIG_SITE;;
+- */*) ac_site_file1=$CONFIG_SITE;;
+- *) ac_site_file1=./$CONFIG_SITE;;
+- esac
++ ac_site_files="$CONFIG_SITE"
+ elif test "x$prefix" != xNONE; then
+- ac_site_file1=$prefix/share/config.site
+- ac_site_file2=$prefix/etc/config.site
++ ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
+ else
+- ac_site_file1=$ac_default_prefix/share/config.site
+- ac_site_file2=$ac_default_prefix/etc/config.site
++ ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
++
++for ac_site_file in $ac_site_files
+ do
+- test "x$ac_site_file" = xNONE && continue
+- if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
++ case $ac_site_file in #(
++ */*) :
++ ;; #(
++ *) :
++ ac_site_file=./$ac_site_file ;;
++esac
++ if test -f "$ac_site_file" && test -r "$ac_site_file"; then
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
++printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+- || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+ as_fn_error $? "failed to load site script $ac_site_file
+ See \`config.log' for more details" "$LINENO" 5; }
+ fi
+@@ -1849,19 +1906,327 @@ if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+-$as_echo "$as_me: loading cache $cache_file" >&6;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
++printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+-$as_echo "$as_me: creating cache $cache_file" >&6;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
++printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+ fi
+
++# Test code for whether the C compiler supports C89 (global declarations)
++ac_c_conftest_c89_globals='
++/* Does the compiler advertise C89 conformance?
++ Do not test the value of __STDC__, because some compilers set it to 0
++ while being otherwise adequately conformant. */
++#if !defined __STDC__
++# error "Compiler does not advertise C89 conformance"
++#endif
++
++#include <stddef.h>
++#include <stdarg.h>
++struct stat;
++/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */
++struct buf { int x; };
++struct buf * (*rcsopen) (struct buf *, struct stat *, int);
++static char *e (p, i)
++ char **p;
++ int i;
++{
++ return p[i];
++}
++static char *f (char * (*g) (char **, int), char **p, ...)
++{
++ char *s;
++ va_list v;
++ va_start (v,p);
++ s = g (p, va_arg (v,int));
++ va_end (v);
++ return s;
++}
++
++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
++ function prototypes and stuff, but not \xHH hex character constants.
++ These do not provoke an error unfortunately, instead are silently treated
++ as an "x". The following induces an error, until -std is added to get
++ proper ANSI mode. Curiously \x00 != x always comes out true, for an
++ array size at least. It is necessary to write \x00 == 0 to get something
++ that is true only with -std. */
++int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
++
++/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
++ inside strings and character constants. */
++#define FOO(x) '\''x'\''
++int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
++
++int test (int i, double x);
++struct s1 {int (*f) (int a);};
++struct s2 {int (*f) (double a);};
++int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
++ int, int);'
++
++# Test code for whether the C compiler supports C89 (body of main).
++ac_c_conftest_c89_main='
++ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
++'
++
++# Test code for whether the C compiler supports C99 (global declarations)
++ac_c_conftest_c99_globals='
++// Does the compiler advertise C99 conformance?
++#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
++# error "Compiler does not advertise C99 conformance"
++#endif
++
++#include <stdbool.h>
++extern int puts (const char *);
++extern int printf (const char *, ...);
++extern int dprintf (int, const char *, ...);
++extern void *malloc (size_t);
++
++// Check varargs macros. These examples are taken from C99 6.10.3.5.
++// dprintf is used instead of fprintf to avoid needing to declare
++// FILE and stderr.
++#define debug(...) dprintf (2, __VA_ARGS__)
++#define showlist(...) puts (#__VA_ARGS__)
++#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
++static void
++test_varargs_macros (void)
++{
++ int x = 1234;
++ int y = 5678;
++ debug ("Flag");
++ debug ("X = %d\n", x);
++ showlist (The first, second, and third items.);
++ report (x>y, "x is %d but y is %d", x, y);
++}
++
++// Check long long types.
++#define BIG64 18446744073709551615ull
++#define BIG32 4294967295ul
++#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
++#if !BIG_OK
++ #error "your preprocessor is broken"
++#endif
++#if BIG_OK
++#else
++ #error "your preprocessor is broken"
++#endif
++static long long int bignum = -9223372036854775807LL;
++static unsigned long long int ubignum = BIG64;
++
++struct incomplete_array
++{
++ int datasize;
++ double data[];
++};
++
++struct named_init {
++ int number;
++ const wchar_t *name;
++ double average;
++};
++
++typedef const char *ccp;
++
++static inline int
++test_restrict (ccp restrict text)
++{
++ // See if C++-style comments work.
++ // Iterate through items via the restricted pointer.
++ // Also check for declarations in for loops.
++ for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
++ continue;
++ return 0;
++}
++
++// Check varargs and va_copy.
++static bool
++test_varargs (const char *format, ...)
++{
++ va_list args;
++ va_start (args, format);
++ va_list args_copy;
++ va_copy (args_copy, args);
++
++ const char *str = "";
++ int number = 0;
++ float fnumber = 0;
++
++ while (*format)
++ {
++ switch (*format++)
++ {
++ case '\''s'\'': // string
++ str = va_arg (args_copy, const char *);
++ break;
++ case '\''d'\'': // int
++ number = va_arg (args_copy, int);
++ break;
++ case '\''f'\'': // float
++ fnumber = va_arg (args_copy, double);
++ break;
++ default:
++ break;
++ }
++ }
++ va_end (args_copy);
++ va_end (args);
++
++ return *str && number && fnumber;
++}
++'
++
++# Test code for whether the C compiler supports C99 (body of main).
++ac_c_conftest_c99_main='
++ // Check bool.
++ _Bool success = false;
++ success |= (argc != 0);
++
++ // Check restrict.
++ if (test_restrict ("String literal") == 0)
++ success = true;
++ char *restrict newvar = "Another string";
++
++ // Check varargs.
++ success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
++ test_varargs_macros ();
++
++ // Check flexible array members.
++ struct incomplete_array *ia =
++ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
++ ia->datasize = 10;
++ for (int i = 0; i < ia->datasize; ++i)
++ ia->data[i] = i * 1.234;
++
++ // Check named initializers.
++ struct named_init ni = {
++ .number = 34,
++ .name = L"Test wide string",
++ .average = 543.34343,
++ };
++
++ ni.number = 58;
++
++ int dynamic_array[ni.number];
++ dynamic_array[0] = argv[0][0];
++ dynamic_array[ni.number - 1] = 543;
++
++ // work around unused variable warnings
++ ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
++ || dynamic_array[ni.number - 1] != 543);
++'
++
++# Test code for whether the C compiler supports C11 (global declarations)
++ac_c_conftest_c11_globals='
++// Does the compiler advertise C11 conformance?
++#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
++# error "Compiler does not advertise C11 conformance"
++#endif
++
++// Check _Alignas.
++char _Alignas (double) aligned_as_double;
++char _Alignas (0) no_special_alignment;
++extern char aligned_as_int;
++char _Alignas (0) _Alignas (int) aligned_as_int;
++
++// Check _Alignof.
++enum
++{
++ int_alignment = _Alignof (int),
++ int_array_alignment = _Alignof (int[100]),
++ char_alignment = _Alignof (char)
++};
++_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
++
++// Check _Noreturn.
++int _Noreturn does_not_return (void) { for (;;) continue; }
++
++// Check _Static_assert.
++struct test_static_assert
++{
++ int x;
++ _Static_assert (sizeof (int) <= sizeof (long int),
++ "_Static_assert does not work in struct");
++ long int y;
++};
++
++// Check UTF-8 literals.
++#define u8 syntax error!
++char const utf8_literal[] = u8"happens to be ASCII" "another string";
++
++// Check duplicate typedefs.
++typedef long *long_ptr;
++typedef long int *long_ptr;
++typedef long_ptr long_ptr;
++
++// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
++struct anonymous
++{
++ union {
++ struct { int i; int j; };
++ struct { int k; long int l; } w;
++ };
++ int m;
++} v1;
++'
++
++# Test code for whether the C compiler supports C11 (body of main).
++ac_c_conftest_c11_main='
++ _Static_assert ((offsetof (struct anonymous, i)
++ == offsetof (struct anonymous, w.k)),
++ "Anonymous union alignment botch");
++ v1.i = 2;
++ v1.w.k = 5;
++ ok |= v1.i != 5;
++'
++
++# Test code for whether the C compiler supports C11 (complete).
++ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
++${ac_c_conftest_c99_globals}
++${ac_c_conftest_c11_globals}
++
++int
++main (int argc, char **argv)
++{
++ int ok = 0;
++ ${ac_c_conftest_c89_main}
++ ${ac_c_conftest_c99_main}
++ ${ac_c_conftest_c11_main}
++ return ok;
++}
++"
++
++# Test code for whether the C compiler supports C99 (complete).
++ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
++${ac_c_conftest_c99_globals}
++
++int
++main (int argc, char **argv)
++{
++ int ok = 0;
++ ${ac_c_conftest_c89_main}
++ ${ac_c_conftest_c99_main}
++ return ok;
++}
++"
++
++# Test code for whether the C compiler supports C89 (complete).
++ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
++
++int
++main (int argc, char **argv)
++{
++ int ok = 0;
++ ${ac_c_conftest_c89_main}
++ return ok;
++}
++"
++
+ # Check that the precious variables saved in the cache have kept the same
+ # value.
+ ac_cache_corrupted=false
+@@ -1872,12 +2237,12 @@ for ac_var in $ac_precious_vars; do
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
++printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
++printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+@@ -1886,24 +2251,24 @@ $as_echo "$as_me: error: \`$ac_var' was
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
++printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
++printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+- { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+-$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+- { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+-$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
++printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
++printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+- *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
++ *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+@@ -1913,11 +2278,12 @@ $as_echo "$as_me: current value: \`$ac
+ fi
+ done
+ if $ac_cache_corrupted; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+- { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+- as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
++printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
++ as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
++ and start over" "$LINENO" 5
+ fi
+ ## -------------------- ##
+ ## Main body of script. ##
+@@ -1934,15 +2300,39 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
++
++
++
+ # Check whether --with-rlm_krb5 was given.
+-if test "${with_rlm_krb5+set}" = set; then :
++if test ${with_rlm_krb5+y}
++then :
+ withval=$with_rlm_krb5;
+ fi
+
+
+-if test x$with_rlm_krb5 != xno; then
+
+- ac_ext=c
++
++fail=
++fr_status=
++fr_features=
++: > "config.report"
++: > "config.report.tmp"
++
++
++
++if test x"$with_rlm_krb5" != xno; then
++
++
++
++
++
++
++
++
++
++
++
++ac_ext=c
+ ac_cpp='$CPP $CPPFLAGS'
+ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+@@ -1950,11 +2340,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+ set dummy ${ac_tool_prefix}gcc; ac_word=$2
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+-$as_echo_n "checking for $ac_word... " >&6; }
+-if ${ac_cv_prog_CC+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++printf %s "checking for $ac_word... " >&6; }
++if test ${ac_cv_prog_CC+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+ else
+@@ -1962,11 +2353,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+ done
+@@ -1977,11 +2372,11 @@ fi
+ fi
+ CC=$ac_cv_prog_CC
+ if test -n "$CC"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+-$as_echo "$CC" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++printf "%s\n" "$CC" >&6; }
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+
+
+@@ -1990,11 +2385,12 @@ if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+ set dummy gcc; ac_word=$2
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+-$as_echo_n "checking for $ac_word... " >&6; }
+-if ${ac_cv_prog_ac_ct_CC+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++printf %s "checking for $ac_word... " >&6; }
++if test ${ac_cv_prog_ac_ct_CC+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+ else
+@@ -2002,11 +2398,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+ done
+@@ -2017,11 +2417,11 @@ fi
+ fi
+ ac_ct_CC=$ac_cv_prog_ac_ct_CC
+ if test -n "$ac_ct_CC"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+-$as_echo "$ac_ct_CC" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
++printf "%s\n" "$ac_ct_CC" >&6; }
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+
+ if test "x$ac_ct_CC" = x; then
+@@ -2029,8 +2429,8 @@ fi
+ else
+ case $cross_compiling:$ac_tool_warned in
+ yes:)
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ ac_tool_warned=yes ;;
+ esac
+ CC=$ac_ct_CC
+@@ -2043,11 +2443,12 @@ if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+ set dummy ${ac_tool_prefix}cc; ac_word=$2
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+-$as_echo_n "checking for $ac_word... " >&6; }
+-if ${ac_cv_prog_CC+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++printf %s "checking for $ac_word... " >&6; }
++if test ${ac_cv_prog_CC+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+ else
+@@ -2055,11 +2456,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+ done
+@@ -2070,11 +2475,11 @@ fi
+ fi
+ CC=$ac_cv_prog_CC
+ if test -n "$CC"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+-$as_echo "$CC" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++printf "%s\n" "$CC" >&6; }
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+
+
+@@ -2083,11 +2488,12 @@ fi
+ if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+ set dummy cc; ac_word=$2
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+-$as_echo_n "checking for $ac_word... " >&6; }
+-if ${ac_cv_prog_CC+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++printf %s "checking for $ac_word... " >&6; }
++if test ${ac_cv_prog_CC+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+ else
+@@ -2096,15 +2502,19 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
++ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
++ if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+ done
+@@ -2120,18 +2530,18 @@ if test $ac_prog_rejected = yes; then
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
++ ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
+ fi
+ fi
+ fi
+ fi
+ CC=$ac_cv_prog_CC
+ if test -n "$CC"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+-$as_echo "$CC" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++printf "%s\n" "$CC" >&6; }
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+
+
+@@ -2142,11 +2552,12 @@ if test -z "$CC"; then
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+ set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+-$as_echo_n "checking for $ac_word... " >&6; }
+-if ${ac_cv_prog_CC+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++printf %s "checking for $ac_word... " >&6; }
++if test ${ac_cv_prog_CC+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+ else
+@@ -2154,11 +2565,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+ done
+@@ -2169,11 +2584,11 @@ fi
+ fi
+ CC=$ac_cv_prog_CC
+ if test -n "$CC"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+-$as_echo "$CC" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++printf "%s\n" "$CC" >&6; }
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+
+
+@@ -2186,11 +2601,12 @@ if test -z "$CC"; then
+ do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+ set dummy $ac_prog; ac_word=$2
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+-$as_echo_n "checking for $ac_word... " >&6; }
+-if ${ac_cv_prog_ac_ct_CC+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++printf %s "checking for $ac_word... " >&6; }
++if test ${ac_cv_prog_ac_ct_CC+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+ else
+@@ -2198,11 +2614,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+ done
+@@ -2213,11 +2633,11 @@ fi
+ fi
+ ac_ct_CC=$ac_cv_prog_ac_ct_CC
+ if test -n "$ac_ct_CC"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+-$as_echo "$ac_ct_CC" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
++printf "%s\n" "$ac_ct_CC" >&6; }
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+
+
+@@ -2229,34 +2649,138 @@ done
+ else
+ case $cross_compiling:$ac_tool_warned in
+ yes:)
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++ CC=$ac_ct_CC
++ fi
++fi
++
++fi
++if test -z "$CC"; then
++ if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
++set dummy ${ac_tool_prefix}clang; ac_word=$2
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++printf %s "checking for $ac_word... " >&6; }
++if test ${ac_cv_prog_CC+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
++ ac_cv_prog_CC="${ac_tool_prefix}clang"
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++ done
++IFS=$as_save_IFS
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++printf "%s\n" "$CC" >&6; }
++else
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_CC"; then
++ ac_ct_CC=$CC
++ # Extract the first word of "clang", so it can be a program name with args.
++set dummy clang; ac_word=$2
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++printf %s "checking for $ac_word... " >&6; }
++if test ${ac_cv_prog_ac_ct_CC+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
++ if test -n "$ac_ct_CC"; then
++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_CC="clang"
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++ done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_CC=$ac_cv_prog_ac_ct_CC
++if test -n "$ac_ct_CC"; then
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
++printf "%s\n" "$ac_ct_CC" >&6; }
++else
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
++fi
++
++ if test "x$ac_ct_CC" = x; then
++ CC=""
++ else
++ case $cross_compiling:$ac_tool_warned in
++yes:)
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ ac_tool_warned=yes ;;
+ esac
+ CC=$ac_ct_CC
+ fi
++else
++ CC="$ac_cv_prog_CC"
+ fi
+
+ fi
+
+
+-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+ as_fn_error $? "no acceptable C compiler found in \$PATH
+ See \`config.log' for more details" "$LINENO" 5; }
+
+ # Provide some information about the compiler.
+-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
++printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+ set X $ac_compile
+ ac_compiler=$2
+-for ac_option in --version -v -V -qversion; do
++for ac_option in --version -v -V -qversion -version; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+ case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+@@ -2266,7 +2790,7 @@ $as_echo "$ac_try_echo"; } >&5
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ done
+
+@@ -2274,7 +2798,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_
+ /* end confdefs.h. */
+
+ int
+-main ()
++main (void)
+ {
+
+ ;
+@@ -2286,9 +2810,9 @@ ac_clean_files="$ac_clean_files a.out a.
+ # Try to create an executable without -o first, disregard a.out.
+ # It will help us diagnose broken compilers, and finding out an intuition
+ # of exeext.
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+-$as_echo_n "checking whether the C compiler works... " >&6; }
+-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
++printf %s "checking whether the C compiler works... " >&6; }
++ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+ # The possible output files:
+ ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+@@ -2309,11 +2833,12 @@ case "(($ac_try" in
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+- test $ac_status = 0; }; then :
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ test $ac_status = 0; }
++then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+ # So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+ # in a Makefile. We should not override ac_cv_exeext if it was cached,
+@@ -2330,7 +2855,7 @@ do
+ # certainly right.
+ break;;
+ *.* )
+- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
++ if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+@@ -2346,44 +2871,46 @@ do
+ done
+ test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+-else
++else $as_nop
+ ac_file=''
+ fi
+-if test -z "$ac_file"; then :
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
+-$as_echo "$as_me: failed program was:" >&5
++if test -z "$ac_file"
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
++printf "%s\n" "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+
+-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+ as_fn_error 77 "C compiler cannot create executables
+ See \`config.log' for more details" "$LINENO" 5; }
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+-fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+-$as_echo_n "checking for C compiler default output file name... " >&6; }
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+-$as_echo "$ac_file" >&6; }
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++fi
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
++printf %s "checking for C compiler default output file name... " >&6; }
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
++printf "%s\n" "$ac_file" >&6; }
+ ac_exeext=$ac_cv_exeext
+
+ rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ ac_clean_files=$ac_clean_files_save
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+-$as_echo_n "checking for suffix of executables... " >&6; }
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
++printf %s "checking for suffix of executables... " >&6; }
+ if { { ac_try="$ac_link"
+ case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+- test $ac_status = 0; }; then :
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ test $ac_status = 0; }
++then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+ # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+ # work properly (i.e., refer to `conftest.exe'), while it won't with
+@@ -2397,15 +2924,15 @@ for ac_file in conftest.exe conftest con
+ * ) break;;
+ esac
+ done
+-else
+- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++else $as_nop
++ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+ as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+ See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ rm -f conftest conftest$ac_cv_exeext
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+-$as_echo "$ac_cv_exeext" >&6; }
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
++printf "%s\n" "$ac_cv_exeext" >&6; }
+
+ rm -f conftest.$ac_ext
+ EXEEXT=$ac_cv_exeext
+@@ -2414,7 +2941,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_
+ /* end confdefs.h. */
+ #include <stdio.h>
+ int
+-main ()
++main (void)
+ {
+ FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+@@ -2426,8 +2953,8 @@ _ACEOF
+ ac_clean_files="$ac_clean_files conftest.out"
+ # Check that the compiler produces executables we can run. If not, either
+ # the compiler is broken, or we cross compile.
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+-$as_echo_n "checking whether we are cross compiling... " >&6; }
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
++printf %s "checking whether we are cross compiling... " >&6; }
+ if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+ case "(($ac_try" in
+@@ -2435,10 +2962,10 @@ case "(($ac_try" in
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+@@ -2446,39 +2973,40 @@ $as_echo "$ac_try_echo"; } >&5
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "cannot run C compiled programs.
++ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error 77 "cannot run C compiled programs.
+ If you meant to cross compile, use \`--host'.
+ See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+ fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+-$as_echo "$cross_compiling" >&6; }
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
++printf "%s\n" "$cross_compiling" >&6; }
+
+ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ ac_clean_files=$ac_clean_files_save
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+-$as_echo_n "checking for suffix of object files... " >&6; }
+-if ${ac_cv_objext+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
++printf %s "checking for suffix of object files... " >&6; }
++if test ${ac_cv_objext+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+ int
+-main ()
++main (void)
+ {
+
+ ;
+@@ -2492,11 +3020,12 @@ case "(($ac_try" in
+ *) ac_try_echo=$ac_try;;
+ esac
+ eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+-$as_echo "$ac_try_echo"; } >&5
++printf "%s\n" "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+- test $ac_status = 0; }; then :
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ test $ac_status = 0; }
++then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+@@ -2505,31 +3034,32 @@ $as_echo "$ac_try_echo"; } >&5
+ break;;
+ esac
+ done
+-else
+- $as_echo "$as_me: failed program was:" >&5
++else $as_nop
++ printf "%s\n" "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+
+-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+ as_fn_error $? "cannot compute suffix of object files: cannot compile
+ See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ rm -f conftest.$ac_cv_objext conftest.$ac_ext
+ fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+-$as_echo "$ac_cv_objext" >&6; }
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
++printf "%s\n" "$ac_cv_objext" >&6; }
+ OBJEXT=$ac_cv_objext
+ ac_objext=$OBJEXT
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+-if ${ac_cv_c_compiler_gnu+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
++printf %s "checking whether the compiler supports GNU C... " >&6; }
++if test ${ac_cv_c_compiler_gnu+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+ int
+-main ()
++main (void)
+ {
+ #ifndef __GNUC__
+ choke me
+@@ -2539,29 +3069,33 @@ main ()
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+ ac_compiler_gnu=yes
+-else
++else $as_nop
+ ac_compiler_gnu=no
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+ fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
++printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
+ if test $ac_compiler_gnu = yes; then
+ GCC=yes
+ else
+ GCC=
+ fi
+-ac_test_CFLAGS=${CFLAGS+set}
++ac_test_CFLAGS=${CFLAGS+y}
+ ac_save_CFLAGS=$CFLAGS
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+-$as_echo_n "checking whether $CC accepts -g... " >&6; }
+-if ${ac_cv_prog_cc_g+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
++printf %s "checking whether $CC accepts -g... " >&6; }
++if test ${ac_cv_prog_cc_g+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+@@ -2570,57 +3104,60 @@ else
+ /* end confdefs.h. */
+
+ int
+-main ()
++main (void)
+ {
+
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+ ac_cv_prog_cc_g=yes
+-else
++else $as_nop
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+ int
+-main ()
++main (void)
+ {
+
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+-else
++else $as_nop
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+ int
+-main ()
++main (void)
+ {
+
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+ ac_cv_prog_cc_g=yes
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+-$as_echo "$ac_cv_prog_cc_g" >&6; }
+-if test "$ac_test_CFLAGS" = set; then
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
++printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
++if test $ac_test_CFLAGS; then
+ CFLAGS=$ac_save_CFLAGS
+ elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+@@ -2635,94 +3172,144 @@ else
+ CFLAGS=
+ fi
+ fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+-if ${ac_cv_prog_cc_c89+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
+- ac_cv_prog_cc_c89=no
++ac_prog_cc_stdc=no
++if test x$ac_prog_cc_stdc = xno
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
++printf %s "checking for $CC option to enable C11 features... " >&6; }
++if test ${ac_cv_prog_cc_c11+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
++ ac_cv_prog_cc_c11=no
+ ac_save_CC=$CC
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-#include <stdarg.h>
+-#include <stdio.h>
+-struct stat;
+-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+-struct buf { int x; };
+-FILE * (*rcsopen) (struct buf *, struct stat *, int);
+-static char *e (p, i)
+- char **p;
+- int i;
+-{
+- return p[i];
+-}
+-static char *f (char * (*g) (char **, int), char **p, ...)
+-{
+- char *s;
+- va_list v;
+- va_start (v,p);
+- s = g (p, va_arg (v,int));
+- va_end (v);
+- return s;
+-}
+-
+-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+- function prototypes and stuff, but not '\xHH' hex character constants.
+- These don't provoke an error unfortunately, instead are silently treated
+- as 'x'. The following induces an error, until -std is added to get
+- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+- array size at least. It's necessary to write '\x00'==0 to get something
+- that's true only with -std. */
+-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
++$ac_c_conftest_c11_program
++_ACEOF
++for ac_arg in '' -std=gnu11
++do
++ CC="$ac_save_CC $ac_arg"
++ if ac_fn_c_try_compile "$LINENO"
++then :
++ ac_cv_prog_cc_c11=$ac_arg
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.beam
++ test "x$ac_cv_prog_cc_c11" != "xno" && break
++done
++rm -f conftest.$ac_ext
++CC=$ac_save_CC
++fi
+
+-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+- inside strings and character constants. */
+-#define FOO(x) 'x'
+-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
++if test "x$ac_cv_prog_cc_c11" = xno
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
++printf "%s\n" "unsupported" >&6; }
++else $as_nop
++ if test "x$ac_cv_prog_cc_c11" = x
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
++printf "%s\n" "none needed" >&6; }
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
++printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
++ CC="$CC $ac_cv_prog_cc_c11"
++fi
++ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
++ ac_prog_cc_stdc=c11
++fi
++fi
++if test x$ac_prog_cc_stdc = xno
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
++printf %s "checking for $CC option to enable C99 features... " >&6; }
++if test ${ac_cv_prog_cc_c99+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
++ ac_cv_prog_cc_c99=no
++ac_save_CC=$CC
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++$ac_c_conftest_c99_program
++_ACEOF
++for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
++do
++ CC="$ac_save_CC $ac_arg"
++ if ac_fn_c_try_compile "$LINENO"
++then :
++ ac_cv_prog_cc_c99=$ac_arg
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.beam
++ test "x$ac_cv_prog_cc_c99" != "xno" && break
++done
++rm -f conftest.$ac_ext
++CC=$ac_save_CC
++fi
+
+-int test (int i, double x);
+-struct s1 {int (*f) (int a);};
+-struct s2 {int (*f) (double a);};
+-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+-int argc;
+-char **argv;
+-int
+-main ()
+-{
+-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+- ;
+- return 0;
+-}
++if test "x$ac_cv_prog_cc_c99" = xno
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
++printf "%s\n" "unsupported" >&6; }
++else $as_nop
++ if test "x$ac_cv_prog_cc_c99" = x
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
++printf "%s\n" "none needed" >&6; }
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
++printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
++ CC="$CC $ac_cv_prog_cc_c99"
++fi
++ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
++ ac_prog_cc_stdc=c99
++fi
++fi
++if test x$ac_prog_cc_stdc = xno
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
++printf %s "checking for $CC option to enable C89 features... " >&6; }
++if test ${ac_cv_prog_cc_c89+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
++ ac_cv_prog_cc_c89=no
++ac_save_CC=$CC
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++$ac_c_conftest_c89_program
+ _ACEOF
+-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
++for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+ do
+ CC="$ac_save_CC $ac_arg"
+- if ac_fn_c_try_compile "$LINENO"; then :
++ if ac_fn_c_try_compile "$LINENO"
++then :
+ ac_cv_prog_cc_c89=$ac_arg
+ fi
+-rm -f core conftest.err conftest.$ac_objext
++rm -f core conftest.err conftest.$ac_objext conftest.beam
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+ done
+ rm -f conftest.$ac_ext
+ CC=$ac_save_CC
+-
+ fi
+-# AC_CACHE_VAL
+-case "x$ac_cv_prog_cc_c89" in
+- x)
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+-$as_echo "none needed" >&6; } ;;
+- xno)
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+-$as_echo "unsupported" >&6; } ;;
+- *)
+- CC="$CC $ac_cv_prog_cc_c89"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+-esac
+-if test "x$ac_cv_prog_cc_c89" != xno; then :
+
++if test "x$ac_cv_prog_cc_c89" = xno
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
++printf "%s\n" "unsupported" >&6; }
++else $as_nop
++ if test "x$ac_cv_prog_cc_c89" = x
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
++printf "%s\n" "none needed" >&6; }
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
++printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
++ CC="$CC $ac_cv_prog_cc_c89"
++fi
++ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
++ ac_prog_cc_stdc=c89
++fi
+ fi
+
+ ac_ext=c
+@@ -2731,45 +3318,41 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS con
+ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+- ac_ext=c
++ac_ext=c
+ ac_cpp='$CPP $CPPFLAGS'
+ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+-$as_echo_n "checking how to run the C preprocessor... " >&6; }
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
++printf %s "checking how to run the C preprocessor... " >&6; }
+ # On Suns, sometimes $CPP names a directory.
+ if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+ fi
+ if test -z "$CPP"; then
+- if ${ac_cv_prog_CPP+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
+- # Double quotes because CPP needs to be expanded
+- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
++ if test ${ac_cv_prog_CPP+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
++ # Double quotes because $CC needs to be expanded
++ for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp
+ do
+ ac_preproc_ok=false
+ for ac_c_preproc_warn_flag in '' yes
+ do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+- # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-#ifdef __STDC__
+-# include <limits.h>
+-#else
+-# include <assert.h>
+-#endif
++#include <limits.h>
+ Syntax error
+ _ACEOF
+-if ac_fn_c_try_cpp "$LINENO"; then :
++if ac_fn_c_try_cpp "$LINENO"
++then :
+
+-else
++else $as_nop
+ # Broken: fails on valid input.
+ continue
+ fi
+@@ -2781,10 +3364,11 @@ rm -f conftest.err conftest.i conftest.$
+ /* end confdefs.h. */
+ #include <ac_nonexistent.h>
+ _ACEOF
+-if ac_fn_c_try_cpp "$LINENO"; then :
++if ac_fn_c_try_cpp "$LINENO"
++then :
+ # Broken: success on invalid input.
+ continue
+-else
++else $as_nop
+ # Passes both tests.
+ ac_preproc_ok=:
+ break
+@@ -2794,7 +3378,8 @@ rm -f conftest.err conftest.i conftest.$
+ done
+ # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+ rm -f conftest.i conftest.err conftest.$ac_ext
+-if $ac_preproc_ok; then :
++if $ac_preproc_ok
++then :
+ break
+ fi
+
+@@ -2806,29 +3391,24 @@ fi
+ else
+ ac_cv_prog_CPP=$CPP
+ fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+-$as_echo "$CPP" >&6; }
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
++printf "%s\n" "$CPP" >&6; }
+ ac_preproc_ok=false
+ for ac_c_preproc_warn_flag in '' yes
+ do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+- # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-#ifdef __STDC__
+-# include <limits.h>
+-#else
+-# include <assert.h>
+-#endif
++#include <limits.h>
+ Syntax error
+ _ACEOF
+-if ac_fn_c_try_cpp "$LINENO"; then :
++if ac_fn_c_try_cpp "$LINENO"
++then :
+
+-else
++else $as_nop
+ # Broken: fails on valid input.
+ continue
+ fi
+@@ -2840,10 +3420,11 @@ rm -f conftest.err conftest.i conftest.$
+ /* end confdefs.h. */
+ #include <ac_nonexistent.h>
+ _ACEOF
+-if ac_fn_c_try_cpp "$LINENO"; then :
++if ac_fn_c_try_cpp "$LINENO"
++then :
+ # Broken: success on invalid input.
+ continue
+-else
++else $as_nop
+ # Passes both tests.
+ ac_preproc_ok=:
+ break
+@@ -2853,11 +3434,12 @@ rm -f conftest.err conftest.i conftest.$
+ done
+ # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+ rm -f conftest.i conftest.err conftest.$ac_ext
+-if $ac_preproc_ok; then :
++if $ac_preproc_ok
++then :
+
+-else
+- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++else $as_nop
++ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+ as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+ See \`config.log' for more details" "$LINENO" 5; }
+ fi
+@@ -2869,31 +3451,32 @@ ac_link='$CC -o conftest$ac_exeext $CFLA
+ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+- rlm_krb5_dir=
++rlm_krb5_dir=
+
+ # Check whether --with-rlm-krb5-dir was given.
+-if test "${with_rlm_krb5_dir+set}" = set; then :
+- withval=$with_rlm_krb5_dir; case "$withval" in
+- no)
++if test ${with_rlm_krb5_dir+y}
++then :
++ withval=$with_rlm_krb5_dir; case "$withval" in
++ no)
+ as_fn_error $? "Need rlm-krb5-dir" "$LINENO" 5
+ ;;
+- yes)
++ yes)
+ ;;
+- *)
++ *)
+ rlm_krb5_dir="$withval"
+ ;;
+- esac
+-
++ esac
+ fi
+
+
+- # Extract the first word of "krb5-config", so it can be a program name with args.
++# Extract the first word of "krb5-config", so it can be a program name with args.
+ set dummy krb5-config; ac_word=$2
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+-$as_echo_n "checking for $ac_word... " >&6; }
+-if ${ac_cv_path_krb5_config+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++printf %s "checking for $ac_word... " >&6; }
++if test ${ac_cv_path_krb5_config+y}
++then :
++ printf %s "(cached) " >&6
++else $as_nop
+ case $krb5_config in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_krb5_config="$krb5_config" # Let the user override the test with a path.
+@@ -2904,11 +3487,15 @@ as_dummy="${rlm_krb5_dir}/bin:${PATH}:/u
+ for as_dir in $as_dummy
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
+ for ac_exec_ext in '' $ac_executable_extensions; do
+- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+- ac_cv_path_krb5_config="$as_dir/$ac_word$ac_exec_ext"
+- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
++ ac_cv_path_krb5_config="$as_dir$ac_word$ac_exec_ext"
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+ done
+@@ -2921,1920 +3508,1639 @@ esac
+ fi
+ krb5_config=$ac_cv_path_krb5_config
+ if test -n "$krb5_config"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $krb5_config" >&5
+-$as_echo "$krb5_config" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $krb5_config" >&5
++printf "%s\n" "$krb5_config" >&6; }
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+
+
+- if test "$krb5_config" != 'not-found'; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking krb5-config CFLAGS" >&5
+-$as_echo_n "checking krb5-config CFLAGS... " >&6; }
+- SMART_CPPFLAGS=$($krb5_config --cflags)
+- SMART_CPPFLAGS=$(echo "$SMART_CPPFLAGS" | sed 's/-I[ ]*/-isystem /g')
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$SMART_CPPFLAGS\"" >&5
+-$as_echo "\"$SMART_CPPFLAGS\"" >&6; }
+-
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking krb5-config LDFLAGS" >&5
+-$as_echo_n "checking krb5-config LDFLAGS... " >&6; }
+- SMART_LIBS=$($krb5_config --libs)
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${SMART_LIBS}" >&5
+-$as_echo "${SMART_LIBS}" >&6; }
+-
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking krb5-config reported version" >&5
+-$as_echo_n "checking krb5-config reported version... " >&6; }
+- krb5_version_raw=$($krb5_config --version)
+-
+- krb5_version=$(echo "$krb5_version_raw" | head -n 1 | \
+- awk '{split($(4),v,"."); if (v["3"] = "") v["3"] = "0"; print v["1"]v["2"]v["3"] }')
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${krb5_version_raw} ($krb5_version)" >&5
+-$as_echo "${krb5_version_raw} ($krb5_version)" >&6; }
+-
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking krb5-config reported vendor" >&5
+-$as_echo_n "checking krb5-config reported vendor... " >&6; }
+- krb5_vendor=$($krb5_config --vendor)
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${krb5_vendor}" >&5
+-$as_echo "${krb5_vendor}" >&6; }
+-
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking canonical API type" >&5
+-$as_echo_n "checking canonical API type... " >&6; }
+- if test "$krb5_vendor" = "Massachusetts Institute of Technology" || \
+- echo "$krb5_vendor" | grep -i 'MIT' > /dev/null 2>&1 || \
+- echo "$krb5_version_raw" | grep -i 'MIT' > /dev/null 2>&1 ; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: MIT" >&5
+-$as_echo "MIT" >&6; }
+- krb5_api_type='mit'
+- else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: HEIMDAL" >&5
+-$as_echo "HEIMDAL" >&6; }
+- krb5_api_type='heimdal'
+- fi
++if test "$krb5_config" != 'not-found'; then
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking krb5-config CFLAGS" >&5
++printf %s "checking krb5-config CFLAGS... " >&6; }
++ SMART_CPPFLAGS=$($krb5_config --cflags)
++ SMART_CPPFLAGS=$(echo "$SMART_CPPFLAGS" | sed 's/-I[ ]*/-isystem /g')
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$SMART_CPPFLAGS\"" >&5
++printf "%s\n" "\"$SMART_CPPFLAGS\"" >&6; }
++
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking krb5-config LDFLAGS" >&5
++printf %s "checking krb5-config LDFLAGS... " >&6; }
++ SMART_LIBS=$($krb5_config --libs)
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${SMART_LIBS}" >&5
++printf "%s\n" "${SMART_LIBS}" >&6; }
++
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking krb5-config reported version" >&5
++printf %s "checking krb5-config reported version... " >&6; }
++ krb5_version_raw=$($krb5_config --version)
++
++ krb5_version=$(echo "$krb5_version_raw" | head -n 1 | \
++ awk '{split($(4),v,"."); if (v["3"] == "") v["3"] = "0"; print v["1"]v["2"]v["3"] }')
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${krb5_version_raw} ($krb5_version)" >&5
++printf "%s\n" "${krb5_version_raw} ($krb5_version)" >&6; }
++
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking krb5-config reported vendor" >&5
++printf %s "checking krb5-config reported vendor... " >&6; }
++ krb5_vendor=$($krb5_config --vendor)
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${krb5_vendor}" >&5
++printf "%s\n" "${krb5_vendor}" >&6; }
++
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking canonical API type" >&5
++printf %s "checking canonical API type... " >&6; }
++ if test "$krb5_vendor" = "Massachusetts Institute of Technology" || \
++ echo "$krb5_vendor" | grep -i 'MIT' > /dev/null 2>&1 || \
++ echo "$krb5_version_raw" | grep -i 'MIT' > /dev/null 2>&1 ; then
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: MIT" >&5
++printf "%s\n" "MIT" >&6; }
++ krb5_api_type='mit'
+ else
+- smart_try_dir="$rlm_krb5_dir/include"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: HEIMDAL" >&5
++printf "%s\n" "HEIMDAL" >&6; }
++ krb5_api_type='heimdal'
++ fi
++else
++ smart_try_dir="$rlm_krb5_dir/include"
+
+
+
+ ac_safe=`echo "krb5.h" | sed 'y%./+-%__pm%'`
++
++if test "x" = "x"; then
++ sm_pkg=`echo "${ac_safe}" | sed 's/.h//;s/^lib//'`
++else
++ sm_pkg=""
++fi
++
+ old_CPPFLAGS="$CPPFLAGS"
+-smart_include=
+-smart_include_dir="/usr/local/include /opt/include"
++smart_include_dir="/usr/local/include /opt/include /usr/local/${sm_pkg}/include /opt/homebrew/include /opt/homebrew/opt/${sm_pkg}/include"
+
+ _smart_try_dir=
+ _smart_include_dir=
+
+ for _prefix in $smart_prefix ""; do
+- for _dir in $smart_try_dir; do
+- _smart_try_dir="${_smart_try_dir} ${_dir}/${_prefix}"
+- done
++for _dir in $smart_try_dir; do
++ _smart_try_dir="${_smart_try_dir} ${_dir}/${_prefix}"
++done
+
+- for _dir in $smart_include_dir; do
+- _smart_include_dir="${_smart_include_dir} ${_dir}/${_prefix}"
+- done
++for _dir in $smart_include_dir; do
++ _smart_include_dir="${_smart_include_dir} ${_dir}/${_prefix}"
++done
+ done
+
+ if test "x$_smart_try_dir" != "x"; then
+- for try in $_smart_try_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5.h in $try" >&5
+-$as_echo_n "checking for krb5.h in $try... " >&6; }
+- CPPFLAGS="-isystem $try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $_smart_try_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5.h in $try" >&5
++printf %s "checking for krb5.h in $try... " >&6; }
++ CPPFLAGS="-isystem $try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+- #include <krb5.h>
++
++ #include <krb5.h>
++
+ int
+-main ()
++main (void)
+ {
+-int a = 1;
++
++ int a = 1;
++
++
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include="-isystem $try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include="-isystem $try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+- done
+- CPPFLAGS="$old_CPPFLAGS"
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
++done
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_include" = "x"; then
+- for _prefix in $smart_prefix; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${_prefix}/krb5.h" >&5
+-$as_echo_n "checking for ${_prefix}/krb5.h... " >&6; }
++for _prefix in $smart_prefix; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${_prefix}/krb5.h" >&5
++printf %s "checking for ${_prefix}/krb5.h... " >&6; }
+
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+- #include <krb5.h>
++
++ #include <krb5.h>
++
+ int
+-main ()
++main (void)
+ {
+-int a = 1;
++
++ int a = 1;
++
++
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include="-isystem ${_prefix}/"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include="-isystem ${_prefix}/"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+- done
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
++done
+ fi
+
+ if test "x$smart_include" = "x"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5.h" >&5
+-$as_echo_n "checking for krb5.h... " >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5.h" >&5
++printf %s "checking for krb5.h... " >&6; }
+
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+- #include <krb5.h>
++
++ #include <krb5.h>
++
+ int
+-main ()
++main (void)
+ {
+-int a = 1;
++
++ int a = 1;
++
++
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include=" "
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include=" "
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ fi
+
+ if test "x$smart_include" = "x"; then
+-
+- for prefix in $smart_prefix; do
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file="${_prefix}/${1}"
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
+-
+- done
++for try in $_smart_include_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5.h in $try" >&5
++printf %s "checking for krb5.h in $try... " >&6; }
++ CPPFLAGS="-isystem $try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
+
+
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=krb5.h
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
++ #include <krb5.h>
+
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
++int
++main (void)
++{
+
++ int a = 1;
+
+- for try in $_smart_include_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5.h in $try" >&5
+-$as_echo_n "checking for krb5.h in $try... " >&6; }
+- CPPFLAGS="-isystem $try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+
+- #include <krb5.h>
+-int
+-main ()
+-{
+-int a = 1;
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include="-isystem $try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include="-isystem $try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+- done
+- CPPFLAGS="$old_CPPFLAGS"
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
++done
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_include" != "x"; then
+- eval "ac_cv_header_$ac_safe=yes"
+- CPPFLAGS="$smart_include $old_CPPFLAGS"
+- SMART_CPPFLAGS="$smart_include $SMART_CPPFLAGS"
++eval "ac_cv_header_$ac_safe=yes"
++CPPFLAGS="$smart_include $old_CPPFLAGS"
++SMART_CPPFLAGS="$smart_include $SMART_CPPFLAGS"
+ fi
+
+ smart_prefix=
+
+- if test "$ac_cv_header_krb5_h" != "yes"; then
+- fail="$fail krb5.h"
+- fi
++ if test "$ac_cv_header_krb5_h" != "yes"; then
++
++fail="$fail krb5.h"
+
+- krb5libcrypto=
+- smart_try_dir="$rlm_krb5_dir/lib"
++ fi
++
++ krb5libcrypto=
++ smart_try_dir="$rlm_krb5_dir/lib"
+
+
+ sm_lib_safe=`echo "k5crypto" | sed 'y%./+-%__p_%'`
+ sm_func_safe=`echo "krb5_encrypt_data" | sed 'y%./+-%__p_%'`
+
++if test "x" = "x"; then
++ sm_pkg="${sm_lib_safe}"
++else
++ sm_pkg=""
++fi
++
+ old_LIBS="$LIBS"
+ old_CPPFLAGS="$CPPFLAGS"
+ smart_lib=
+ smart_ldflags=
+-smart_lib_dir=
++smart_lib_dir="/usr/local/lib /opt/lib /usr/local/${sm_pkg}/lib /opt/homebrew/lib /opt/homebrew/opt/${sm_pkg}/lib"
+
+ if test "x$smart_try_dir" != "x"; then
+- for try in $smart_try_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_encrypt_data in -lk5crypto in $try" >&5
+-$as_echo_n "checking for krb5_encrypt_data in -lk5crypto in $try... " >&6; }
+- LIBS="-lk5crypto $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_try_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_encrypt_data in -lk5crypto in $try" >&5
++printf %s "checking for krb5_encrypt_data in -lk5crypto in $try... " >&6; }
++ LIBS="-lk5crypto $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_encrypt_data();
+ int
+-main ()
++main (void)
+ {
+ krb5_encrypt_data()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lk5crypto"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lk5crypto"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_encrypt_data in -lk5crypto" >&5
+-$as_echo_n "checking for krb5_encrypt_data in -lk5crypto... " >&6; }
+- LIBS="-lk5crypto $old_LIBS"
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_encrypt_data in -lk5crypto" >&5
++printf %s "checking for krb5_encrypt_data in -lk5crypto... " >&6; }
++LIBS="-lk5crypto $old_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_encrypt_data();
+ int
+-main ()
++main (void)
+ {
+ krb5_encrypt_data()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
++if ac_fn_c_try_link "$LINENO"
++then :
+
+- smart_lib="-lk5crypto"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+-
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lk5crypto"
++ smart_ld_found=""
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- LIBS="$old_LIBS"
++LIBS="$old_LIBS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libk5crypto${libltdl_cv_shlibext}
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libk5crypto.a
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+- for try in $smart_lib_dir /usr/local/lib /opt/lib; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_encrypt_data in -lk5crypto in $try" >&5
+-$as_echo_n "checking for krb5_encrypt_data in -lk5crypto in $try... " >&6; }
+- LIBS="-lk5crypto $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_lib_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_encrypt_data in -lk5crypto in $try" >&5
++printf %s "checking for krb5_encrypt_data in -lk5crypto in $try... " >&6; }
++ LIBS="-lk5crypto $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_encrypt_data();
+ int
+-main ()
++main (void)
+ {
+ krb5_encrypt_data()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lk5crypto"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lk5crypto"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" != "x"; then
+- eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
+- LIBS="$smart_ldflags $smart_lib $old_LIBS"
+- SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
++LIBS="$smart_ldflags $smart_lib $old_LIBS"
++SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++SMART_LD_FOUND="$smart_ld_found"
+ fi
+
+- if test "x$ac_cv_lib_k5crypto_krb5_encrypt_data" = xyes; then
+- krb5libcrypto="-lk5crypto"
+- fi
++ if test "x$ac_cv_lib_k5crypto_krb5_encrypt_data" = xyes; then
++ krb5libcrypto="-lk5crypto"
++ fi
+
+- if test "x$krb5libcrypto" = x; then
++ if test "x$krb5libcrypto" = x; then
+
+
+ sm_lib_safe=`echo "crypto" | sed 'y%./+-%__p_%'`
+ sm_func_safe=`echo "DH_new" | sed 'y%./+-%__p_%'`
+
++if test "x" = "x"; then
++ sm_pkg="${sm_lib_safe}"
++else
++ sm_pkg=""
++fi
++
+ old_LIBS="$LIBS"
+ old_CPPFLAGS="$CPPFLAGS"
+ smart_lib=
+ smart_ldflags=
+-smart_lib_dir=
++smart_lib_dir="/usr/local/lib /opt/lib /usr/local/${sm_pkg}/lib /opt/homebrew/lib /opt/homebrew/opt/${sm_pkg}/lib"
+
+ if test "x$smart_try_dir" != "x"; then
+- for try in $smart_try_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DH_new in -lcrypto in $try" >&5
+-$as_echo_n "checking for DH_new in -lcrypto in $try... " >&6; }
+- LIBS="-lcrypto $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_try_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for DH_new in -lcrypto in $try" >&5
++printf %s "checking for DH_new in -lcrypto in $try... " >&6; }
++ LIBS="-lcrypto $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char DH_new();
+ int
+-main ()
++main (void)
+ {
+ DH_new()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lcrypto"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lcrypto"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DH_new in -lcrypto" >&5
+-$as_echo_n "checking for DH_new in -lcrypto... " >&6; }
+- LIBS="-lcrypto $old_LIBS"
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for DH_new in -lcrypto" >&5
++printf %s "checking for DH_new in -lcrypto... " >&6; }
++LIBS="-lcrypto $old_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char DH_new();
+ int
+-main ()
++main (void)
+ {
+ DH_new()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lcrypto"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lcrypto"
++ smart_ld_found=""
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- LIBS="$old_LIBS"
++LIBS="$old_LIBS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libcrypto${libltdl_cv_shlibext}
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libcrypto.a
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+- for try in $smart_lib_dir /usr/local/lib /opt/lib; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DH_new in -lcrypto in $try" >&5
+-$as_echo_n "checking for DH_new in -lcrypto in $try... " >&6; }
+- LIBS="-lcrypto $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_lib_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for DH_new in -lcrypto in $try" >&5
++printf %s "checking for DH_new in -lcrypto in $try... " >&6; }
++ LIBS="-lcrypto $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char DH_new();
+ int
+-main ()
++main (void)
+ {
+ DH_new()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lcrypto"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lcrypto"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" != "x"; then
+- eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
+- LIBS="$smart_ldflags $smart_lib $old_LIBS"
+- SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
++LIBS="$smart_ldflags $smart_lib $old_LIBS"
++SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++SMART_LD_FOUND="$smart_ld_found"
+ fi
+
+- if test "x$ac_cv_lib_crypto_DH_new" = xyes; then
+- krb5libcrypto="-lcrypto"
+- fi
++ if test "x$ac_cv_lib_crypto_DH_new" = xyes; then
++ krb5libcrypto="-lcrypto"
+ fi
++ fi
+
+- if test "x$krb5libcrypto" = x; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: neither krb5 'k5crypto' nor 'crypto' libraries are found!" >&5
+-$as_echo "$as_me: WARNING: neither krb5 'k5crypto' nor 'crypto' libraries are found!" >&2;}
+- fi
++ if test "x$krb5libcrypto" = x; then
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: neither krb5 'k5crypto' nor 'crypto' libraries are found!" >&5
++printf "%s\n" "$as_me: WARNING: neither krb5 'k5crypto' nor 'crypto' libraries are found!" >&2;}
++ fi
+
+
+
+ sm_lib_safe=`echo "com_err" | sed 'y%./+-%__p_%'`
+ sm_func_safe=`echo "set_com_err_hook" | sed 'y%./+-%__p_%'`
+
++if test "x" = "x"; then
++ sm_pkg="${sm_lib_safe}"
++else
++ sm_pkg=""
++fi
++
+ old_LIBS="$LIBS"
+ old_CPPFLAGS="$CPPFLAGS"
+ smart_lib=
+ smart_ldflags=
+-smart_lib_dir=
++smart_lib_dir="/usr/local/lib /opt/lib /usr/local/${sm_pkg}/lib /opt/homebrew/lib /opt/homebrew/opt/${sm_pkg}/lib"
+
+ if test "x$smart_try_dir" != "x"; then
+- for try in $smart_try_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for set_com_err_hook in -lcom_err in $try" >&5
+-$as_echo_n "checking for set_com_err_hook in -lcom_err in $try... " >&6; }
+- LIBS="-lcom_err $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_try_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for set_com_err_hook in -lcom_err in $try" >&5
++printf %s "checking for set_com_err_hook in -lcom_err in $try... " >&6; }
++ LIBS="-lcom_err $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char set_com_err_hook();
+ int
+-main ()
++main (void)
+ {
+ set_com_err_hook()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
++if ac_fn_c_try_link "$LINENO"
++then :
+
+- smart_lib="-lcom_err"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
+-
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lcom_err"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for set_com_err_hook in -lcom_err" >&5
+-$as_echo_n "checking for set_com_err_hook in -lcom_err... " >&6; }
+- LIBS="-lcom_err $old_LIBS"
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for set_com_err_hook in -lcom_err" >&5
++printf %s "checking for set_com_err_hook in -lcom_err... " >&6; }
++LIBS="-lcom_err $old_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char set_com_err_hook();
+ int
+-main ()
++main (void)
+ {
+ set_com_err_hook()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
++if ac_fn_c_try_link "$LINENO"
++then :
+
+- smart_lib="-lcom_err"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+-
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lcom_err"
++ smart_ld_found=""
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- LIBS="$old_LIBS"
++LIBS="$old_LIBS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libcom_err${libltdl_cv_shlibext}
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libcom_err.a
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+- for try in $smart_lib_dir /usr/local/lib /opt/lib; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for set_com_err_hook in -lcom_err in $try" >&5
+-$as_echo_n "checking for set_com_err_hook in -lcom_err in $try... " >&6; }
+- LIBS="-lcom_err $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_lib_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for set_com_err_hook in -lcom_err in $try" >&5
++printf %s "checking for set_com_err_hook in -lcom_err in $try... " >&6; }
++ LIBS="-lcom_err $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char set_com_err_hook();
+ int
+-main ()
++main (void)
+ {
+ set_com_err_hook()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lcom_err"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lcom_err"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" != "x"; then
+- eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
+- LIBS="$smart_ldflags $smart_lib $old_LIBS"
+- SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
++LIBS="$smart_ldflags $smart_lib $old_LIBS"
++SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++SMART_LD_FOUND="$smart_ld_found"
+ fi
+
+- if test "x$ac_cv_lib_com_err_set_com_err_hook" != xyes; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: the comm_err library isn't found!" >&5
+-$as_echo "$as_me: WARNING: the comm_err library isn't found!" >&2;}
+- fi
++ if test "x$ac_cv_lib_com_err_set_com_err_hook" != xyes; then
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: the comm_err library isn't found!" >&5
++printf "%s\n" "$as_me: WARNING: the comm_err library isn't found!" >&2;}
++ fi
+
+
+
+ sm_lib_safe=`echo "krb5" | sed 'y%./+-%__p_%'`
+ sm_func_safe=`echo "krb5_verify_user_opt" | sed 'y%./+-%__p_%'`
+
++if test "x" = "x"; then
++ sm_pkg="${sm_lib_safe}"
++else
++ sm_pkg=""
++fi
++
+ old_LIBS="$LIBS"
+ old_CPPFLAGS="$CPPFLAGS"
+ smart_lib=
+ smart_ldflags=
+-smart_lib_dir=
++smart_lib_dir="/usr/local/lib /opt/lib /usr/local/${sm_pkg}/lib /opt/homebrew/lib /opt/homebrew/opt/${sm_pkg}/lib"
+
+ if test "x$smart_try_dir" != "x"; then
+- for try in $smart_try_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_verify_user_opt in -lkrb5 in $try" >&5
+-$as_echo_n "checking for krb5_verify_user_opt in -lkrb5 in $try... " >&6; }
+- LIBS="-lkrb5 $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_try_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_verify_user_opt in -lkrb5 in $try" >&5
++printf %s "checking for krb5_verify_user_opt in -lkrb5 in $try... " >&6; }
++ LIBS="-lkrb5 $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_verify_user_opt();
+ int
+-main ()
++main (void)
+ {
+ krb5_verify_user_opt()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lkrb5"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lkrb5"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_verify_user_opt in -lkrb5" >&5
+-$as_echo_n "checking for krb5_verify_user_opt in -lkrb5... " >&6; }
+- LIBS="-lkrb5 $old_LIBS"
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_verify_user_opt in -lkrb5" >&5
++printf %s "checking for krb5_verify_user_opt in -lkrb5... " >&6; }
++LIBS="-lkrb5 $old_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_verify_user_opt();
+ int
+-main ()
++main (void)
+ {
+ krb5_verify_user_opt()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
++if ac_fn_c_try_link "$LINENO"
++then :
+
+- smart_lib="-lkrb5"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+-
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lkrb5"
++ smart_ld_found=""
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- LIBS="$old_LIBS"
++LIBS="$old_LIBS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libkrb5${libltdl_cv_shlibext}
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libkrb5.a
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+- for try in $smart_lib_dir /usr/local/lib /opt/lib; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_verify_user_opt in -lkrb5 in $try" >&5
+-$as_echo_n "checking for krb5_verify_user_opt in -lkrb5 in $try... " >&6; }
+- LIBS="-lkrb5 $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_lib_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_verify_user_opt in -lkrb5 in $try" >&5
++printf %s "checking for krb5_verify_user_opt in -lkrb5 in $try... " >&6; }
++ LIBS="-lkrb5 $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_verify_user_opt();
+ int
+-main ()
++main (void)
+ {
+ krb5_verify_user_opt()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lkrb5"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lkrb5"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" != "x"; then
+- eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
+- LIBS="$smart_ldflags $smart_lib $old_LIBS"
+- SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
++LIBS="$smart_ldflags $smart_lib $old_LIBS"
++SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++SMART_LD_FOUND="$smart_ld_found"
+ fi
+
+- if test "x$ac_cv_lib_krb5_krb5_verify_user_opt" = xyes; then
+- krb5_api_type='heimdal'
+- else
+- krb5_api_type='mit'
++ if test "x$ac_cv_lib_krb5_krb5_verify_user_opt" = xyes; then
++ krb5_api_type='heimdal'
++ else
++ krb5_api_type='mit'
+
+
+
+ sm_lib_safe=`echo "krb5" | sed 'y%./+-%__p_%'`
+ sm_func_safe=`echo "krb5_get_init_creds_password" | sed 'y%./+-%__p_%'`
+
++if test "x" = "x"; then
++ sm_pkg="${sm_lib_safe}"
++else
++ sm_pkg=""
++fi
++
+ old_LIBS="$LIBS"
+ old_CPPFLAGS="$CPPFLAGS"
+ smart_lib=
+ smart_ldflags=
+-smart_lib_dir=
++smart_lib_dir="/usr/local/lib /opt/lib /usr/local/${sm_pkg}/lib /opt/homebrew/lib /opt/homebrew/opt/${sm_pkg}/lib"
+
+ if test "x$smart_try_dir" != "x"; then
+- for try in $smart_try_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_get_init_creds_password in -lkrb5 in $try" >&5
+-$as_echo_n "checking for krb5_get_init_creds_password in -lkrb5 in $try... " >&6; }
+- LIBS="-lkrb5 $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_try_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_get_init_creds_password in -lkrb5 in $try" >&5
++printf %s "checking for krb5_get_init_creds_password in -lkrb5 in $try... " >&6; }
++ LIBS="-lkrb5 $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_get_init_creds_password();
+ int
+-main ()
++main (void)
+ {
+ krb5_get_init_creds_password()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lkrb5"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lkrb5"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_get_init_creds_password in -lkrb5" >&5
+-$as_echo_n "checking for krb5_get_init_creds_password in -lkrb5... " >&6; }
+- LIBS="-lkrb5 $old_LIBS"
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_get_init_creds_password in -lkrb5" >&5
++printf %s "checking for krb5_get_init_creds_password in -lkrb5... " >&6; }
++LIBS="-lkrb5 $old_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_get_init_creds_password();
+ int
+-main ()
++main (void)
+ {
+ krb5_get_init_creds_password()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
++if ac_fn_c_try_link "$LINENO"
++then :
+
+- smart_lib="-lkrb5"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+-
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lkrb5"
++ smart_ld_found=""
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- LIBS="$old_LIBS"
++LIBS="$old_LIBS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libkrb5${libltdl_cv_shlibext}
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libkrb5.a
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+- for try in $smart_lib_dir /usr/local/lib /opt/lib; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_get_init_creds_password in -lkrb5 in $try" >&5
+-$as_echo_n "checking for krb5_get_init_creds_password in -lkrb5 in $try... " >&6; }
+- LIBS="-lkrb5 $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_lib_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_get_init_creds_password in -lkrb5 in $try" >&5
++printf %s "checking for krb5_get_init_creds_password in -lkrb5 in $try... " >&6; }
++ LIBS="-lkrb5 $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_get_init_creds_password();
+ int
+-main ()
++main (void)
+ {
+ krb5_get_init_creds_password()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lkrb5"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lkrb5"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" != "x"; then
+- eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
+- LIBS="$smart_ldflags $smart_lib $old_LIBS"
+- SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
++LIBS="$smart_ldflags $smart_lib $old_LIBS"
++SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++SMART_LD_FOUND="$smart_ld_found"
+ fi
+
+- if test "x$ac_cv_lib_krb5_krb5_get_init_creds_password" != xyes; then
+- fail="$fail krb5"
+- fi
+- fi
++ if test "x$ac_cv_lib_krb5_krb5_get_init_creds_password" != xyes; then
+
++fail="$fail krb5"
++
++ fi
+ fi
+
+- LDFLAGS="${LDFLAGS} ${SMART_LIBS}"
+- CFLAGS="${CFLAGS} ${SMART_CPPFLAGS}"
++fi
+
+- for ac_func in krb5_get_error_message krb5_free_error_string krb5_free_error_message
+-do :
+- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+- cat >>confdefs.h <<_ACEOF
+-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+-_ACEOF
++LDFLAGS="${LDFLAGS} ${SMART_LIBS}"
++CFLAGS="${CFLAGS} ${SMART_CPPFLAGS}"
++
++ac_fn_c_check_func "$LINENO" "krb5_get_error_message" "ac_cv_func_krb5_get_error_message"
++if test "x$ac_cv_func_krb5_get_error_message" = xyes
++then :
++ printf "%s\n" "#define HAVE_KRB5_GET_ERROR_MESSAGE 1" >>confdefs.h
+
+ fi
+-done
++ac_fn_c_check_func "$LINENO" "krb5_free_error_string" "ac_cv_func_krb5_free_error_string"
++if test "x$ac_cv_func_krb5_free_error_string" = xyes
++then :
++ printf "%s\n" "#define HAVE_KRB5_FREE_ERROR_STRING 1" >>confdefs.h
+
+- if test "x$ac_cv_func_krb5_get_error_message" = xyes; then
+- krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_GET_ERROR_MESSAGE"
+- fi
+- if test "x$ac_cv_func_krb5_free_error_message" = xyes; then
+- krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_FREE_ERROR_MESSAGE"
+- fi
+- if test "x$ac_cv_func_krb5_free_error_string" = xyes; then
+- krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_FREE_ERROR_STRING"
+- fi
++fi
++ac_fn_c_check_func "$LINENO" "krb5_free_error_message" "ac_cv_func_krb5_free_error_message"
++if test "x$ac_cv_func_krb5_free_error_message" = xyes
++then :
++ printf "%s\n" "#define HAVE_KRB5_FREE_ERROR_MESSAGE 1" >>confdefs.h
+
+- if test "$krb5threadsafe" != "no"; then
+- krb5threadsafe=
++fi
++
++if test "x$ac_cv_func_krb5_get_error_message" = xyes; then
++ krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_GET_ERROR_MESSAGE"
++fi
++if test "x$ac_cv_func_krb5_free_error_message" = xyes; then
++ krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_FREE_ERROR_MESSAGE"
++fi
++if test "x$ac_cv_func_krb5_free_error_string" = xyes; then
++ krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_FREE_ERROR_STRING"
++fi
++
++if test "$krb5threadsafe" != "no"; then
++ krb5threadsafe=
+
+
+
+ sm_lib_safe=`echo "krb5" | sed 'y%./+-%__p_%'`
+ sm_func_safe=`echo "krb5_is_thread_safe" | sed 'y%./+-%__p_%'`
+
++if test "x" = "x"; then
++ sm_pkg="${sm_lib_safe}"
++else
++ sm_pkg=""
++fi
++
+ old_LIBS="$LIBS"
+ old_CPPFLAGS="$CPPFLAGS"
+ smart_lib=
+ smart_ldflags=
+-smart_lib_dir=
++smart_lib_dir="/usr/local/lib /opt/lib /usr/local/${sm_pkg}/lib /opt/homebrew/lib /opt/homebrew/opt/${sm_pkg}/lib"
+
+ if test "x$smart_try_dir" != "x"; then
+- for try in $smart_try_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_is_thread_safe in -lkrb5 in $try" >&5
+-$as_echo_n "checking for krb5_is_thread_safe in -lkrb5 in $try... " >&6; }
+- LIBS="-lkrb5 $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_try_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_is_thread_safe in -lkrb5 in $try" >&5
++printf %s "checking for krb5_is_thread_safe in -lkrb5 in $try... " >&6; }
++ LIBS="-lkrb5 $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_is_thread_safe();
+ int
+-main ()
++main (void)
+ {
+ krb5_is_thread_safe()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
++if ac_fn_c_try_link "$LINENO"
++then :
+
+- smart_lib="-lkrb5"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
+-
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lkrb5"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_is_thread_safe in -lkrb5" >&5
+-$as_echo_n "checking for krb5_is_thread_safe in -lkrb5... " >&6; }
+- LIBS="-lkrb5 $old_LIBS"
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_is_thread_safe in -lkrb5" >&5
++printf %s "checking for krb5_is_thread_safe in -lkrb5... " >&6; }
++LIBS="-lkrb5 $old_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_is_thread_safe();
+ int
+-main ()
++main (void)
+ {
+ krb5_is_thread_safe()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+-
+- smart_lib="-lkrb5"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
++if ac_fn_c_try_link "$LINENO"
++then :
+
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lkrb5"
++ smart_ld_found=""
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- LIBS="$old_LIBS"
++LIBS="$old_LIBS"
+ fi
+
+ if test "x$smart_lib" = "x"; then
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libkrb5${libltdl_cv_shlibext}
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=libkrb5.a
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$smart_lib_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\""
+-
+-
+- for try in $smart_lib_dir /usr/local/lib /opt/lib; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_is_thread_safe in -lkrb5 in $try" >&5
+-$as_echo_n "checking for krb5_is_thread_safe in -lkrb5 in $try... " >&6; }
+- LIBS="-lkrb5 $old_LIBS"
+- CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $smart_lib_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for krb5_is_thread_safe in -lkrb5 in $try" >&5
++printf %s "checking for krb5_is_thread_safe in -lkrb5 in $try... " >&6; }
++ LIBS="-lkrb5 $old_LIBS"
++ CPPFLAGS="-L$try -Wl,-rpath,$try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ extern char krb5_is_thread_safe();
+ int
+-main ()
++main (void)
+ {
+ krb5_is_thread_safe()
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
++if ac_fn_c_try_link "$LINENO"
++then :
+
+- smart_lib="-lkrb5"
+- smart_ldflags="-L$try -Wl,-rpath,$try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
+-
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_lib="-lkrb5"
++ smart_ldflags="-L$try -Wl,-rpath,$try"
++ smart_ld_found="$try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
++
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+ fi
+-rm -f core conftest.err conftest.$ac_objext \
++rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+- done
+- LIBS="$old_LIBS"
+- CPPFLAGS="$old_CPPFLAGS"
++done
++LIBS="$old_LIBS"
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_lib" != "x"; then
+- eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
+- LIBS="$smart_ldflags $smart_lib $old_LIBS"
+- SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++eval "ac_cv_lib_${sm_lib_safe}_${sm_func_safe}=yes"
++LIBS="$smart_ldflags $smart_lib $old_LIBS"
++SMART_LIBS="$smart_ldflags $smart_lib $SMART_LIBS"
++SMART_LD_FOUND="$smart_ld_found"
+ fi
+
+- if test "x$ac_cv_lib_krb5_krb5_is_thread_safe" = xyes; then
+- if test "$cross_compiling" = yes; then :
+- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "cannot run test program while cross compiling
+-See \`config.log' for more details" "$LINENO" 5; }
+-else
++ if test "x$ac_cv_lib_krb5_krb5_is_thread_safe" = xyes; then
++ if test "$cross_compiling" = yes
++then :
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5
++printf "%s\n" "$as_me: WARNING: cross compiling: not checking" >&2;}
++else $as_nop
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+ #include <krb5.h>
+ int
+-main ()
++main (void)
+ {
+ return krb5_is_thread_safe() ? 0 : 1
+ ;
+ return 0;
+ }
+ _ACEOF
+-if ac_fn_c_try_run "$LINENO"; then :
++if ac_fn_c_try_run "$LINENO"
++then :
+ krb5threadsafe="-DKRB5_IS_THREAD_SAFE"
+-else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libkrb5 is not threadsafe" >&5
+-$as_echo "$as_me: WARNING: libkrb5 is not threadsafe" >&2;}
++else $as_nop
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libkrb5 is not threadsafe" >&5
++printf "%s\n" "$as_me: WARNING: libkrb5 is not threadsafe" >&2;}
+ fi
+ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+ fi
+
+- fi
+- else
+- krb5threadsafe=""
+ fi
++else
++ krb5threadsafe=""
++fi
+
+- if test "$krb5_api_type" = "mit"; then
++if test "$krb5_api_type" = "mit"; then
+
+
+ ac_safe=`echo "com_err.h" | sed 'y%./+-%__pm%'`
++
++if test "x" = "x"; then
++ sm_pkg=`echo "${ac_safe}" | sed 's/.h//;s/^lib//'`
++else
++ sm_pkg=""
++fi
++
+ old_CPPFLAGS="$CPPFLAGS"
+-smart_include=
+-smart_include_dir="/usr/local/include /opt/include"
++smart_include_dir="/usr/local/include /opt/include /usr/local/${sm_pkg}/include /opt/homebrew/include /opt/homebrew/opt/${sm_pkg}/include"
+
+ _smart_try_dir=
+ _smart_include_dir=
+
+ for _prefix in $smart_prefix ""; do
+- for _dir in $smart_try_dir; do
+- _smart_try_dir="${_smart_try_dir} ${_dir}/${_prefix}"
+- done
++for _dir in $smart_try_dir; do
++ _smart_try_dir="${_smart_try_dir} ${_dir}/${_prefix}"
++done
+
+- for _dir in $smart_include_dir; do
+- _smart_include_dir="${_smart_include_dir} ${_dir}/${_prefix}"
+- done
++for _dir in $smart_include_dir; do
++ _smart_include_dir="${_smart_include_dir} ${_dir}/${_prefix}"
++done
+ done
+
+ if test "x$_smart_try_dir" != "x"; then
+- for try in $_smart_try_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for com_err.h in $try" >&5
+-$as_echo_n "checking for com_err.h in $try... " >&6; }
+- CPPFLAGS="-isystem $try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $_smart_try_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for com_err.h in $try" >&5
++printf %s "checking for com_err.h in $try... " >&6; }
++ CPPFLAGS="-isystem $try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+- #include <com_err.h>
++
++ #include <com_err.h>
++
+ int
+-main ()
++main (void)
+ {
+-int a = 1;
++
++ int a = 1;
++
++
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include="-isystem $try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include="-isystem $try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+- done
+- CPPFLAGS="$old_CPPFLAGS"
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
++done
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_include" = "x"; then
+- for _prefix in $smart_prefix; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${_prefix}/com_err.h" >&5
+-$as_echo_n "checking for ${_prefix}/com_err.h... " >&6; }
++for _prefix in $smart_prefix; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${_prefix}/com_err.h" >&5
++printf %s "checking for ${_prefix}/com_err.h... " >&6; }
+
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+- #include <com_err.h>
++
++ #include <com_err.h>
++
+ int
+-main ()
++main (void)
+ {
+-int a = 1;
++
++ int a = 1;
++
++
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include="-isystem ${_prefix}/"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include="-isystem ${_prefix}/"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+- done
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
++done
+ fi
+
+ if test "x$smart_include" = "x"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for com_err.h" >&5
+-$as_echo_n "checking for com_err.h... " >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for com_err.h" >&5
++printf %s "checking for com_err.h... " >&6; }
+
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+- #include <com_err.h>
++
++ #include <com_err.h>
++
+ int
+-main ()
++main (void)
+ {
+-int a = 1;
++
++ int a = 1;
++
++
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include=" "
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include=" "
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ fi
+
+ if test "x$smart_include" = "x"; then
++for try in $_smart_include_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for com_err.h in $try" >&5
++printf %s "checking for com_err.h in $try... " >&6; }
++ CPPFLAGS="-isystem $try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
+
+- for prefix in $smart_prefix; do
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file="${_prefix}/${1}"
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
+-
+- done
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=com_err.h
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+
+- already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
++ #include <com_err.h>
+
+-eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
++int
++main (void)
++{
+
++ int a = 1;
+
+- for try in $_smart_include_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for com_err.h in $try" >&5
+-$as_echo_n "checking for com_err.h in $try... " >&6; }
+- CPPFLAGS="-isystem $try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+
+- #include <com_err.h>
+-int
+-main ()
+-{
+-int a = 1;
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include="-isystem $try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include="-isystem $try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+- done
+- CPPFLAGS="$old_CPPFLAGS"
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
++done
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_include" != "x"; then
+- eval "ac_cv_header_$ac_safe=yes"
+- CPPFLAGS="$smart_include $old_CPPFLAGS"
+- SMART_CPPFLAGS="$smart_include $SMART_CPPFLAGS"
++eval "ac_cv_header_$ac_safe=yes"
++CPPFLAGS="$smart_include $old_CPPFLAGS"
++SMART_CPPFLAGS="$smart_include $SMART_CPPFLAGS"
+ fi
+
+ smart_prefix=
+
+- if test "$ac_cv_header_com_err_h" != "yes"; then
++ if test "$ac_cv_header_com_err_h" != "yes"; then
+
+
+ ac_safe=`echo "et/com_err.h" | sed 'y%./+-%__pm%'`
++
++if test "x" = "x"; then
++ sm_pkg=`echo "${ac_safe}" | sed 's/.h//;s/^lib//'`
++else
++ sm_pkg=""
++fi
++
+ old_CPPFLAGS="$CPPFLAGS"
+-smart_include=
+-smart_include_dir="/usr/local/include /opt/include"
++smart_include_dir="/usr/local/include /opt/include /usr/local/${sm_pkg}/include /opt/homebrew/include /opt/homebrew/opt/${sm_pkg}/include"
+
+ _smart_try_dir=
+ _smart_include_dir=
+
+ for _prefix in $smart_prefix ""; do
+- for _dir in $smart_try_dir; do
+- _smart_try_dir="${_smart_try_dir} ${_dir}/${_prefix}"
+- done
++for _dir in $smart_try_dir; do
++ _smart_try_dir="${_smart_try_dir} ${_dir}/${_prefix}"
++done
+
+- for _dir in $smart_include_dir; do
+- _smart_include_dir="${_smart_include_dir} ${_dir}/${_prefix}"
+- done
++for _dir in $smart_include_dir; do
++ _smart_include_dir="${_smart_include_dir} ${_dir}/${_prefix}"
++done
+ done
+
+ if test "x$_smart_try_dir" != "x"; then
+- for try in $_smart_try_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for et/com_err.h in $try" >&5
+-$as_echo_n "checking for et/com_err.h in $try... " >&6; }
+- CPPFLAGS="-isystem $try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++for try in $_smart_try_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for et/com_err.h in $try" >&5
++printf %s "checking for et/com_err.h in $try... " >&6; }
++ CPPFLAGS="-isystem $try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+- #include <et/com_err.h>
++
++ #include <et/com_err.h>
++
+ int
+-main ()
++main (void)
+ {
+-int a = 1;
++
++ int a = 1;
++
++
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include="-isystem $try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include="-isystem $try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+- done
+- CPPFLAGS="$old_CPPFLAGS"
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
++done
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_include" = "x"; then
+- for _prefix in $smart_prefix; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${_prefix}/et/com_err.h" >&5
+-$as_echo_n "checking for ${_prefix}/et/com_err.h... " >&6; }
++for _prefix in $smart_prefix; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${_prefix}/et/com_err.h" >&5
++printf %s "checking for ${_prefix}/et/com_err.h... " >&6; }
+
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+- #include <et/com_err.h>
++
++ #include <et/com_err.h>
++
+ int
+-main ()
++main (void)
+ {
+-int a = 1;
++
++ int a = 1;
++
++
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include="-isystem ${_prefix}/"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include="-isystem ${_prefix}/"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+- done
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
++done
+ fi
+
+ if test "x$smart_include" = "x"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for et/com_err.h" >&5
+-$as_echo_n "checking for et/com_err.h... " >&6; }
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for et/com_err.h" >&5
++printf %s "checking for et/com_err.h... " >&6; }
+
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+
+- #include <et/com_err.h>
++
++ #include <et/com_err.h>
++
+ int
+-main ()
++main (void)
+ {
+-int a = 1;
++
++ int a = 1;
++
++
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include=" "
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include=" "
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+ fi
+
+ if test "x$smart_include" = "x"; then
++for try in $_smart_include_dir; do
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for et/com_err.h in $try" >&5
++printf %s "checking for et/com_err.h in $try... " >&6; }
++ CPPFLAGS="-isystem $try $old_CPPFLAGS"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
+
+- for prefix in $smart_prefix; do
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file="${_prefix}/${1}"
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+-
+- already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
+-
+-eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
+-
+- done
+-
+-
+-if test "x$LOCATE" != "x"; then
+- DIRS=
+- file=et/com_err.h
+-
+- for x in `${LOCATE} $file 2>/dev/null`; do
+- base=`echo $x | sed "s%/${file}%%"`
+- if test "x$x" = "x$base"; then
+- continue;
+- fi
+-
+- dir=`${DIRNAME} $x 2>/dev/null`
+- exclude=`echo ${dir} | ${GREP} /home`
+- if test "x$exclude" != "x"; then
+- continue
+- fi
+
+- already=`echo \$_smart_include_dir ${DIRS} | ${GREP} ${dir}`
+- if test "x$already" = "x"; then
+- DIRS="$DIRS $dir"
+- fi
+- done
+-fi
++ #include <et/com_err.h>
+
+-eval "_smart_include_dir=\"\$_smart_include_dir $DIRS\""
++int
++main (void)
++{
+
++ int a = 1;
+
+- for try in $_smart_include_dir; do
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for et/com_err.h in $try" >&5
+-$as_echo_n "checking for et/com_err.h in $try... " >&6; }
+- CPPFLAGS="-isystem $try $old_CPPFLAGS"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+
+- #include <et/com_err.h>
+-int
+-main ()
+-{
+-int a = 1;
+ ;
+ return 0;
+ }
++
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"
++then :
+
+- smart_include="-isystem $try"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+- break
++ smart_include="-isystem $try"
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++printf "%s\n" "yes" >&6; }
++ break
+
+-else
++else $as_nop
+
+- smart_include=
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ smart_include=
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
++printf "%s\n" "no" >&6; }
+
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+- done
+- CPPFLAGS="$old_CPPFLAGS"
++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
++done
++CPPFLAGS="$old_CPPFLAGS"
+ fi
+
+ if test "x$smart_include" != "x"; then
+- eval "ac_cv_header_$ac_safe=yes"
+- CPPFLAGS="$smart_include $old_CPPFLAGS"
+- SMART_CPPFLAGS="$smart_include $SMART_CPPFLAGS"
++eval "ac_cv_header_$ac_safe=yes"
++CPPFLAGS="$smart_include $old_CPPFLAGS"
++SMART_CPPFLAGS="$smart_include $SMART_CPPFLAGS"
+ fi
+
+ smart_prefix=
+
+- if test "$ac_cv_header_et_com_err_h" != "yes"; then
+- fail="$fail com_err.h"
+- else
+- krb5mod_cflags="$krb5mod_cflags -DET_COMM_ERR "
+- fi
++ if test "$ac_cv_header_et_com_err_h" != "yes"; then
++
++fail="$fail com_err.h"
++
++ else
++ krb5mod_cflags="$krb5mod_cflags -DET_COMM_ERR "
+ fi
+- else
+- krb5mod_cflags="$krb5mod_cflags -DHEIMDAL_KRB5"
+ fi
++else
++ krb5mod_cflags="$krb5mod_cflags -DHEIMDAL_KRB5"
++fi
++
++
+ targetname=rlm_krb5
+ else
+ targetname=
+ echo \*\*\* module rlm_krb5 is disabled.
++
++
++fr_status="disabled"
++
+ fi
+
+ if test x"$fail" != x""; then
++ targetname=""
++
++
+ if test x"${enable_strict_dependencies}" = x"yes"; then
+ as_fn_error $? "set --without-rlm_krb5 to disable it explicitly." "$LINENO" 5
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: silently not building rlm_krb5." >&5
+-$as_echo "$as_me: WARNING: silently not building rlm_krb5." >&2;}
+- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: FAILURE: rlm_krb5 requires: $fail." >&5
+-$as_echo "$as_me: WARNING: FAILURE: rlm_krb5 requires: $fail." >&2;};
+- targetname=""
++
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: silently not building rlm_krb5." >&5
++printf "%s\n" "$as_me: WARNING: silently not building rlm_krb5." >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: FAILURE: rlm_krb5 requires: $fail." >&5
++printf "%s\n" "$as_me: WARNING: FAILURE: rlm_krb5 requires: $fail." >&2;};
++ fail="$(echo $fail)"
++
++
++fr_status="skipping (requires $fail)"
++
++ fr_features=
++
+ fi
++
++else
++
++
++fr_status="OK"
++
+ fi
+
+-mod_ldflags="$krb5mod_ldflags $krb5libcrypto $SMART_LIBS"
+-mod_cflags="$krb5mod_cflags $krb5threadsafe $SMART_CPPFLAGS"
++if test x"$fr_features" = x""; then
++ $as_echo "$fr_status" > "config.report"
++else
++ $as_echo_n "$fr_status ... " > "config.report"
++ cat "config.report.tmp" >> "config.report"
++fi
+
++rm "config.report.tmp"
+
+
+
+
+- unset ac_cv_env_LIBS_set
+- unset ac_cv_env_LIBS_value
++mod_ldflags="$krb5mod_ldflags $krb5libcrypto $SMART_LIBS"
++mod_cflags="$krb5mod_cflags $krb5threadsafe $SMART_CPPFLAGS"
+
+- ac_config_files="$ac_config_files all.mk"
++
++
++
++ac_config_files="$ac_config_files all.mk"
+
+ cat >confcache <<\_ACEOF
+ # This file is a shell script that caches the results of configure
+@@ -4863,8 +5169,8 @@ _ACEOF
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
++ *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
++printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+@@ -4894,15 +5200,15 @@ $as_echo "$as_me: WARNING: cache variabl
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
++ s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+ if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+-$as_echo "$as_me: updating cache $cache_file" >&6;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
++printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+@@ -4916,8 +5222,8 @@ $as_echo "$as_me: updating cache $cache_
+ fi
+ fi
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
++printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+ fi
+ rm -f confcache
+@@ -4970,7 +5276,7 @@ U=
+ for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+- ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
++ ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+@@ -4986,8 +5292,8 @@ LTLIBOBJS=$ac_ltlibobjs
+ ac_write_fail=0
+ ac_clean_files_save=$ac_clean_files
+ ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
++printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
+ as_write_fail=0
+ cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+ #! $SHELL
+@@ -5010,14 +5316,16 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_wri
+
+ # Be more Bourne compatible
+ DUALCASE=1; export DUALCASE # for MKS sh
+-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
++as_nop=:
++if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
++then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+-else
++else $as_nop
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+@@ -5027,46 +5335,46 @@ esac
+ fi
+
+
++
++# Reset variables that may have inherited troublesome values from
++# the environment.
++
++# IFS needs to be set, to space, tab, and newline, in precisely that order.
++# (If _AS_PATH_WALK were called with IFS unset, it would have the
++# side effect of setting IFS to empty, thus disabling word splitting.)
++# Quoting is to prevent editors from complaining about space-tab.
+ as_nl='
+ '
+ export as_nl
+-# Printing a long string crashes Solaris 7 /usr/bin/printf.
+-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+-# Prefer a ksh shell builtin over an external printf program on Solaris,
+-# but without wasting forks for bash or zsh.
+-if test -z "$BASH_VERSION$ZSH_VERSION" \
+- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+- as_echo='print -r --'
+- as_echo_n='print -rn --'
+-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+- as_echo='printf %s\n'
+- as_echo_n='printf %s'
+-else
+- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+- as_echo_n='/usr/ucb/echo -n'
+- else
+- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+- as_echo_n_body='eval
+- arg=$1;
+- case $arg in #(
+- *"$as_nl"*)
+- expr "X$arg" : "X\\(.*\\)$as_nl";
+- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+- esac;
+- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+- '
+- export as_echo_n_body
+- as_echo_n='sh -c $as_echo_n_body as_echo'
+- fi
+- export as_echo_body
+- as_echo='sh -c $as_echo_body as_echo'
+-fi
++IFS=" "" $as_nl"
++
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# Ensure predictable behavior from utilities with locale-dependent output.
++LC_ALL=C
++export LC_ALL
++LANGUAGE=C
++export LANGUAGE
++
++# We cannot yet rely on "unset" to work, but we need these variables
++# to be unset--not just set to an empty or harmless value--now, to
++# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct
++# also avoids known problems related to "unset" and subshell syntax
++# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
++for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
++do eval test \${$as_var+y} \
++ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
++done
++
++# Ensure that fds 0, 1, and 2 are open.
++if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
++if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
++if (exec 3>&2) ; then :; else exec 2>/dev/null; fi
+
+ # The user is always right.
+-if test "${PATH_SEPARATOR+set}" != set; then
++if ${PATH_SEPARATOR+false} :; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+@@ -5075,13 +5383,6 @@ if test "${PATH_SEPARATOR+set}" != set;
+ fi
+
+
+-# IFS
+-# We need space, tab and new line, in precisely that order. Quoting is
+-# there to prevent editors from complaining about space-tab.
+-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+-# splitting by setting IFS to empty value.)
+-IFS=" "" $as_nl"
+-
+ # Find who we are. Look in the path if we contain no directory separator.
+ as_myself=
+ case $0 in #((
+@@ -5090,8 +5391,12 @@ case $0 in #((
+ for as_dir in $PATH
+ do
+ IFS=$as_save_IFS
+- test -z "$as_dir" && as_dir=.
+- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
++ case $as_dir in #(((
++ '') as_dir=./ ;;
++ */) ;;
++ *) as_dir=$as_dir/ ;;
++ esac
++ test -r "$as_dir$0" && as_myself=$as_dir$0 && break
+ done
+ IFS=$as_save_IFS
+
+@@ -5103,30 +5408,10 @@ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
++ printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+ fi
+
+-# Unset variables that we do not need and which cause bugs (e.g. in
+-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+-# suppresses any "Segmentation fault" message there. '((' could
+-# trigger a bug in pdksh 5.2.14.
+-for as_var in BASH_ENV ENV MAIL MAILPATH
+-do eval test x\${$as_var+set} = xset \
+- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+-done
+-PS1='$ '
+-PS2='> '
+-PS4='+ '
+-
+-# NLS nuisances.
+-LC_ALL=C
+-export LC_ALL
+-LANGUAGE=C
+-export LANGUAGE
+-
+-# CDPATH.
+-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+ # as_fn_error STATUS ERROR [LINENO LOG_FD]
+@@ -5139,13 +5424,14 @@ as_fn_error ()
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+- $as_echo "$as_me: error: $2" >&2
++ printf "%s\n" "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+ } # as_fn_error
+
+
++
+ # as_fn_set_status STATUS
+ # -----------------------
+ # Set $? to STATUS, without forking.
+@@ -5172,18 +5458,20 @@ as_fn_unset ()
+ { eval $1=; unset $1;}
+ }
+ as_unset=as_fn_unset
++
+ # as_fn_append VAR VALUE
+ # ----------------------
+ # Append the text in VALUE to the end of the definition contained in VAR. Take
+ # advantage of any shell optimizations that allow amortized linear growth over
+ # repeated appends, instead of the typical quadratic growth present in naive
+ # implementations.
+-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
++if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
++then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+-else
++else $as_nop
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+@@ -5195,12 +5483,13 @@ fi # as_fn_append
+ # Perform arithmetic evaluation on the ARGs, and store the result in the
+ # global $as_val. Take advantage of shells that can avoid forks. The arguments
+ # must be portable across $(()) and expr.
+-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
++if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
++then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+-else
++else $as_nop
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+@@ -5231,7 +5520,7 @@ as_me=`$as_basename -- "$0" ||
+ $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+-$as_echo X/"$0" |
++printf "%s\n" X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+@@ -5253,6 +5542,10 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTE
+ as_cr_digits='0123456789'
+ as_cr_alnum=$as_cr_Letters$as_cr_digits
+
++
++# Determine whether it's possible to make 'echo' print without a newline.
++# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
++# for compatibility with existing Makefiles.
+ ECHO_C= ECHO_N= ECHO_T=
+ case `echo -n x` in #(((((
+ -n*)
+@@ -5266,6 +5559,12 @@ case `echo -n x` in #(((((
+ ECHO_N='-n';;
+ esac
+
++# For backward compatibility with old third-party macros, we provide
++# the shell variables $as_echo and $as_echo_n. New code should use
++# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
++as_echo='printf %s\n'
++as_echo_n='printf %s'
++
+ rm -f conf$$ conf$$.exe conf$$.file
+ if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+@@ -5307,7 +5606,7 @@ as_fn_mkdir_p ()
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
++ *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+@@ -5316,7 +5615,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+-$as_echo X"$as_dir" |
++printf "%s\n" X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+@@ -5379,7 +5678,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wri
+ # values after options handling.
+ ac_log="
+ This file was extended by $as_me, which was
+-generated by GNU Autoconf 2.69. Invocation command line was
++generated by GNU Autoconf 2.71. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+@@ -5428,14 +5727,16 @@ $config_files
+ Report bugs to the package provider."
+
+ _ACEOF
++ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
++ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
+ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
++ac_cs_config='$ac_cs_config_escaped'
+ ac_cs_version="\\
+ config.status
+-configured by $0, generated by GNU Autoconf 2.69,
++configured by $0, generated by GNU Autoconf 2.71,
+ with options \\"\$ac_cs_config\\"
+
+-Copyright (C) 2012 Free Software Foundation, Inc.
++Copyright (C) 2021 Free Software Foundation, Inc.
+ This config.status script is free software; the Free Software Foundation
+ gives unlimited permission to copy, distribute and modify it."
+
+@@ -5472,21 +5773,21 @@ do
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+- $as_echo "$ac_cs_version"; exit ;;
++ printf "%s\n" "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+- $as_echo "$ac_cs_config"; exit ;;
++ printf "%s\n" "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
++ *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+- $as_echo "$ac_cs_usage"; exit ;;
++ printf "%s\n" "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+@@ -5514,7 +5815,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_writ
+ if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+- \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
++ \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+@@ -5528,7 +5829,7 @@ exec 5>>config.log
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+ ## Running $as_me. ##
+ _ASBOX
+- $as_echo "$ac_log"
++ printf "%s\n" "$ac_log"
+ } >&5
+
+ _ACEOF
+@@ -5553,7 +5854,7 @@ done
+ # We use the long form for the default assignment because of an extremely
+ # bizarre bug on SunOS 4.1.3.
+ if $ac_need_defaults; then
+- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
++ test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files
+ fi
+
+ # Have a temporary directory for convenience. Make it in the build tree
+@@ -5781,7 +6082,7 @@ do
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+- case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
++ case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+@@ -5789,17 +6090,17 @@ do
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+- $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
++ printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+- { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+-$as_echo "$as_me: creating $ac_file" >&6;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
++printf "%s\n" "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+- ac_sed_conf_input=`$as_echo "$configure_input" |
++ ac_sed_conf_input=`printf "%s\n" "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+@@ -5816,7 +6117,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+-$as_echo X"$ac_file" |
++printf "%s\n" X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+@@ -5840,9 +6141,9 @@ $as_echo X"$ac_file" |
+ case "$ac_dir" in
+ .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *)
+- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
++ ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
++ ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+@@ -5895,8 +6196,8 @@ ac_sed_dataroot='
+ case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+ *datarootdir*) ac_datarootdir_seen=yes;;
+ *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
++printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+ _ACEOF
+ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+@@ -5938,9 +6239,9 @@ test -z "$ac_datarootdir_hack$ac_dataroo
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+ which seems to be undefined. Please make sure it is defined" >&5
+-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
++printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+ which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+@@ -5987,8 +6288,8 @@ if test "$no_create" != yes; then
+ $ac_cs_success || as_fn_exit 1
+ fi
+ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
++printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+ fi
+
+
+--- a/src/modules/rlm_krb5/configure.ac
++++ b/src/modules/rlm_krb5/configure.ac
+@@ -1,187 +1,178 @@
+-AC_PREREQ([2.53])
+-AC_INIT(rlm_krb5.c)
++AC_PREREQ([2.71])
++AC_INIT
++AC_CONFIG_SRCDIR([rlm_krb5.c])
+ AC_REVISION($Revision$)
+-AC_DEFUN(modname,[rlm_krb5])
++FR_INIT_MODULE([rlm_krb5], [Kerberos support])
+
+-AC_ARG_WITH([]modname,
+-[ --with-[]modname build []modname. (default=yes)])
++FR_MODULE_START_TESTS
+
+-if test x$with_[]modname != xno; then
++AC_PROG_CC
++AC_PROG_CPP
+
+- AC_PROG_CC
+- AC_PROG_CPP
+-
+- dnl extra argument: --with-rlm-krb5-dir
+- rlm_krb5_dir=
+- AC_ARG_WITH(rlm-krb5-dir,
+- [ --with-rlm-krb5-dir=DIR Directory for krb5 files []],
+- [ case "$withval" in
+- no)
++dnl extra argument: --with-rlm-krb5-dir
++rlm_krb5_dir=
++AC_ARG_WITH(rlm-krb5-dir,
++ [AS_HELP_STRING([--with-rlm-krb5-dir=DIR],
++ [directory where krb5 files are installed])],
++ [case "$withval" in
++ no)
+ AC_MSG_ERROR(Need rlm-krb5-dir)
+ ;;
+- yes)
++ yes)
+ ;;
+- *)
++ *)
+ rlm_krb5_dir="$withval"
+ ;;
+- esac ]
+- )
++ esac])
+
+- AC_PATH_PROG(krb5_config, krb5-config, not-found, [${rlm_krb5_dir}/bin:${PATH}:/usr/bin:/usr/local/bin])
+- dnl #
+- dnl # If we can find krb5-config we can get the version of the library and determine
+- dnl # whether it's safe to enable threading.
+- dnl #
+- if test "$krb5_config" != 'not-found'; then
+- AC_MSG_CHECKING([krb5-config CFLAGS])
+- SMART_CPPFLAGS=$($krb5_config --cflags)
+- SMART_CPPFLAGS=[$(echo "$SMART_CPPFLAGS" | sed 's/-I[ ]*/-isystem /g')]
+- AC_MSG_RESULT("$SMART_CPPFLAGS")
+-
+- AC_MSG_CHECKING([krb5-config LDFLAGS])
+- SMART_LIBS=$($krb5_config --libs)
+- AC_MSG_RESULT(${SMART_LIBS})
+-
+- AC_MSG_CHECKING([krb5-config reported version])
+- krb5_version_raw=$($krb5_config --version)
+-
+- dnl # AWK originally from from https://github.com/hpc/lustre
+- krb5_version=$(echo "$krb5_version_raw" | head -n 1 | \
+- awk '{split($(4),v,"."); if (v@<:@"3"@:>@ = "") v@<:@"3"@:>@ = "0"; print v@<:@"1"@:>@v@<:@"2"@:>@v@<:@"3"@:>@ }')
+- AC_MSG_RESULT([${krb5_version_raw} ($krb5_version)])
+-
+- AC_MSG_CHECKING([krb5-config reported vendor])
+- krb5_vendor=$($krb5_config --vendor)
+- AC_MSG_RESULT([${krb5_vendor}])
+-
+- AC_MSG_CHECKING([canonical API type])
+- if test "$krb5_vendor" = "Massachusetts Institute of Technology" || \
+- echo "$krb5_vendor" | grep -i 'MIT' > /dev/null 2>&1 || \
+- echo "$krb5_version_raw" | grep -i 'MIT' > /dev/null 2>&1 ; then
+- AC_MSG_RESULT([MIT])
+- krb5_api_type='mit'
+- else
+- AC_MSG_RESULT([HEIMDAL])
+- krb5_api_type='heimdal'
+- fi
++AC_PATH_PROG(krb5_config, krb5-config, not-found, [${rlm_krb5_dir}/bin:${PATH}:/usr/bin:/usr/local/bin])
++dnl #
++dnl # If we can find krb5-config we can get the version of the library and determine
++dnl # whether it's safe to enable threading.
++dnl #
++if test "$krb5_config" != 'not-found'; then
++ AC_MSG_CHECKING([krb5-config CFLAGS])
++ SMART_CPPFLAGS=$($krb5_config --cflags)
++ SMART_CPPFLAGS=[$(echo "$SMART_CPPFLAGS" | sed 's/-I[ ]*/-isystem /g')]
++ AC_MSG_RESULT("$SMART_CPPFLAGS")
++
++ AC_MSG_CHECKING([krb5-config LDFLAGS])
++ SMART_LIBS=$($krb5_config --libs)
++ AC_MSG_RESULT(${SMART_LIBS})
++
++ AC_MSG_CHECKING([krb5-config reported version])
++ krb5_version_raw=$($krb5_config --version)
++
++ dnl # AWK originally from from https://github.com/hpc/lustre
++ krb5_version=$(echo "$krb5_version_raw" | head -n 1 | \
++ awk '{split($(4),v,"."); if (v@<:@"3"@:>@ == "") v@<:@"3"@:>@ = "0"; print v@<:@"1"@:>@v@<:@"2"@:>@v@<:@"3"@:>@ }')
++ AC_MSG_RESULT([${krb5_version_raw} ($krb5_version)])
++
++ AC_MSG_CHECKING([krb5-config reported vendor])
++ krb5_vendor=$($krb5_config --vendor)
++ AC_MSG_RESULT([${krb5_vendor}])
++
++ AC_MSG_CHECKING([canonical API type])
++ if test "$krb5_vendor" = "Massachusetts Institute of Technology" || \
++ echo "$krb5_vendor" | grep -i 'MIT' > /dev/null 2>&1 || \
++ echo "$krb5_version_raw" | grep -i 'MIT' > /dev/null 2>&1 ; then
++ AC_MSG_RESULT([MIT])
++ krb5_api_type='mit'
+ else
+- smart_try_dir="$rlm_krb5_dir/include"
+- FR_SMART_CHECK_INCLUDE(krb5.h)
+- if test "$ac_cv_header_krb5_h" != "yes"; then
+- fail="$fail krb5.h"
+- fi
+-
+- krb5libcrypto=
+- smart_try_dir="$rlm_krb5_dir/lib"
+- FR_SMART_CHECK_LIB(k5crypto, krb5_encrypt_data)
+- if test "x$ac_cv_lib_k5crypto_krb5_encrypt_data" = xyes; then
+- krb5libcrypto="-lk5crypto"
+- fi
+-
+- if test "x$krb5libcrypto" = x; then
+- FR_SMART_CHECK_LIB(crypto, DH_new)
+- if test "x$ac_cv_lib_crypto_DH_new" = xyes; then
+- krb5libcrypto="-lcrypto"
+- fi
+- fi
+-
+- if test "x$krb5libcrypto" = x; then
+- AC_MSG_WARN([neither krb5 'k5crypto' nor 'crypto' libraries are found!])
+- fi
+-
+- FR_SMART_CHECK_LIB(com_err, set_com_err_hook)
+- if test "x$ac_cv_lib_com_err_set_com_err_hook" != xyes; then
+- AC_MSG_WARN([the comm_err library isn't found!])
+- fi
++ AC_MSG_RESULT([HEIMDAL])
++ krb5_api_type='heimdal'
++ fi
++else
++ smart_try_dir="$rlm_krb5_dir/include"
++ FR_SMART_CHECK_INCLUDE(krb5.h)
++ if test "$ac_cv_header_krb5_h" != "yes"; then
++ FR_MODULE_FAIL([krb5.h])
++ fi
+
+- dnl #
+- dnl # Only the heimdal version of the library has this function
+- dnl #
+- FR_SMART_CHECK_LIB(krb5, krb5_verify_user_opt)
+- if test "x$ac_cv_lib_krb5_krb5_verify_user_opt" = xyes; then
+- krb5_api_type='heimdal'
+- else
+- krb5_api_type='mit'
++ krb5libcrypto=
++ smart_try_dir="$rlm_krb5_dir/lib"
++ FR_SMART_CHECK_LIB(k5crypto, krb5_encrypt_data)
++ if test "x$ac_cv_lib_k5crypto_krb5_encrypt_data" = xyes; then
++ krb5libcrypto="-lk5crypto"
++ fi
+
+- FR_SMART_CHECK_LIB(krb5, krb5_get_init_creds_password)
+- if test "x$ac_cv_lib_krb5_krb5_get_init_creds_password" != xyes; then
+- fail="$fail krb5"
+- fi
++ if test "x$krb5libcrypto" = x; then
++ FR_SMART_CHECK_LIB(crypto, DH_new)
++ if test "x$ac_cv_lib_crypto_DH_new" = xyes; then
++ krb5libcrypto="-lcrypto"
+ fi
+-
+ fi
+
+- dnl #
+- dnl # Need to ensure the test program(s) link against the right library
+- dnl #
+- LDFLAGS="${LDFLAGS} ${SMART_LIBS}"
+- CFLAGS="${CFLAGS} ${SMART_CPPFLAGS}"
+-
+- dnl #
+- dnl # Check how to free things returned by krb5_get_error_message
+- dnl #
+- AC_CHECK_FUNCS([krb5_get_error_message krb5_free_error_string krb5_free_error_message])
+- if test "x$ac_cv_func_krb5_get_error_message" = xyes; then
+- krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_GET_ERROR_MESSAGE"
+- fi
+- if test "x$ac_cv_func_krb5_free_error_message" = xyes; then
+- krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_FREE_ERROR_MESSAGE"
++ if test "x$krb5libcrypto" = x; then
++ AC_MSG_WARN([neither krb5 'k5crypto' nor 'crypto' libraries are found!])
+ fi
+- if test "x$ac_cv_func_krb5_free_error_string" = xyes; then
+- krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_FREE_ERROR_STRING"
++
++ FR_SMART_CHECK_LIB(com_err, set_com_err_hook)
++ if test "x$ac_cv_lib_com_err_set_com_err_hook" != xyes; then
++ AC_MSG_WARN([the comm_err library isn't found!])
+ fi
+
+ dnl #
+- dnl # Only check if version checks have not found kerberos to be thread unsafe
++ dnl # Only the heimdal version of the library has this function
+ dnl #
+- if test "$krb5threadsafe" != "no"; then
+- krb5threadsafe=
++ FR_SMART_CHECK_LIB(krb5, krb5_verify_user_opt)
++ if test "x$ac_cv_lib_krb5_krb5_verify_user_opt" = xyes; then
++ krb5_api_type='heimdal'
++ else
++ krb5_api_type='mit'
+
+- FR_SMART_CHECK_LIB(krb5, krb5_is_thread_safe)
+- if test "x$ac_cv_lib_krb5_krb5_is_thread_safe" = xyes; then
+- AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <krb5.h>]], [[return krb5_is_thread_safe() ? 0 : 1]])],
+- [krb5threadsafe="-DKRB5_IS_THREAD_SAFE"], [AC_MSG_WARN([[libkrb5 is not threadsafe]])])
++ FR_SMART_CHECK_LIB(krb5, krb5_get_init_creds_password)
++ if test "x$ac_cv_lib_krb5_krb5_get_init_creds_password" != xyes; then
++ FR_MODULE_FAIL([krb5])
+ fi
+- else
+- krb5threadsafe=""
+ fi
+
+- if test "$krb5_api_type" = "mit"; then
+- dnl #
+- dnl # This lives in different places depending on the distro
+- dnl #
+- FR_SMART_CHECK_INCLUDE([com_err.h])
+- if test "$ac_cv_header_com_err_h" != "yes"; then
+- FR_SMART_CHECK_INCLUDE([et/com_err.h])
+- if test "$ac_cv_header_et_com_err_h" != "yes"; then
+- fail="$fail com_err.h"
+- else
+- krb5mod_cflags="$krb5mod_cflags -DET_COMM_ERR "
+- fi
+- fi
+- else
+- krb5mod_cflags="$krb5mod_cflags -DHEIMDAL_KRB5"
++fi
++
++dnl #
++dnl # Need to ensure the test program(s) link against the right library
++dnl #
++LDFLAGS="${LDFLAGS} ${SMART_LIBS}"
++CFLAGS="${CFLAGS} ${SMART_CPPFLAGS}"
++
++dnl #
++dnl # Check how to free things returned by krb5_get_error_message
++dnl #
++AC_CHECK_FUNCS(\
++ krb5_get_error_message \
++ krb5_free_error_string \
++ krb5_free_error_message \
++)
++if test "x$ac_cv_func_krb5_get_error_message" = xyes; then
++ krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_GET_ERROR_MESSAGE"
++fi
++if test "x$ac_cv_func_krb5_free_error_message" = xyes; then
++ krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_FREE_ERROR_MESSAGE"
++fi
++if test "x$ac_cv_func_krb5_free_error_string" = xyes; then
++ krb5mod_cflags="${krb5mod_cflags} -DHAVE_KRB5_FREE_ERROR_STRING"
++fi
++
++dnl #
++dnl # Only check if version checks have not found kerberos to be thread unsafe
++dnl #
++if test "$krb5threadsafe" != "no"; then
++ krb5threadsafe=
++
++ FR_SMART_CHECK_LIB(krb5, krb5_is_thread_safe)
++ if test "x$ac_cv_lib_krb5_krb5_is_thread_safe" = xyes; then
++ AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <krb5.h>]], [[return krb5_is_thread_safe() ? 0 : 1]])],
++ [krb5threadsafe="-DKRB5_IS_THREAD_SAFE"], [AC_MSG_WARN([[libkrb5 is not threadsafe]])],
++ [AC_MSG_WARN(cross compiling: not checking)])
+ fi
+- targetname=modname
+ else
+- targetname=
+- echo \*\*\* module modname is disabled.
++ krb5threadsafe=""
+ fi
+
+-if test x"$fail" != x""; then
+- if test x"${enable_strict_dependencies}" = x"yes"; then
+- AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.])
+- else
+- AC_MSG_WARN([silently not building ]modname[.])
+- AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]);
+- targetname=""
++if test "$krb5_api_type" = "mit"; then
++ dnl #
++ dnl # This lives in different places depending on the distro
++ dnl #
++ FR_SMART_CHECK_INCLUDE([com_err.h])
++ if test "$ac_cv_header_com_err_h" != "yes"; then
++ FR_SMART_CHECK_INCLUDE([et/com_err.h])
++ if test "$ac_cv_header_et_com_err_h" != "yes"; then
++ FR_MODULE_FAIL([com_err.h])
++ else
++ krb5mod_cflags="$krb5mod_cflags -DET_COMM_ERR "
++ fi
+ fi
++else
++ krb5mod_cflags="$krb5mod_cflags -DHEIMDAL_KRB5"
+ fi
+
++FR_MODULE_END_TESTS(strict)
++
+ mod_ldflags="$krb5mod_ldflags $krb5libcrypto $SMART_LIBS"
+ mod_cflags="$krb5mod_cflags $krb5threadsafe $SMART_CPPFLAGS"
+
+ AC_SUBST(mod_ldflags)
+ AC_SUBST(mod_cflags)
+-AC_SUBST(targetname)
+-AC_OUTPUT(all.mk)
++
++AC_CONFIG_FILES([all.mk])
++AC_OUTPUT
include $(TOPDIR)/rules.mk
PKG_NAME:=gensio
-PKG_VERSION:=2.4.2
+PKG_VERSION:=2.7.6
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/ser2net
-PKG_HASH:=2593c1e7beaec3a0a4acbf60f94bbf64b99883d86f172a3b584eba5f67441b4b
+PKG_HASH:=7574fb710ddd6580d53ea44af4ddfc57f28dbcdc646d842f7ed8ccc1235fdf89
PKG_LICENSE:=GPL-2.0-or-later
PKG_LICENSE_FILES:=COPYING
include ../../lang/python/python3-package.mk
CONFIGURE_ARGS += \
+ --$(if $(CONFIG_GENSIO_AVAHI),with,without)-avahi \
--$(if $(CONFIG_GENSIO_SSL),with,without)-openssl \
--$(if $(CONFIG_GENSIO_SCTP),with,without)-sctp \
--$(if $(CONFIG_GENSIO_WRAP),with,without)-tcp-wrappers \
--$(if $(CONFIG_GENSIO_PTHREADS),with,without)-pthreads \
--$(if $(CONFIG_GENSIO_GLIB),with,without)-glib \
--$(if $(CONFIG_GENSIO_TCL),with,without)-tcl \
+ --without-afskmdm \
+ --without-alsa \
+ --without-ax25 \
+ --without-cm108gpio \
+ --without-dnssd \
--without-go \
+ --without-ipmisol \
+ --without-kiss \
--without-openipmi \
+ --without-portaudio \
+ --without-sound \
+ --without-udev \
--with-cplusplus \
+ --with-flock-locking \
+ --with-uucp-locking \
--disable-doc
CONFIGURE_VARS += \
PYTHON_LIBS="$(shell $(STAGING_DIR)/host/bin/$(PYTHON3)-config --ldflags) -l${PYTHON3}" \
PYTHON_CPPFLAGS="$(shell $(STAGING_DIR)/host/bin/$(PYTHON3)-config --includes)" \
PYTHON="$(STAGING_DIR_HOSTPKG)/bin/$(PYTHON3)"
+
+MAKE_VARS += \
+ PYTHON_LIBS="$(shell $(STAGING_DIR)/host/bin/$(PYTHON3)-config --ldflags) -l${PYTHON3}"
else
CONFIGURE_ARGS += \
--without-python \
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include/gensio/
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/gensio/* $(1)/usr/include/gensio/
- $(INSTALL_DIR) $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/lib/gensio
$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a,la} $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/gensio/* $(1)/usr/lib/gensio/
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
ifneq ($(CONFIG_PACKAGE_python3-gensio),)
endef
define Package/libgensio/install
- $(INSTALL_DIR) $(1)/usr/lib
+ $(INSTALL_DIR) $(1)/usr/lib/gensio
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgensio.so.* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgensioosh.so.* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgensiomdns.so.* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/gensio/* $(1)/usr/lib/gensio/
ifeq ($(CONFIG_GENSIO_GLIB),y)
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgensioglib.so.* $(1)/usr/lib/
endif
define Package/libgensiocpp/install
$(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgensiocpp.so.* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgensio*cpp.so.* $(1)/usr/lib/
endef
$(eval $(call BuildPackage,libgensio))
--- /dev/null
+From 6bbc3056c4b9192010d888672d97810609ee23f9 Mon Sep 17 00:00:00 2001
+From: Michael Heimpold <mhei@heimpold.de>
+Date: Sat, 18 Nov 2023 21:46:15 +0100
+Subject: [PATCH] Ensure that $ax_python_devel_found is defined
+
+Otherwise in case of --without-python, it triggers an error like:
+-snip-
+...
+checking consistency of all components of python development environment... yes
+./configure: line 23729: test: =: unary operator expected
+...
+-snap-
+
+Signed-off-by: Michael Heimpold <mhei@heimpold.de>
+---
+ configure.ac | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -1997,6 +1997,9 @@ if test "x$trypython" = "xyes"; then
+ PYTHON_CPPFLAGS="$pythoncflags"
+ fi
+ AX_PYTHON_DEVEL([], [true])
++ ax_python_devel_found=yes
++else
++ ax_python_devel_found=no
+ fi
+ if test $ax_python_devel_found = yes; then
+ AX_PROG_PYTHON_VERSION([3.0.0],
--- /dev/null
+--- a/m4/ax_python_devel.m4
++++ b/m4/ax_python_devel.m4
+@@ -72,7 +72,7 @@
+ # modified version of the Autoconf Macro, you may extend this special
+ # exception to the GPL to apply to your modified version as well.
+
+-#serial 34
++#serial 35
+
+ AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
+ AC_DEFUN([AX_PYTHON_DEVEL],[
--- /dev/null
+From f53fc85ee9734dd21447ea3438b7ba1edcd1bcf8 Mon Sep 17 00:00:00 2001
+From: Michael Heimpold <mhei@heimpold.de>
+Date: Tue, 21 Nov 2023 23:27:45 +0100
+Subject: [PATCH] Revert ax_pkg_swig.m4 to latest vanilla version
+
+And instead of extending the macro, we can use the already
+create variable 'available_swig_vernum' to compare the
+required version number.
+
+Signed-off-by: Michael Heimpold <mhei@heimpold.de>
+---
+ configure.ac | 26 ++++++++++++--------------
+ m4/ax_pkg_swig.m4 | 20 +++++++++-----------
+ 2 files changed, 21 insertions(+), 25 deletions(-)
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -1956,21 +1956,19 @@ AC_CHECK_LIB(nsl, main, [HAVE_LIBNSL=1;
+ SWIG_DIR=
+ SWIG_CPP_DIR=
+ SWIG=
+-SWIG_NUMVERSION=0
++available_swig_vernum=0
+ if test "x$tryswig" = "xyes"; then
+ if test "x$swigprog" != "x"; then
+ SWIG="$swigprog"
+ fi
+- AX_PKG_SWIG([1.3.21])
+- if test "x$SWIG" != "x"; then
+- AC_DEFINE([HAVE_SWIG], [], [Have swig installed])
+- SWIG_DIR=swig
+- if test $SWIG_NUMVERSION -ge 40100; then
+- SWIG_CPP_DIR=swig
+- else
+- AC_MSG_WARN([SWIG version >= 4.1.0 is required for C++ swig.])
+- fi
+- fi
++ AX_PKG_SWIG(4.1.0,
++ [
++ AC_DEFINE([HAVE_SWIG], [], [Have swig installed])
++ SWIG_DIR=swig
++ SWIG_CPP_DIR=swig
++ ], [
++ AC_MSG_WARN([SWIG version >= 4.1.0 is required for C++ swig.])
++ ])
+ fi
+ AC_SUBST(SWIG_DIR)
+ AC_SUBST(SWIG_CPP_DIR)
+@@ -2055,7 +2053,7 @@ AC_SUBST(PYTHON_UNDEF_LIBS)
+ PYTHON_EXECUTABLE="${PYTHON}"
+ AC_SUBST(PYTHON_EXECUTABLE)
+
+-if test $SWIG_NUMVERSION -ge 40100 -a "${enable_shared}" = yes; then
++if test $available_swig_vernum -ge 40100 -a "${enable_shared}" = yes; then
+ trygo=yes
+ else
+ trygo=no
+@@ -2076,7 +2074,7 @@ AC_ARG_WITH(go,
+ fi,
+ )
+
+-if test $trygo = yes -a $SWIG_NUMVERSION -lt 40100; then
++if test $trygo = yes -a $available_swig_vernum -lt 40100; then
+ AC_MSG_ERROR([Go enabled, but swig version must be >= 4.1.0 for that])
+ fi
+ GODIR=
+@@ -2363,7 +2361,7 @@ pr_op " shared libraries: " $enable_sh
+ pr_op " sctp sendv: " $ac_cv_lib_sctp_sctp_sendv
+ pr_vop " python: " "$ax_python_version"
+ if test "$SWIG_CPP_DIR" = "swig"; then
+- prrw " swig: " "$SWIG_NUMVERSION"
++ prrw " swig: " "$available_swig_vernum"
+ else
+ prrw " swig: " "no"
+ fi
+--- a/m4/ax_pkg_swig.m4
++++ b/m4/ax_pkg_swig.m4
+@@ -19,11 +19,6 @@
+ # 1.3.17), AX_PKG_SWIG checks that the swig package is this version number
+ # or higher.
+ #
+-# If successful, SWIG_NUMVERSION is set to a numeric value for the
+-# version found in the format NNnnpp where NN is the major version,
+-# nn is the minor version, and pp is the patch version. This is
+-# easy to directly compare with a number.
+-#
+ # As usual, action-if-found is executed if SWIG is found, otherwise
+ # action-if-not-found is executed.
+ #
+@@ -41,6 +36,8 @@
+ # Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
+ # Copyright (c) 2008 Andrew Collier
+ # Copyright (c) 2011 Murray Cumming <murrayc@openismus.com>
++# Copyright (c) 2018 Reini Urban <rurban@cpan.org>
++# Copyright (c) 2021 Vincent Danjean <Vincent.Danjean@ens-lyon.org>
+ #
+ # This program is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by the
+@@ -68,14 +65,16 @@
+ # modified version of the Autoconf Macro, you may extend this special
+ # exception to the GPL to apply to your modified version as well.
+
+-#serial 13
++#serial 15
+
+ AC_DEFUN([AX_PKG_SWIG],[
+ # Find path to the "swig" executable.
+ AC_PATH_PROGS([SWIG],[swig swig3.0 swig2.0])
+ if test -z "$SWIG" ; then
+ m4_ifval([$3],[$3],[:])
+- elif test -n "$1" ; then
++ elif test -z "$1" ; then
++ m4_ifval([$2],[$2],[:])
++ else
+ AC_MSG_CHECKING([SWIG version])
+ [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
+ AC_MSG_RESULT([$swig_version])
+@@ -86,12 +85,12 @@ AC_DEFUN([AX_PKG_SWIG],[
+ if test -z "$required_major" ; then
+ [required_major=0]
+ fi
+- [required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
++ [required=`echo $required. | sed 's/[0-9]*[^0-9]//'`]
+ [required_minor=`echo $required | sed 's/[^0-9].*//'`]
+ if test -z "$required_minor" ; then
+ [required_minor=0]
+ fi
+- [required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
++ [required=`echo $required. | sed 's/[0-9]*[^0-9]//'`]
+ [required_patch=`echo $required | sed 's/[^0-9].*//'`]
+ if test -z "$required_patch" ; then
+ [required_patch=0]
+@@ -126,10 +125,9 @@ AC_DEFUN([AX_PKG_SWIG],[
+ m4_ifval([$3],[$3],[])
+ else
+ AC_MSG_CHECKING([for SWIG library])
+- SWIG_LIB=`$SWIG -swiglib | tail -1`
++ SWIG_LIB=`$SWIG -swiglib | tr '\r\n' ' '`
+ AC_MSG_RESULT([$SWIG_LIB])
+ m4_ifval([$2],[$2],[])
+- SWIG_NUMVERSION=$available_swig_vernum
+ fi
+ else
+ AC_MSG_WARN([cannot determine SWIG version])
+++ /dev/null
---- a/tools/gensiotool.c
-+++ b/tools/gensiotool.c
-@@ -44,7 +44,7 @@
- #include <signal.h>
- #include <errno.h>
- #include <sys/types.h>
--#include <sys/unistd.h>
-+#include <unistd.h>
- #include <syslog.h>
- #endif
-
include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy
-PKG_VERSION:=2.8.3
+PKG_VERSION:=2.8.4
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.haproxy.org/download/2.8/src
-PKG_HASH:=9ecc6ffe67a977d1ed279107bbdab790d73ae2a626bc38eee23fa1f6786a759e
+PKG_HASH:=81bacbf50ec6d0f7ecaaad7c03e59978b00322fbdad6ed4a989dd31754b6f25d
PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>, \
Christian Lachner <gladiac@gmail.com>
define Package/haproxy
$(call Package/haproxy/Default)
TITLE+=with SSL support
- DEPENDS+= +libpcre +libltdl +zlib +libpthread +liblua5.3 +libopenssl +libncurses +libreadline +libatomic
+ DEPENDS+= +libpcre2 +libltdl +zlib +libpthread +liblua5.3 +libopenssl +libncurses +libreadline +libatomic
VARIANT:=ssl
endef
$(call Package/haproxy/Default)
TITLE+=without SSL support
VARIANT:=nossl
- DEPENDS+= +libpcre +libltdl +zlib +libpthread +liblua5.3 +libatomic
+ DEPENDS+= +libpcre2 +libltdl +zlib +libpthread +liblua5.3 +libatomic
CONFLICTS:=haproxy
endef
PCREDIR="$(STAGING_DIR)/usr/" \
USE_LUA=1 LUA_LIB_NAME="lua5.3" LUA_INC="$(STAGING_DIR)/usr/include/lua5.3" LUA_LIB="$(STAGING_DIR)/usr/lib" \
SMALL_OPTS="-DBUFSIZE=16384 -DMAXREWRITE=1030 -DSYSTEM_MAXCONN=165530" \
- USE_ZLIB=1 USE_PCRE=1 USE_PCRE_JIT=1 USE_PTHREAD_PSHARED=1 USE_LIBATOMIC=1 USE_PROMEX=1 \
+ USE_ZLIB=1 USE_PCRE2=1 USE_PCRE2_JIT=1 USE_PTHREAD_PSHARED=1 USE_LIBATOMIC=1 USE_PROMEX=1 \
VERSION="$(PKG_VERSION)" SUBVERS="-$(PKG_RELEASE)" \
VERDATE="$(shell date -d @$(SOURCE_DATE_EPOCH) '+%Y/%m/%d')" IGNOREGIT=1 \
$(ADDON) \
#!/bin/sh
CLONEURL=https://git.haproxy.org/git/haproxy-2.8.git
-BASE_TAG=v2.8.3
+BASE_TAG=v2.8.4
TMP_REPODIR=tmprepo
PATCHESDIR=patches
include $(TOPDIR)/rules.mk
PKG_NAME:=hcxdumptool
-PKG_VERSION:=6.2.4
+PKG_VERSION:=6.3.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/zerbea/hcxdumptool/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=cadeb4b2f00da3a1df65cb53080e134f201ef73825d35049110764faf699028d
+PKG_HASH:=1f6fe2b4757a5f20adeb6cc469693b4d0e8c49ba290450e10a37699d9f9a2a42
PKG_MAINTAINER:=Andreas Nilsen <adde88@gmail.com>
PKG_LICENSE:=MIT
+++ /dev/null
---- a/hcxdumptool.c
-+++ b/hcxdumptool.c
-@@ -571,10 +571,6 @@ if(rebootflag == true)
- }
- }
-
--EVP_cleanup();
--CRYPTO_cleanup_all_ex_data();
--ERR_free_strings();
--
- if(errorcount != 0) exit(EXIT_FAILURE);
- if(totflag == true) exit(USER_EXIT_TOT);
- exit(EXIT_SUCCESS);
-@@ -7777,8 +7773,6 @@ return true;
- /*===========================================================================*/
- static inline bool tlsinit()
- {
--SSL_load_error_strings();
--OpenSSL_add_ssl_algorithms();
- if((tlsctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
- {
- fprintf(stderr, "OpenSSl can't create SSL context\n");
-@@ -7797,7 +7791,6 @@ if(SSL_CTX_use_PrivateKey_file(tlsctx, e
- if((eaptlsctx = (eaptlsctx_t*)malloc(EAPTLSCTX_SIZE)) == NULL) return false;
- memset(eaptlsctx, 0, EAPTLSCTX_SIZE);
- SSL_CTX_set_session_cache_mode(tlsctx, SSL_SESS_CACHE_OFF);
--SSL_CTX_set_ecdh_auto(tlsctx, 1);
- SSL_CTX_set_verify(tlsctx, (SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE), eap_tls_clientverify_cb);
- #if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
- SSL_CTX_set_min_proto_version(tlsctx, TLS1_VERSION);
-@@ -7872,8 +7865,6 @@ if(gpiostatusled > 0)
- }
-
-
--ERR_load_crypto_strings();
--OpenSSL_add_all_algorithms();
- opensslversion = OpenSSL_version_num();
- opensslversionmajor = (opensslversion & 0x10000000L) >> 28;
- opensslversionminor = (opensslversion & 0x01100000L) >> 20;
include $(TOPDIR)/rules.mk
PKG_NAME:=hcxtools
-PKG_VERSION:=6.2.4
+PKG_VERSION:=6.3.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/zerbea/hcxtools/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=74299313dd15ed38f07b42201903ab85ebbc3ad220a01fff1bd5c967cfea817d
+PKG_HASH:=555e46a59df6a77c5aa73b99ffa8c1e84fa79e24ffaf5180de1d3a7f4ab7a470
PKG_MAINTAINER:=Andreas Nilsen <adde88@gmail.com>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=license.txt
include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
define Package/hcxtools
SECTION:=net
for the use with latest hashcat or John the Ripper.
endef
-define Build/Compile
- $(MAKE) -C $(PKG_BUILD_DIR)/ \
- $(TARGET_CONFIGURE_OPTS) \
- CFLAGS="$(TARGET_CFLAGS)"
-endef
-
define Package/hcxtools/install
- $(INSTALL_DIR) $(1)/sbin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxeiutool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxessidtool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxhash2cap $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxhashcattool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxhashtool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxmactool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxpcapngtool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxpmkidtool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxpmktool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxpsktool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/hcxwltool $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/whoismac $(1)/sbin/
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/wlancap2wpasec $(1)/sbin/
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/hcxeiutool $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/hcxhash2cap $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/hcxhashtool $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/hcxpcapngtool $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/hcxpmktool $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/hcxpsktool $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/hcxwltool $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/whoismac $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wlancap2wpasec $(1)/usr/bin/
endef
$(eval $(call BuildPackage,hcxtools))
+++ /dev/null
---- a/hcxhashtool.c
-+++ b/hcxhashtool.c
-@@ -107,9 +107,6 @@ static void closelists()
- {
- if(hashlist != NULL) free(hashlist);
- if(ouilist != NULL) free(ouilist);
--EVP_cleanup();
--CRYPTO_cleanup_all_ex_data();
--ERR_free_strings();
- return;
- }
- /*===========================================================================*/
-@@ -128,8 +125,6 @@ eapolwrittencount = 0;
- essidwrittencount = 0;
- hccapxwrittencount = 0;
- hccapwrittencount = 0;
--ERR_load_crypto_strings();
--OpenSSL_add_all_algorithms();
- if((hashlist = (hashlist_t*)calloc(hashlistcount, HASHLIST_SIZE)) == NULL) return false;
- if((ouilist = (ouilist_t*)calloc(ouilistcount, OUILIST_SIZE)) == NULL) return false;
- return true;
---- a/hcxpcapngtool.c
-+++ b/hcxpcapngtool.c
-@@ -366,9 +366,6 @@ if(eapmschapv2msglist != NULL) free(eapm
- if(eapmschapv2hashlist != NULL) free(eapmschapv2hashlist);
- if(tacacsplist != NULL) free(tacacsplist);
-
--EVP_cleanup();
--CRYPTO_cleanup_all_ex_data();
--ERR_free_strings();
- return;
- }
- /*===========================================================================*/
-@@ -377,8 +374,6 @@ static bool initlists()
- static unsigned long opensslversion;
- static const char nastring[] = { "N/A" };
-
--ERR_load_crypto_strings();
--OpenSSL_add_all_algorithms();
- opensslversion = OpenSSL_version_num();
- opensslversionmajor = (opensslversion & 0x10000000L) >> 28;
- opensslversionminor = (opensslversion & 0x01100000L) >> 20;
---- a/hcxpmktool.c
-+++ b/hcxpmktool.c
-@@ -923,8 +923,6 @@ while((auswahl = getopt_long(argc, argv,
- }
- }
-
--ERR_load_crypto_strings();
--OpenSSL_add_all_algorithms();
- printf("\n");
- if((essidstring != NULL) && (pskstring != NULL) && (pmkstring == NULL) && (hashlinestring == NULL))
- {
-@@ -956,9 +954,6 @@ else if((essidstring != NULL) && (pskstr
- }
-
- printf("\n");
--EVP_cleanup();
--CRYPTO_cleanup_all_ex_data();
--ERR_free_strings();
- return EXIT_SUCCESS;
- }
- /*===========================================================================*/
---- a/hcxpsktool.c
-+++ b/hcxpsktool.c
-@@ -63,8 +63,6 @@ essidglen = 32;
- t = time(NULL);
- tm = localtime(&t);
- thisyear = tm->tm_year +1900;
--ERR_load_crypto_strings();
--OpenSSL_add_all_algorithms();
- return;
- }
- /*===========================================================================*/
-@@ -2832,10 +2830,6 @@ if(pskname != NULL)
- fclose(fhpsk);
- }
-
--EVP_cleanup();
--CRYPTO_cleanup_all_ex_data();
--ERR_free_strings();
--
- return EXIT_SUCCESS;
- }
- /*===========================================================================*/
include $(TOPDIR)/rules.mk
PKG_NAME:=https-dns-proxy
-PKG_VERSION:=2023-05-25
+PKG_VERSION:=2023-10-25
PKG_RELEASE:=5
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/aarond10/https_dns_proxy/
PKG_SOURCE_DATE:=$(PKG_VERSION)
-PKG_SOURCE_VERSION:=d03e11572562f008f68df217a7378628f1bb7b79
-PKG_MIRROR_HASH:=5af3683c48bc9e493ca2761a6f7ee756431692a695d6008f61b8b92431036dca
+PKG_SOURCE_VERSION:=977341a4e35a37ee454e97e82caf4276b1b4961a
+PKG_MIRROR_HASH:=8622846f1038ac05436a48d9b36a07c516cbb6504ce68e7ee8c5529788fac39b
+
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
TITLE:=DNS Over HTTPS Proxy
URL:=https://docs.openwrt.melmac.net/https-dns-proxy/
DEPENDS:=+libcares +libcurl +libev +ca-bundle +jsonfilter
+ DEPENDS+=+!BUSYBOX_DEFAULT_GREP:grep
+ DEPENDS+=+!BUSYBOX_DEFAULT_SED:sed
CONFLICTS:=https_dns_proxy
endef
$(SED) "s|^\(readonly PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/https-dns-proxy
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/etc/config/https-dns-proxy $(1)/etc/config/https-dns-proxy
- $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
- $(INSTALL_DATA) ./files/etc/hotplug.d/iface/90-https-dns-proxy $(1)/etc/hotplug.d/iface/90-https-dns-proxy
$(INSTALL_DIR) $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/50-https-dns-proxy-migrate-options.sh $(1)/etc/uci-defaults/50-https-dns-proxy-migrate-options.sh
endef
+++ /dev/null
-#!/bin/sh
-# Copied from https://openwrt.org/docs/guide-user/advanced/hotplug_extras
-# shellcheck disable=SC1091
-. /lib/functions/network.sh
-network_flush_cache
-network_find_wan NET_IF
-network_find_wan6 NET_IF6
-[ "$INTERFACE" != "$NET_IF" ] && [ "$INTERFACE" != "$NET_IF6" ] && exit 0
-[ "$ACTION" != "ifup" ] && [ "$ACTION" != "ifupdate" ] && exit 0
-[ "$ACTION" = "ifupdate" ] && [ -z "$IFUPDATE_ADDRESSES" ] && \
-[ -z "$IFUPDATE_DATA" ] && exit 0
-
-sleep 10
-/etc/init.d/https-dns-proxy start 'on_hotplug'
# shellcheck disable=SC2034
START=90
# shellcheck disable=SC2034
+STOP=15
+# shellcheck disable=SC2034
USE_PROCD=1
if type extra_command 1>/dev/null 2>&1; then
readonly canaryDomainsMozilla='use-application-dns.net'
readonly canaryDomainsiCloud='mask.icloud.com mask-h2.icloud.com'
-str_contains() { [ -n "$1" ] &&[ -n "$2" ] && [ "${1//$2}" != "$1" ]; }
+on_boot_trigger=
+
+dnsmasq_restart() { [ -x /etc/init.d/dnsmasq ] || return 1; /etc/init.d/dnsmasq restart >/dev/null 2>&1; }
+is_fw4_restart_needed() { [ "$(uci_get "$packageName" 'config' 'force_dns' '1')" = '1' ]; }
is_mac_address() { expr "$1" : '[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]$' >/dev/null; }
is_ipv4() { expr "$1" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; }
is_ipv6() { ! is_mac_address "$1" && str_contains "$1" ":"; }
+is_resolver_working() { resolveip -t 3 one.one.one.one >/dev/null 2>&1; }
output() {
local msg memmsg logmsg
local sharedMemoryOutput="/dev/shm/$packageName-output"
output_okn() { output "${_OK_}\\n"; }
output_fail() { output "$_FAIL_"; }
output_failn() { output "${_FAIL_}\\n"; }
+str_contains() { [ -n "$1" ] &&[ -n "$2" ] && [ "${1//$2}" != "$1" ]; }
uci_add_list_if_new() {
local PACKAGE="$1"
local CONFIG="$2"
local OPTION="$3"
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} changes "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}"
}
-
-dnsmasq_restart() { [ -x /etc/init.d/dnsmasq ] || return 1; /etc/init.d/dnsmasq restart >/dev/null 2>&1; }
-
version() { echo "$PKG_VERSION"; }
xappend() { PROG_param="$PROG_param $1"; }
[ "$ipv6_resolvers_only" -eq 0 ] && xappend '-4'
}
-resolver_health_check() { resolveip -t 3 one.one.one.one >/dev/null 2>&1; }
-
boot() {
ubus -t 30 wait_for network.interface 2>/dev/null
- rc_procd start_service 'on_boot'
- resolver_health_check || rc_procd stop_service 'on_boot'
+ on_boot_trigger=1
+ rc_procd start_service 'on_boot' && service_started 'on_boot'
+ is_resolver_working || { rc_procd stop_service 'on_boot' && service_stopped 'on_boot'; }
}
start_instance() {
json_add_object mdns
procd_add_mdns_service "$packageName" 'udp' "$port" "DNS over HTTPS proxy"
json_close_object
- if [ "$force_dns" -ne 0 ]; then
+ if [ "$force_dns" -ne '0' ]; then
json_add_array firewall
for iface in $procd_fw_src_interfaces; do
for p in $force_dns_port; do
procd_close_data
procd_close_instance
- if [ "$?" ]; then
+# shellcheck disable=SC2181
+ if [ "$?" -eq 0 ]; then
config_get listen_addr "$cfg" 'listen_addr' '127.0.0.1'
config_get listen_port "$cfg" 'listen_port' "$port"
if [ "$dnsmasq_config_update" = '*' ]; then
fi
output_ok
port="$((port+1))"
- force_dns=0
+ force_dns='0'
else
output_fail
fi
output "Updating dnsmasq config "
if uci_commit 'dhcp'; then
output_okn
- else
- output_failn
- fi
- param='dnsmasq_restart'
- fi
- if [ "$param" = 'on_hotplug' ] || [ "$param" = 'on_boot' ] || \
- [ "$param" = 'dnsmasq_restart' ] ; then
- output "Restarting dnsmasq "
- if dnsmasq_restart; then
- output_okn
+ param='on_config_update'
else
output_failn
fi
fi
+ case "$param" in
+ on_boot|on_config_update|on_hotplug)
+ output "Restarting dnsmasq ${param:+$param }"
+ if dnsmasq_restart; then
+ output_okn
+ else
+ output_failn
+ fi
+ ;;
+ esac
}
stop_service() {
[ "$s" = '0' ] && output_okn || output_failn
}
-# shellcheck disable=SC1091
service_triggers() {
local wan wan6 i
local procd_trigger_wan6
- config_load "$packageName"
- config_get_bool procd_trigger_wan6 'config' 'procd_trigger_wan6' '0'
- . /lib/functions/network.sh
- network_flush_cache
- network_find_wan wan
- wan="${wan:-wan}"
- if [ "$procd_trigger_wan6" -ne 0 ]; then
- network_find_wan6 wan6
- wan6="${wan6:-wan6}"
+ if [ "$on_boot_trigger" = '1' ]; then
+ procd_add_raw_trigger "interface.*.up" 3000 "/etc/init.d/${packageName}" restart 'on_interface_up'
+ else
+ config_load "$packageName"
+ config_get_bool procd_trigger_wan6 'config' 'procd_trigger_wan6' '0'
+ . /lib/functions/network.sh
+ network_flush_cache
+ network_find_wan wan
+ wan="${wan:-wan}"
+ if [ "$procd_trigger_wan6" -ne 0 ]; then
+ network_find_wan6 wan6
+ wan6="${wan6:-wan6}"
+ fi
+ for i in $wan $wan6; do
+ procd_add_interface_trigger "interface.*" "$i" "/etc/init.d/${packageName}" restart 'on_interface_trigger'
+ done
fi
- for i in "$wan" "$wan6"; do
- [ -n "$i" ] && procd_add_interface_trigger "interface.*" "$i" "/etc/init.d/${packageName}" restart
- done
- procd_add_config_trigger "config.change" "$packageName" "/etc/init.d/${packageName}" reload
+ procd_add_config_trigger "config.change" "$packageName" "/etc/init.d/${packageName}" reload 'on_config_change'
}
-service_started() { procd_set_config_changed firewall; }
-service_stopped() { procd_set_config_changed firewall; }
-restart() { procd_send_signal "$packageName"; rc_procd start_service; }
+service_started() { is_fw4_restart_needed && procd_set_config_changed firewall; }
+service_stopped() { is_fw4_restart_needed && procd_set_config_changed firewall; }
+restart() { procd_send_signal "$packageName"; rc_procd start_service "$*"; }
dnsmasq_doh_server() {
local cfg="$1" param="$2" address="${3:-127.0.0.1}" port="$4" i
uci_add_list_if_new 'dhcp' "$cfg" 'doh_server' "${address}#${port}"
;;
remove)
- for i in $(uci -q get "dhcp.$cfg.doh_server"); do
+ for i in $(uci_get 'dhcp' "$cfg" 'doh_server'); do
uci_remove_list 'dhcp' "$cfg" 'server' "$i"
uci_remove_list 'dhcp' "$cfg" 'doh_server' "$i"
done
endif()
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra --pedantic -Wno-strict-aliasing -Wno-variadic-macros")
--set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG")
+-set(CMAKE_C_FLAGS_DEBUG "-gdwarf-4 -DDEBUG")
-set(CMAKE_C_FLAGS_RELEASE "-O2")
+#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra --pedantic -Wno-strict-aliasing -Wno-variadic-macros")
-+#set(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG")
++#set(CMAKE_C_FLAGS_DEBUG "-gdwarf-4 -DDEBUG")
+#set(CMAKE_C_FLAGS_RELEASE "-O2")
if ((CMAKE_C_COMPILER_ID MATCHES GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 9) OR
--- a/src/options.c
+++ b/src/options.c
-@@ -22,7 +22,7 @@ const char * options_sw_version() {
+@@ -24,7 +24,7 @@ const char * options_sw_version(void) {
#ifdef SW_VERSION
return SW_VERSION;
#else
-- return "2023.01.01-atLeast"; // update date sometimes, like 1-2 times a year
-+ return "2023-05-25-1"; // update date sometimes, like 1-2 times a year
+- return "2023.10.10-atLeast"; // update date sometimes, like 1-2 times a year
++ return "2023-10-25-5"; // update date sometimes, like 1-2 times a year
#endif
}
include $(TOPDIR)/rules.mk
PKG_NAME:=iperf
-PKG_VERSION:=3.15
+PKG_VERSION:=3.16
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.es.net/pub/iperf
-PKG_HASH:=bdb77c11f72bce90214883159577fa24412013e62b2083cf5f54391d79b1d8ff
+PKG_HASH:=cc740c6bbea104398cc3e466befc515a25896ec85e44a662d5f4a767b9cf713e
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=BSD-3-Clause
$(call Package/iperf3/default)
TITLE+= with iperf_auth support
VARIANT:=ssl
- DEPENDS:=+libopenssl
+ DEPENDS:=+libopenssl +libatomic
+ CONFLICTS:=iperf3
endef
define Package/libiperf3
CATEGORY:=Libraries
TITLE:=Internet Protocol bandwidth measuring library
URL:=https://github.com/esnet/iperf
+ DEPENDS+=+libatomic
endef
TARGET_CFLAGS += -D_GNU_SOURCE
+TARGET_LDFLAGS += -latomic
ifeq ($(BUILD_VARIANT),ssl)
CONFIGURE_ARGS += --with-openssl="$(STAGING_DIR)/usr" --disable-shared
PKG_NAME:=isc-dhcp
UPSTREAM_NAME:=dhcp
PKG_VERSION:=4.4.3-P1
-PKG_RELEASE:=6
+PKG_RELEASE:=7
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
USE_PROCD=1
PROG=/usr/sbin/dhcpd
+WS=$'[\t ]'
TTL=3600
PREFIX="update add"
echo $(( number * multiplier ))
}
+explode() {
+ echo "${1//\./ }"
+}
+
trim() {
- local arg="$1"
+ local str="$1" prev
- echo "$arg" | sed -e 's/^ *//' -e 's/ *$//'
+ while true; do
+ prev="$str"
+ str="${str%%$WS}"
+ [ "$str" = "$prev" ] && break
+ done
+ while true; do
+ prev="$str"
+ str="${str##$WS}"
+ [ "$str" = "$prev" ] && break
+ done
+ echo "$str"
}
rfc1918_prefix() {
- local octets="$(echo "${1%%/*}" | cut -d. -f1)"
+ local subnet="${1%/*}"
+ set -- $(explode "$subnet")
- [ "$octets" = "10" ] && { echo "$octets"; return; }
-
- octets="$(echo "${1%%/*}" | cut -d. -f1-2)"
-
- case "$octets" in
+ case "$1.$2" in
+ 10.*)
+ echo "$1" ;;
172.1[6789]|172.2[0-9]|172.3[01]|192.168)
- echo "$octets"
- ;;
+ echo "$1.$2" ;;
esac
}
echo -e "$PREFIX" "$lhs $family $type $@\nsend" >> $dyn_file
}
-explode() {
- local arg="$1"
-
- echo "$arg" | sed -e 's/\./, /g'
-}
-
rev_str() {
local str="$1" delim="$2"
local frag result="" IFS="$delim"
}
append_routes() {
- local tuple tuple="$(trim "$1")"
- local network prefix router save octets compacted
+ local tuple="$(trim "$1")"
+ local network prefix router subnet compacted octet
+
+ subnet="${tuple%%$WS*}"
+
+ network="${subnet%/[0-9]*}"
- save="${tuple% *}"
- router="$(trim "${tuple#${save} }")"
+ prefix="${subnet#*/}"
- network="$(trim "${save%/[0-9]*}")"
+ set -- $(explode "$network")
- prefix="$(trim "${save##${network}/}")"
+ case $((($prefix + 7) / 8)) in
+ 0)
+ compacted= ;;
+ 1)
+ compacted="$1" ;;
+ 2)
+ compacted="$1 $2" ;;
+ 3)
+ compacted="$1 $2 $3" ;;
+ 4)
+ compacted="$1 $2 $3 $4" ;;
+ esac
- octets=$((($prefix + 7) / 8))
- compacted="$(echo "$network" | cut -d. -f1-$octets)"
+ router="${tuple#${subnet}$WS}"
- routes="$routes${routes:+, }$(explode "$prefix${compacted:+.$compacted}.$router")"
+ for octet in $prefix $compacted $(explode "$router"); do
+ append routes "$octet" ", "
+ done
}
append_dhcp_options() {
value="\"$value\""
;;
esac
- formatted="$formatted${formatted:+, }$value"
+ append formatted "$value" ", "
done
echo " option $tag $formatted;"
}
config_get leasetime "$cfg" "leasetime"
if [ -n "$leasetime" ] ; then
leasetime="$(time2seconds "$leasetime")"
- [ "$?" -ne 0 ] && return 1
+ [ $? -ne 0 ] && return 1
fi
config_get hostid "$cfg" "hostid"
config_get force_send "$cfg" "force_send"
extra_options=
- local _IFS="$IFS" IFS=','
- for option in $force_send; do
+ for option in ${force_send//,/ }; do
case "$option" in
hostname)
- extra_options="$extra_options${extra_options:+,}0c" ;;
+ append extra_options "0c" "," ;;
domain-name)
- extra_options="$extra_options${extra_options:+,}0f" ;;
+ append extra_options "0f" "," ;;
renewal-time)
- extra_options="$extra_options${extra_options:+,}3a" ;;
+ append extra_options "3a" "," ;;
rebinding-time)
- extra_options="$extra_options${extra_options:+,}3b" ;;
+ append extra_options "3b" "," ;;
fqdn)
- extra_options="$extra_options${extra_options:+,}51" ;;
+ append extra_options "51" "," ;;
routes)
- extra_options="$extra_options${extra_options:+,}79" ;;
+ append extra_options "79" "," ;;
*)
echo "unknown option: $option" >&2 ;;
esac
done
- IFS="$_IFS"
macn=0
for mac in $macs; do
echo " hardware ethernet $mac;"
echo " fixed-address $ip;"
echo " option host-name \"$name\";"
- if [ "$broadcast" -eq 1 ] ; then
+ if [ $broadcast -eq 1 ] ; then
echo " always-broadcast true;"
fi
if [ -n "$leasetime" ] ; then
echo " range $START $END;"
fi
echo " option subnet-mask $netmask;"
- if [ "$BROADCAST" != "0.0.0.0" ] ; then
+ # check for 0.0.0.0 until all active releases of ipcalc.sh omit it
+ # for small networks:
+ if [ -n "$BROADCAST" ] && [ "$BROADCAST" != "0.0.0.0" ] ; then
echo " option broadcast-address $BROADCAST;"
fi
- if [ "$dynamicdhcp" -eq 0 ] ; then
- if [ "$authoritative" -eq 1 ] ; then
+ if [ $dynamicdhcp -eq 0 ] ; then
+ if [ $authoritative -eq 1 ] ; then
echo " deny unknown-clients;"
else
echo " ignore unknown-clients;"
echo " default-lease-time $leasetime;"
echo " max-lease-time $leasetime;"
fi
- if [ "$defaultroute" -eq 1 ] ; then
+ if [ $defaultroute -eq 1 ] ; then
echo " option routers $gateway;"
fi
echo " option domain-name-servers $DNS;"
local IP NETMASK BROADCAST NETWORK PREFIX DNS START END
config_get_bool ignore "$cfg" "ignore" 0
- [ "$ignore" = "0" ] || return 0
+ [ $ignore -eq 1 ] && return 0
config_get net "$cfg" "interface"
[ -n "$net" ] || return 0
network_get_device ifname "$net" || return 0
network_get_protocol proto "$net" || return 0
- [ static = "$proto" ] || return 0
+ [ "$proto" != "static" ] && return 0
local octets="$(rfc1918_prefix "$subnet")"
- [ -n "$octets" ] && rfc1918_nets="$rfc1918_nets${rfc1918_nets:+ }$octets"
+ [ -n "$octets" ] && append rfc1918_nets "$octets"
- [ $synthesize -eq 0 ] && return
+ [ $synthesize -eq 0 ] && return 0
config_get_bool dynamicdhcp "$cfg" "dynamicdhcp" 1
config_get_bool defaultroute "$cfg" "default_route" 1
- dhcp_ifs="$dhcp_ifs $ifname"
+ append dhcp_ifs "$ifname"
- eval "$(ipcalc.sh $subnet $start $limit)"
+ if ! ipcalc "$subnet" "$start" "$limit"; then
+ echo "invalid range params: $subnet start: $start limit $limit" >&2
+ return 1
+ fi
config_get netmask "$cfg" "netmask" "$NETMASK"
config_get leasetime "$cfg" "leasetime"
if [ -n "$leasetime" ] ; then
leasetime="$(time2seconds "$leasetime")"
- [ "$?" -ne 0 ] && return 1
+ [ $? -ne 0 ] && return 1
fi
if network_get_dnsserver dnsserver "$net" ; then
[ $boot_unknown_clients -eq 0 ] && echo "boot-unknown-clients false;"
default_lease_time="$(time2seconds "$default_lease_time")"
- [ "$?" -ne 0 ] && return 1
+ [ $? -ne 0 ] && return 1
max_lease_time="$(time2seconds "$max_lease_time")"
- [ "$?" -ne 0 ] && return 1
+ [ $? -ne 0 ] && return 1
if [ $dynamicdns -eq 1 ]; then
create_empty_zone "$domain"
local rfc1918_nets=""
# alas we have to make 2 passes...
+ dhcp_ifs=
config_foreach dhcpd_add dhcp 0
rfc1918_nets="$(echo "$rfc1918_nets" | tr ' ' $'\n' | sort | uniq | tr $'\n' ' ')"
rfc1918_nets=
+ dhcp_ifs=
config_foreach dhcpd_add dhcp 1 >> $config_file
static_hosts >> $config_file
PKG_NAME:=keepalived
PKG_VERSION:=2.2.8
-PKG_RELEASE:=3
+PKG_RELEASE:=5
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.keepalived.org/software
printf '%benable_script_security\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
printf '%bprocess_names\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
+ printf '%bstartup_script "/bin/busybox env -i ACTION=startup /sbin/hotplug-call keepalived"\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
+ printf '%bstartup_script_timeout 10\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
+ printf '%bshutdown_script "/bin/busybox env -i ACTION=shutdown /sbin/hotplug-call keepalived"\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
+ printf '%bshutdown_script_timeout 10\n' "${INDENT_1}" >> "$KEEPALIVED_CONF"
+
config_get notification_email "$1" notification_email
print_list_indent notification_email
garp_master_repeat garp_master_refresh_repeat \
no_val_vmac_xmit_base no_val_native_ipv6 no_val_accept \
no_val_dont_track_primary no_val_smtp_alert no_val_nopreempt \
- no_val_use_vmac
+ no_val_use_vmac no_val_no_accept
print_notify "INSTANCE" "$name" "$INDENT_1" notify_backup notify_master \
notify_fault notify_stop
include $(TOPDIR)/rules.mk
PKG_NAME:=knot
-PKG_VERSION:=3.3.1
+PKG_VERSION:=3.3.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://secure.nic.cz/files/knot-dns/
-PKG_HASH:=f3f4b1d49ec9b81113b14a38354b823bd4a470356ed7e8e555595b6fd1ac80c9
+PKG_HASH:=0d65d4b59f5df69b78c6295ade0a2ea7931831de7ef5eeee3e00f8a20af679e4
PKG_MAINTAINER:=Daniel Salzman <daniel.salzman@nic.cz>
PKG_LICENSE:=GPL-3.0 LGPL-2.0 0BSD BSD-3-Clause OLDAP-2.8
--- /dev/null
+--- a/src/libdnssec/key/key.c
++++ b/src/libdnssec/key/key.c
+@@ -146,10 +146,14 @@ dnssec_key_t *dnssec_key_dup(const dnsse
+
+ gnutls_privkey_type_t type = gnutls_privkey_get_type(key->private_key);
+ if (type == GNUTLS_PRIVKEY_PKCS11) {
++#ifdef ENABLE_PKCS11
+ gnutls_pkcs11_privkey_t tmp;
+ gnutls_privkey_export_pkcs11(key->private_key, &tmp);
+ gnutls_privkey_import_pkcs11(dup->private_key, tmp,
+ GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
++#else
++ assert(0);
++#endif
+ } else {
+ assert(type == GNUTLS_PRIVKEY_X509);
+ gnutls_x509_privkey_t tmp;
PKG_NAME:=librespeed-go
PKG_VERSION:=1.1.5
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/librespeed/speedtest-go/tar.gz/v$(PKG_VERSION)?
local cfg="$1"
local isdir="${2:-0}"
local rw="${3:-0}"
+ local reload="${4:-0}"
local value
config_get value "config" "$cfg"
else
procd_add_jail_mount "$value"
fi
+
+ [ "$reload" = "0" ] || procd_append_param file "$value"
}
start_service() {
mount_jail_file "assets_path" "1"
mount_jail_file "database_file" "0" "1"
- mount_jail_file "tls_cert_file"
- mount_jail_file "tls_key_file"
+ mount_jail_file "tls_cert_file" "0" "0" "1"
+ mount_jail_file "tls_key_file" "0" "0" "1"
procd_close_instance
}
PKG_NAME:=libreswan
PKG_VERSION:=4.12
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://download.libreswan.org/
include $(INCLUDE_DIR)/package.mk
-define Package/libreswan/Default
- TITLE:=Libreswan
- URL:=https://libreswan.org/
-endef
-
-define Package/libreswan/Default/description
- Libreswan is a free software implementation of the most widely supported and
- standardized VPN protocol based on ("IPsec") and the Internet Key Exchange
- ("IKE"). These standards are produced and maintained by the Internet
- Engineering Task Force ("IETF").
-endef
-
-define Package/libreswan
-$(call Package/libreswan/Default)
+define Package/libreswan/default
SUBMENU:=VPN
SECTION:=net
CATEGORY:=Network
- DEPENDS:= +IPV6:kmod-ip6-vti +IPV6:kmod-ipsec6 +ip-full +iptables-mod-ipsec \
- +kmod-crypto-aead +kmod-crypto-authenc +kmod-crypto-gcm \
- +kmod-crypto-hash +kmod-crypto-rng +kmod-ip-vti +kmod-ipsec \
- +kmod-ipsec4 +kmod-ipt-ipsec +kmod-xfrm-interface +libevent2 +libevent2-pthreads \
- +libldns +librt +libunbound +nss-utils +nspr +libcap-ng
+ TITLE:=Libreswan
+ URL:=https://libreswan.org/
PROVIDES:=openswan
CONFLICTS:=strongswan
- TITLE+= IPsec Server
+endef
+
+define Package/libreswan
+ $(Package/libreswan/default)
+ DEPENDS:= \
+ +kmod-ip-vti +IPV6:kmod-ip6-vti \
+ +kmod-ipsec +kmod-ipsec4 +IPV6:kmod-ipsec6 \
+ +ip-full +kmod-xfrm-interface \
+ +libevent2 +libevent2-pthreads \
+ +libldns +librt +libunbound +nss-utils +nspr +libcap-ng \
+ +kmod-crypto-acompress \
+ +kmod-crypto-aead \
+ +kmod-crypto-authenc \
+ +kmod-crypto-arc4 \
+ +kmod-crypto-cbc \
+ +kmod-crypto-ccm \
+ +kmod-crypto-chacha20poly1305 \
+ +kmod-crypto-cmac \
+ +kmod-crypto-ctr \
+ +kmod-crypto-cts \
+ +kmod-crypto-des \
+ +kmod-crypto-ecb \
+ +kmod-crypto-ecdh \
+ +kmod-crypto-gcm \
+ +kmod-crypto-ghash \
+ +kmod-crypto-hash \
+ +kmod-crypto-hmac \
+ +kmod-crypto-md4 \
+ +kmod-crypto-md5 \
+ +kmod-crypto-null \
+ +kmod-crypto-pcbc \
+ +kmod-crypto-sha1 \
+ +kmod-crypto-sha256 \
+ +kmod-crypto-sha512 \
+ +kmod-crypto-xcbc \
+ +kmod-crypto-rng
endef
define Package/libreswan/description
-$(call Package/libreswan/Default/description)
- Libreswan is a free software implementation of the most widely supported and
- standardized VPN protocol based on ("IPsec") and the Internet Key Exchange
- ("IKE"). These standards are produced and maintained by the Internet
- Engineering Task Force ("IETF").
+ Libreswan is a free software implementation of the most widely supported and
+ standardized VPN protocol based on ("IPsec") and the Internet Key Exchange
+ ("IKE"). These standards are produced and maintained by the Internet
+ Engineering Task Force ("IETF").
endef
define Package/libreswan/conffiles
/etc/ipsec.d
-/etc/ipsec.conf
-/etc/ipsec.secrets
+/etc/config/libreswan
+/etc/ipsec.user
endef
+
TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
MAKE_FLAGS+= \
define Package/libreswan/install
$(INSTALL_DIR) \
- $(1)/etc/init.d \
$(1)/etc/ipsec.d/policies \
$(1)/usr/libexec/ipsec \
- $(1)/usr/sbin
+ $(1)/usr/sbin \
+ $(1)/etc/config \
+ $(1)/etc/init.d \
+ $(1)/etc/hotplug.d/libreswan \
+ $(1)/etc/hotplug.d/iface \
+ $(1)/usr/libexec/rpcd \
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ipsec \
$(1)/usr/sbin/ipsec
- $(INSTALL_BIN) ./files/ipsec.init $(1)/etc/init.d/ipsec
- $(INSTALL_DATA) ./files/ipsec.conf $(1)/etc/ipsec.conf
- $(INSTALL_DATA) ./files/ipsec.secrets $(1)/etc/ipsec.secrets
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/ipsec.d/policies/* \
$(1)/etc/ipsec.d/policies/
$(CP) $(PKG_INSTALL_DIR)/usr/libexec/ipsec/* \
$(1)/usr/libexec/ipsec/
+
+ $(INSTALL_BIN) ./files/usr/libexec/ipsec/_updown.xfrm $(1)/usr/libexec/ipsec/_updown.xfrm
+ $(INSTALL_BIN) ./files/etc/init.d/ipsec $(1)/etc/init.d/ipsec
+ $(INSTALL_BIN) ./files/usr/libexec/rpcd/libreswan $(1)/usr/libexec/rpcd/libreswan
+ $(INSTALL_DATA) ./files/etc/ipsec.conf $(1)/etc/ipsec.conf
+ $(INSTALL_DATA) ./files/etc/ipsec.secrets $(1)/etc/ipsec.secrets
+ $(INSTALL_DATA) ./files/etc/config/libreswan $(1)/etc/config/libreswan
+ $(INSTALL_DATA) ./files/etc/hotplug.d/libreswan/01-user $(1)/etc/hotplug.d/libreswan/01-user
+ $(INSTALL_DATA) ./files/etc/hotplug.d/libreswan/02-vti $(1)/etc/hotplug.d/libreswan/02-vti
+ $(INSTALL_DATA) ./files/etc/hotplug.d/iface/89-libreswan $(1)/etc/hotplug.d/iface/89-libreswan
+endef
+
+define Package/libreswan-nftables
+ $(Package/libreswan/default)
+ TITLE+= nftables plugin)
+ DEPENDS+=firewall4 +libreswan +kmod-nft-xfrm +nftables \
+ +kmod-nfnetlink-log
+endef
+
+define Package/libreswan-nftables/description
+ Provides Libreswan nftables plugin for adding firewall rules
+endef
+
+define Package/libreswan-nftables/install
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/libreswan \
+ $(1)/usr/share/nftables.d/ruleset-post
+
+ $(CP) ./files/usr/share/nftables.d/* $(1)/usr/share/nftables.d
+ $(CP) ./files/etc/hotplug.d/libreswan/62-nftables $(1)/etc/hotplug.d/libreswan/62-nftables
+ $(LN) /tmp/libreswan/firewall.d/libreswan.rules $(1)/usr/share/nftables.d/ruleset-post/10_libreswan.nft
+endef
+
+define Package/libreswan-iptables
+ $(Package/libreswan/default)
+ TITLE+= iptables plugin)
+ DEPENDS+=firewall +libreswan +iptables-mod-ipsec +kmod-ipt-ipsec \
+ +iptables-zz-legacy +IPV6:ip6tables-zz-legacy \
+ +kmod-ipt-nflog +iptables-mod-nflog
+endef
+
+define Package/libreswan-iptables/description
+ Provides Libreswan iptables plugin for adding firewall rules
+endef
+
+define Package/libreswan-iptables/install
+ $(INSTALL_DIR) $(1)/etc \
+ $(1)/etc/uci-defaults \
+ $(1)/etc/hotplug.d/libreswan
+
+ $(CP) ./files/etc/hotplug.d/libreswan/61-iptables $(1)/etc/hotplug.d/libreswan/61-iptables
+ $(CP) ./files/etc/uci-defaults/091-libreswan $(1)/etc/uci-defaults/091-libreswan
+ $(INSTALL_BIN) ./files/etc/libreswan_firewall.sh $(1)/etc/libreswan_firewall.sh
+endef
+
+define Package/libreswan-iptables/postinst
+#!/bin/sh
+[ -n "$$IPKG_INSTROOT" ] || {
+ /etc/init.d/firewall reload
+}
endef
$(eval $(call BuildPackage,libreswan))
+$(eval $(call BuildPackage,libreswan-nftables))
+$(eval $(call BuildPackage,libreswan-iptables))
--- /dev/null
+config libreswan 'globals'
+ option debug '0' # set debug mode none/all
+ list virtual_private '10.0.0.0/8'
+ list virtual_private '192.168.0.0/16'
+ list virtual_private '172.16.0.0/12'
+ list virtual_private '25.0.0.0/8'
+ list virtual_private '100.64.0.0/10'
+ list virtual_private '!100.64.0.0/24' # the address ranges that may live behind a NAT router through which a client connects
+ # option listen '192.168.2.100' # listening address, if set listen_interface would not be used
+ # option listen_interface 'wan' # listening interface
+ # option uniqueids 'yes' # yes/no
+
+# config crypto_proposal 'p1'
+# list encryption_algorithm '3des' # possible values: 3des, aes, aes_ctr, aes_cbc, aes128, aes192, aes256, camellia_cbc
+# list hash_algorithm 'md5' # possible values: md5, sha1, sha256, sha384, sha512
+# list dh_group 'modp1536' # possible values: modp1536, modp2048, modp3072, modp4096, modp6144, modp8192, dh19, dh20, dh21, dh22, dh31
+
+# config tunnel 'vti2_1_5'
+# option left '192.168.1.1'
+# option left_interface 'wan' # interface ipaddr to be used as left
+# option leftid '@left' # local id
+# option right '192.168.2.201' # remote endpoint public ip
+# option rightid '@62dd3e3f82339b002405245b' # rightid
+# option auto 'start' # what operation, should be done automatically at IPsec startup
+# option authby 'secret' # how the two security gateways should authenticate each other
+# option psk 'AyG9RlTtQJIUxgxG' # preshare key
+# option ikev2 '1' # ike version
+# option ikelifetime '8h'
+# option rekey '1'
+# option rekeymargin '9m'
+# option dpdaction 'restart'
+# option dpddelay '30'
+# option dpdtimeout '150'
+# option interface 'vti2_1_5' # only for route based tunnels
+# list leftsubnets '0.0.0.0/0'
+# list rightsubnets '0.0.0.0/0'
+# option phase2 'esp' # phase2 protocol
+# list ike 'p1' # list of crypto_proposal (phase1 proposals)
+# list phase2ag 'p1' # list of crypto_proposal (phase2 proposals')
+# option nflog '0' # enable nflog
+# option update_peeraddr '1' # auto update vti interface ppeeradd in /etc/config/network
--- /dev/null
+#!/bin/sh
+
+[ "$ACTION" = ifup -o "$ACTION" = ifupdate ] || exit 0
+[ "$ACTION" = ifupdate -a -z "$IFUPDATE_ADDRESSES" -a -z "$IFUPDATE_DATA" ] && exit 0
+
+/etc/init.d/ipsec running || exit 0
+uci show libreswan | grep -i "='$INTERFACE'$" || exit 0
+
+logger -t libreswan "Restart libreswan due to $ACTION of $INTERFACE ($DEVICE)"
+
+/etc/init.d/ipsec restart
--- /dev/null
+#!/bin/sh
+
+# Things that this script gets (from ipsec_pluto(8) man page)
+#
+# PLUTO_VERB
+# specifies the name of the operation to be performed
+# (prepare-host, prepare-client, up-host, up-client,
+# down-host, or down-client). If the address family
+# for security gateway to security gateway
+# communications is IPv6, then a suffix of -v6 is added
+# to the verb.
+#
+# PLUTO_CONNECTION
+# is the name of the connection for which we are
+# routing.
+#
+# PLUTO_CONNECTION_TYPE
+# is type of the connection, "tunnel" or "transport".
+#
+# PLUTO_CONN_POLICY
+# the policy of the connection, as in:
+# RSASIG+ENCRYPT+TUNNEL+PFS+DONTREKEY+OPPORTUNISTIC
+# +failureDROP+lKOD+rKOD
+#
+# CAT=YES|
+# if client address translation inside IPsec stack is enabled
+#
+# PLUTO_NEXT_HOP
+# is the next hop to which packets bound for the peer
+# must be sent.
+#
+# PLUTO_INTERFACE
+# is the name of the real interface used by encrypted traffic and IKE traffic
+#
+# PLUTO_ME
+# is the IP address of our host.
+#
+# PLUTO_MY_ID
+# is our ID.
+#
+# PLUTO_METRIC
+# is the metric to set for the route
+#
+# PLUTO_MTU
+# is the mtu to set for the route
+#
+# PLUTO_ADD_TIME
+# Time the IPsec SA was added to the kernel
+#
+# PLUTO_MOBIKE_EVENT
+# wether the connection is underdoing MOBIKE migration
+#
+# PLUTO_MY_CLIENT
+# is the IP address / count of our client subnet. If
+# the client is just the host, this will be the
+# host's own IP address / mask (where max is 32 for
+# IPv4 and 128 for IPv6).
+#
+# PLUTO_MY_CLIENT_NET
+# is the IP address of our client net. If the client
+# is just the host, this will be the host's own IP
+# address.
+#
+# PLUTO_MY_CLIENT_MASK
+# is the mask for our client net. If the client is
+# just the host, this will be 255.255.255.255.
+#
+# PLUTO_MY_SOURCEIP
+# if non-empty, then the source address for the route will be
+# set to this IP address.
+#
+# PLUTO_MY_PROTOCOL
+# is the protocol for this connection. Useful for
+# firewalling.
+#
+# PLUTO_MY_PORT
+# is the port. Useful for firewalling.
+#
+# PLUTO_PEER
+# is the IP address of our peer.
+#
+# PLUTO_PEER_ID
+# is the ID of our peer.
+#
+# PLUTO_PEER_CLIENT
+# is the IP address / count of the peer's client subnet.
+# If the client is just the peer, this will be
+# the peer's own IP address / mask (where max is 32
+# for IPv4 and 128 for IPv6).
+#
+# PLUTO_PEER_CLIENT_NET
+# is the IP address of the peer's client net. If the
+# client is just the peer, this will be the peer's
+# own IP address.
+#
+# PLUTO_PEER_CLIENT_MASK
+# is the mask for the peer's client net. If the
+# client is just the peer, this will be
+# 255.255.255.255.
+#
+# PLUTO_PEER_PROTOCOL
+# is the protocol set for remote end with port
+# selector.
+#
+# PLUTO_PEER_PORT
+# is the peer's port. Useful for firewalling.
+#
+# PLUTO_PEER_CA
+# is the DN of the peer's CA that signed its certificate
+#
+# PLUTO_CFG_CLIENT=0|1
+# is MODECFG or IKEv2 Config client.
+#
+# PLUTO_CFG_SERVER=0|1
+# is MODECFG or IKEv2 Config server.
+#
+# PLUTO_PEER_DNS_INFO
+# The peer's supplied DNS information (IKEv1 and IKEv2)
+#
+# PLUTO_PEER_DOMAIN_INFO
+# The peer's supplied domain list for local resolving (IKEv2 only)
+#
+# PLUTO_PEER_BANNER
+# is the peer's provided banner
+#
+# PLUTO_NM_CONFIGURED=0|1
+# is NetworkManager used for resolv.conf update
+#
+# PLUTO_CONN_ADDRFAMILY
+# is the family type, "ipv4" or "ipv6"
+#
+# PLUTO_CONN_KIND
+# is the "kind" of connection (CK_PERMANENT, CK_INSTANCE, etc)
+#
+# PLUTO_STACK
+# is the local IPsec kernel stack used, eg XFRM, BSDKAME, NOSTACK
+#
+# PLUTO_IS_PEER_CISCO=0|1
+# remote server type is cisco. Add support for cisco extensions
+# when used with xauth.
+#
+# PLUTO_SA_REQID
+# When using KAME or XFRM, the IPsec SA reqid base value.
+# ESP/AH out is base, ESP/AH in = base + 1
+# IPCOMP is base + 2 plus for inbound + 1
+#
+# PLUTO_XFRMI_FWMARK
+# use outgoing mark
+#
+# PLUTO_SA_TYPE
+# The type of IPsec SA (ESP or AH)
+#
+# PLUTO_USERNAME
+# The username (XAUTH or GSSAPI) that was authenticated (if any)
+# for this SA
+#
+# PLUTO_VIRT_INTERFACE
+# is the name of ipsec interface used by clear traffic in/out
+#
+# INTERFACE_IP
+# The IP to configure / expect on the interface? Currently is never set
+#
+# PLUTO_XFRM_ROUTE
+# if an XFRM (ipsec-device) has been specified, value will be "yes"
+#
+# XAUTH_FAILED
+# If xauthfail=soft this will be set to 1 if XAUTH authentication
+# failed. If xauthfail=hard, the updown scripts never run.
+#
+# CONNMARK
+# If mark= is set on the connection, this variable will be
+# set with the value. It can be used for iptables or VTI.
+#
+# CONNMARK_IN
+# the incoming mark to use
+#
+# CONNMARK_OUT
+# the outgoing mark to use
+#
+# VTI_IFACE=iface
+# Name of VTI interface to create
+#
+# VTI_ROUTING=yes|no
+# Whether or not to perform ip rule and ip route commands
+# covering the IPsec SA address ranges to route those packets
+# into the VTI_IFACE interface. This should be enabled unless
+# the IPsec SA covers 0.0.0.0/0 <-> 0.0.0.0/0
+#
+# VTI_SHARED=yes|no
+# Whether or not more conns (or instances) share a VTI device.
+# If not shared, the VTI device is deleted when tunnel goes down.
+#
+# VTI_IP
+# The IP to configure on the VTI device
+#
+# SPI_IN / SPI_OUT
+# The inbound and outbound SPI's of the connection.
+#
+# PLUTO_INBYTES
+# total bytes received
+#
+# PLUTO_OUTBYTES
+# total bytes sent
+#
+# NFLOG
+# is the nflog group to use
+#
+
+case "${PLUTO_VERB}" in
+ prepare-host|prepare-host-v6) ;;
+ prepare-client|prepare-client-v6) ;;
+ route-host|route-host-v6) ;;
+ unroute-host|unroute-host-v6) ;;
+ route-client|route-client-v6) ;;
+ unroute-client|unroute-client-v6) ;;
+ up-host|up-host-v6) ;;
+ down-host|down-host-v6) ;;
+ up-client|up-client-v6) ;;
+ down-client|down-client-v6) ;;
+esac
--- /dev/null
+#!/bin/sh
+
+[ -e "/etc/ipsec.user" ] && {
+ . /etc/ipsec.user
+}
+
+exit 0
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+
+[ "${PLUTO_VERB}" != "route-client" ] && [ "${PLUTO_VERB}" != "up-client" ] && exit 0
+
+CONNECTION=${PLUTO_CONNECTION%/*}
+[ -z "$CONNECTION" ] && exit 0
+
+update_peeraddr=$(uci_get libreswan $CONNECTION update_peeraddr)
+[ "$update_peeraddr" != "1" ] && exit 0
+
+interface=$(uci_get libreswan $CONNECTION interface)
+[ -z "$interface" ] && exit 0
+
+proto=$(uci_get network "$interface" proto)
+[ "$proto" != "vti" ] && exit 0
+
+peeraddr=$(uci_get network "$interface" peeraddr)
+[ "$peeraddr" == "$PLUTO_PEER" ] && exit 0
+
+uci_set network "$interface" peeraddr "$PLUTO_PEER"
+uci_commit network
+ifup "$interface"
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+
+FW4="$(command -v fw4)"
+[ -n "$FW4" ] && exit 0
+
+CONNECTION="${PLUTO_CONNECTION//\//_}"
+[ -z "$CONNECTION" ] && exit 0
+
+IPT_LEGACY="$(command -v iptables-legacy)"
+IPT="$(command -v iptables)"
+BIN="${IPT_LEGACY:-$IPT}"
+[ -z "$BIN" ] && exit 0
+
+LIBRESWAN_INPUT="libreswan_input"
+LIBRESWAN_FORWARD="libreswan_forward"
+LIBRESWAN_OUTPUT="libreswan_output"
+LIBRESWAN_NFLOG_INPUT="libreswan_nflog_input"
+LIBRESWAN_NFLOG_OUTPUT="libreswan_nflog_output"
+LIBRESWAN_POSTROUTING="libreswan_postrouting"
+
+FW_DIR="/tmp/libreswan/firewall.d"
+LIBRESWAN_RULES_FILE="$FW_DIR/libreswan.rules"
+RULES_DIR="$FW_DIR/rules"
+
+IPV4_RULES_FILE="$RULES_DIR/${CONNECTION}-ipv4.rules"
+IPV6_RULES_FILE="$RULES_DIR/${CONNECTION}-ipv6.rules"
+
+reload_firewall() {
+ [ ! -d "$RULES_DIR" ] && return 0
+
+ cat $RULES_DIR/*.rules > "$LIBRESWAN_RULES_FILE" 2>/dev/null
+ /etc/init.d/firewall reload
+}
+
+up_rules() {
+ [ -z "$PLUTO_PEER_CLIENT" ] && return 0
+
+ [ ! -d "$RULES_DIR" ] && mkdir -p "$RULES_DIR"
+ [ "$PLUTO_PEER_CLIENT" = "0.0.0.0/0" ] && [ "$PLUTO_MY_CLIENT" = "0.0.0.0/0" ] && return 0
+
+ cat << EOF > $IPV4_RULES_FILE
+$BIN -t filter -A $LIBRESWAN_INPUT -m policy --dir in --pol ipsec -s $PLUTO_PEER_CLIENT -d $PLUTO_MY_CLIENT -m comment --comment "$PLUTO_CONNECTION" -j ACCEPT
+$BIN -t filter -A $LIBRESWAN_FORWARD -s $PLUTO_PEER_CLIENT -d $PLUTO_MY_CLIENT -m comment --comment "$PLUTO_CONNECTION" -j ACCEPT
+$BIN -t filter -A $LIBRESWAN_OUTPUT -m policy --dir out --pol ipsec -s $PLUTO_MY_CLIENT -d $PLUTO_PEER_CLIENT -m comment --comment "$PLUTO_CONNECTION" -j ACCEPT
+$BIN -t nat -A $LIBRESWAN_POSTROUTING -m policy --dir out --pol ipsec -s $PLUTO_MY_CLIENT -d $PLUTO_PEER_CLIENT -m comment --comment "$PLUTO_CONNECTION" -j ACCEPT
+EOF
+ if [ -n "$NFLOG" ]; then
+ cat << EOF > $IPV4_RULES_FILE
+$BIN -t filter -A $LIBRESWAN_NFLOG_INPUT -m policy --dir in --pol ipsec -s $PLUTO_PEER_CLIENT -d $PLUTO_MY_CLIENT -j NFLOG --nflog-group $NFLOG --nflog-prefix $PLUTO_CONNECTION
+$BIN -t filter -A $LIBRESWAN_NFLOG_OUTPUT -m policy --dir out --pol ipsec -s $PLUTO_MY_CLIENT -d $PLUTO_PEER_CLIENT -j NFLOG --nflog-group $NFLOG --nflog-prefix $PLUTO_CONNECTION
+EOF
+
+ fi
+
+ reload_firewall
+
+ return 0
+}
+
+down_rules() {
+ if [ -f "$IPV4_RULES_FILE" ]; then
+ rm -rf "$IPV4_RULES_FILE"
+ reload_firewall
+ fi
+
+ return 0
+}
+
+case "${PLUTO_VERB}" in
+ up-host|up-client) up_rules ;;
+ down-host|down-client) down_rules ;;
+ up-host-v6|down-host-v6) ;;
+ up-client|down-client-v6) ;;
+esac
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+
+FW4="$(command -v fw4)"
+[ -z "$FW4" ] && exit 0
+
+CONNECTION="${PLUTO_CONNECTION//\//_}"
+[ -z "$CONNECTION" ] && exit 0
+
+FW_DIR="/tmp/libreswan/firewall.d"
+LIBRESWAN_RULES_FILE="$FW_DIR/libreswan.rules"
+RULES_DIR="$FW_DIR/rules"
+
+IPV4_RULES_FILE="$RULES_DIR/${CONNECTION}-ipv4.rules"
+IPV6_RULES_FILE="$RULES_DIR/${CONNECTION}-ipv6.rules"
+NFLOG_ALL_RULES_FILE="$RULES_DIR/nflog_all.rules"
+
+reload_firewall() {
+ [ ! -d "$RULES_DIR" ] && return 0
+
+ cat $RULES_DIR/*.rules > "$LIBRESWAN_RULES_FILE" 2>/dev/null
+ /etc/init.d/firewall reload
+}
+
+up_rules() {
+ [ -z "$PLUTO_PEER_CLIENT" ] && return 0
+
+ [ ! -d "$RULES_DIR" ] && mkdir -p "$RULES_DIR"
+
+ eval $(ipsec addconn --configsetup)
+
+ if [ -n "$nflog_all" ]; then
+ unset NFLOG
+ if [ ! -f "$NFLOG_ALL_RULES_FILE" ]; then
+ cat << EOF > "$NFLOG_ALL_RULES_FILE"
+table inet fw4 {
+ chain libreswan_nflog_input {
+ meta ipsec exists log prefix "all-ipsec" group ${nflog_all}
+ }
+ chain libreswan_nflog_output {
+ rt ipsec exists log prefix "all-ipsec" group ${nflog_all}
+ }
+}
+EOF
+ fi
+ else
+ [ -f "$NFLOG_ALL_RULES_FILE" ] && rm -f "$NFLOG_ALL_RULES_FILE"
+ fi
+
+ cat << EOF > $IPV4_RULES_FILE
+table inet fw4 {
+ chain libreswan_input {
+ meta ipsec exists ipsec in ip saddr $PLUTO_PEER_CLIENT ip daddr $PLUTO_MY_CLIENT ${NFLOG:+log prefix \"${PLUTO_CONNECTION}\" group ${NFLOG}} accept comment "$PLUTO_CONNECTION"
+ }
+ chain libreswan_forward {
+ meta ipsec exists ipsec in ip saddr $PLUTO_PEER_CLIENT ip daddr $PLUTO_MY_CLIENT accept comment "$PLUTO_CONNECTION"
+ }
+ chain libreswan_output {
+ ipsec out ip saddr $PLUTO_MY_CLIENT ip daddr $PLUTO_PEER_CLIENT ${NFLOG:+log prefix \"${PLUTO_CONNECTION}\" group ${NFLOG}} accept comment "$PLUTO_CONNECTION"
+ }
+ chain libreswan_srcnat {
+ ip saddr $PLUTO_MY_CLIENT ip daddr $PLUTO_PEER_CLIENT accept comment "$PLUTO_CONNECTION"
+ }
+}
+EOF
+
+ reload_firewall
+
+ return 0
+}
+
+down_rules() {
+ if [ -f "$IPV4_RULES_FILE" ]; then
+ rm -rf "$IPV4_RULES_FILE"
+ reload_firewall
+ fi
+
+ return 0
+}
+
+case "${PLUTO_VERB}" in
+ up-host|up-client) up_rules ;;
+ down-host|down-client) down_rules ;;
+ up-host-v6|down-host-v6) ;;
+ up-client|down-client-v6) ;;
+esac
--- /dev/null
+#!/bin/sh /etc/rc.common
+
+. "${IPKG_INSTROOT}/lib/functions/network.sh"
+
+START=90
+STOP=10
+
+USE_PROCD=1
+
+PROG="/usr/libexec/ipsec/pluto"
+IPSEC_BIN="/usr/sbin/ipsec"
+
+IPSEC_DIR="/var/run/ipsec"
+IPSEC_CONF="$IPSEC_DIR/setup.conf"
+IPSEC_CONF_DIR="$IPSEC_DIR/conf.d"
+
+IPSEC_AUTO="${IPSEC_BIN} auto"
+
+extra_command "start_tunnel" "Start ipsec tunnel"
+extra_command "stop_tunnel" "Stop ipsec tunnel"
+extra_command "reload_tunnel" "Reload/restart ipsec tunnel"
+
+set_var() {
+ export "$1=$2"
+}
+
+get_var() {
+ local var
+
+ var=$(eval echo "\"\${${1}}\"")
+ [ "$var" = "1" ] && return 0
+
+ return 1
+}
+
+set_restart_flag() {
+ set_var "RESTART_IPSEC" 1
+}
+
+restart_flag() {
+ get_var RESTART_IPSEC
+}
+
+set_replace_flag() {
+ set_var "REPLACE_${1}" 1
+}
+
+replace_flag() {
+ get_var "REPLACE_${1}"
+}
+
+checkconfig() {
+ ${IPSEC_BIN} addconn --checkconfig || return 1
+ mkdir -p /var/run/pluto
+}
+
+expand_ike() {
+ local id="$1"
+ local encryption_algorithm hash_algorithm dh_group proposal
+
+ config_get encryption_algorithm "${id}" encryption_algorithm
+ config_get hash_algorithm "${id}" hash_algorithm
+ config_get dh_group "${id}" dh_group
+
+ encryption_algorithm="${encryption_algorithm% *}"
+ proposal="${encryption_algorithm:+${encryption_algorithm}${hash_algorithm:+-${hash_algorithm}${dh_group:+;${dh_group%% *}}}}"
+ append ike_proposal "$proposal" ","
+}
+
+expand_phase2alg() {
+ local id="$1"
+ local encryption_algorithm hash_algorithm dh_group
+
+ config_get encryption_algorithm "${id}" encryption_algorithm
+ config_get hash_algorithm "${id}" hash_algorithm
+ config_get dh_group "${id}" dh_group
+
+ phase2alg_proposal="${encryption_algorithm:+${encryption_algorithm// /+}${hash_algorithm:+-${hash_algorithm// /+}${dh_group:+-${dh_group// /+}}}}"
+}
+
+generate_tunnel_config() {
+ local id=$1
+ local config_file="$IPSEC_CONF_DIR/$id.conf"
+ local secret_file="$IPSEC_CONF_DIR/$id.secret"
+ local tmp_config_file="/tmp/$id.conf"
+ local tmp_secret_file="/tmp/$id.secret"
+ local ikey mark_in okey mark_out ifid
+
+ config_get auto "$id" auto
+ config_get left "$id" left
+ config_get left_interface "$id" left_interface
+ [ -n "$left_interface" ] && network_get_ipaddr left "$left_interface"
+ config_get right "$id" right
+ config_get leftid "$id" leftid "$left"
+ config_get rightid "$id" rightid "$right"
+ config_get leftsourceip "$id" leftsourceip
+ config_get rightsourceip "$id" rightsourceip
+ config_get leftsubnets "$id" leftsubnets
+ config_get rightsubnets "$id" rightsubnets
+ config_get_bool ikev2 "$id" ikev2
+ [ "$ikev2" = "1" ] && ikev2=yes || ikev2=no
+ config_get_bool rekey "$id" rekey
+ [ "$rekey" = "1" ] && rekey=yes || rekey=no
+ config_get ikelifetime "$id" ikelifetime
+ config_get rekeymargin "$id" rekeymargin
+ config_get dpdaction "$id" dpdaction
+ config_get dpdtimeout "$id" dpdtimeout
+ config_get dpddelay "$id" dpddelay
+ config_get phase2 "$id" phase2
+ config_get phase2alg "$id" phase2alg
+ config_get nflog "$id" nflog 0
+ [ "$nflog" = "0" ] && unset nflog
+
+ config_list_foreach "$id" ike expand_ike
+ config_list_foreach "$id" phase2alg expand_phase2alg
+
+ config_get authby "$id" authby
+ config_get psk "$id" psk
+
+ if [ -n "$leftsubnets" ]; then
+ [[ "$leftsubnets" =~ 0.0.0.0* ]] && leftsubnets="0.0.0.0/0"
+ leftsubnets="{${leftsubnets// /,}}"
+ fi
+
+ if [ -n "$rightsubnets" ]; then
+ [[ "$rightsubnets" =~ 0.0.0.0* ]] && rightsubnets="0.0.0.0/0"
+ rightsubnets="{${rightsubnets// /,}}"
+ fi
+
+ config_get interface "$id" interface
+
+ cat << EOF > "$tmp_secret_file"
+$leftid $rightid : PSK "$psk"
+EOF
+
+ cat << EOF > "$tmp_config_file"
+conn $id
+ auto=${auto}
+ authby=${authby}
+ ikev2=${ikev2}
+ left=${left%% *}
+ ${leftid:+leftid=${leftid}}
+ ${leftsourceip:+leftsourceip=${leftsourceip}}
+ ${leftsubnets:+leftsubnets=${leftsubnets}}
+ right=${right%% *}
+ ${rightid:+rightid=${rightid}}
+ ${rightsourceip:+rightsourceip=${rightsourceip}}
+ ${rightsubnets:+rightsubnets=${rightsubnets}}
+ ${dpdaction:+dpdaction=${dpdaction}}
+ ${dpdtimeout:+dpdtimeout=${dpdtimeout}}
+ ${dpddelay:+dpddelay=${dpddelay}}
+ ${ikelifetime:+ikelifetime=${ikelifetime}}
+ ${rekey:+rekey=${rekey}}
+ ${rekeymargin:+rekeymargin=${rekeymargin}}
+ ${rekeyfuzz:+rekeyfuzz=${rekeyfuzz}}
+ ${phase2:+phase2=${phase2}}
+ ${ike_proposal:+ike=${ike_proposal}}
+ ${phase2alg_proposal:+phase2alg=${phase2alg_proposal}}
+ ${nflog:+nflog=${nflog}}
+EOF
+
+ if [ -n "$interface" ]; then
+ proto=$(uci_get network "$interface" proto)
+ case "$proto" in
+ vti)
+ ikey=$(uci_get network "$interface" ikey)
+ okey=$(uci_get network "$interface" okey)
+ mark_in=$(printf "0x%x" $ikey)
+ mark_out=$(printf "0x%x" $okey)
+ echo -e "${mark_in:+\tmark-in=${mark_in}}" >> "$tmp_config_file"
+ echo -e "${mark_out:+\tmark-out=${mark_out}}" >> "$tmp_config_file"
+ echo -e "${interface:+\tvti-interface=${interface}}" >> "$tmp_config_file"
+ ;;
+ xfrm)
+ ifid=$(uci_get network "$interface" ifid)
+ echo -e "${ifid:+\tipsec-interface=${ifid}}" >> "$tmp_config_file"
+ ;;
+ esac
+ fi
+
+
+ [ -f "$config_file" ] && {
+ cmp "$config_file" "$tmp_config_file" 2>/dev/null && rm -f "$tmp_config_file"
+ }
+
+ [ -f "$secret_file" ] && {
+ cmp "$secret_file" "$tmp_secret_file" 2>/dev/null && rm -f "$tmp_secret_file"
+ }
+
+ [ -f "$tmp_config_file" ] && mv "$tmp_config_file" "$config_file" && set_replace_flag "$id"
+ [ -f "$tmp_secret_file" ] && mv "$tmp_secret_file" "$secret_file" && set_replace_flag "$id"
+
+ unset ike_proposal phase2alg_proposal
+}
+
+generate_daemon_config() {
+ local tmp_config_file="/tmp/setup.conf"
+
+ config_get_bool debug globals debug 0
+ [ "$debug" = "0" ] && debug=none || debug=all
+ config_get_bool uniqueids globals uniqueids 0
+ [ "$uniqueids" = "0" ] && uniqueids=no || uniqueids=yes
+ config_get listen globals listen
+ config_get listen_interface globals listen_interface
+ [ -n "$listen_interface" ] && network_get_ipaddr listen "$listen_interface"
+ config_get virtual_private globals virtual_private
+ [ -z "$virtual_private" ] && virtual_private='10.0.0.0/8 192.168.0.0/16 172.16.0.0/12 25.0.0.0/8 100.64.0.0/10 !100.64.0.0/24'
+ config_get nflog_all globals nflog_all 0
+ [ "$nflog_all" = "0" ] && unset nflog_all
+
+ [ ! -d $IPSEC_DIR ] && mkdir -p $IPSEC_DIR
+ [ ! -d $IPSEC_CONF_DIR ] && mkdir -p $IPSEC_CONF_DIR
+
+ cat << EOF > "$tmp_config_file"
+config setup
+ ${debug:+plutodebug=${debug}}
+ ${uniqueids:+uniqueids=${uniqueids}}
+ ${listen:+listen=${listen}}
+ ${virtual_private:+virtual-private=%v4:${virtual_private// /,%v4:}}
+ ${nflog_all:+nflog-all=${nflog_all}}
+EOF
+
+ if ! cmp "$IPSEC_CONF" "$tmp_config_file" 2>/dev/null; then
+ mv "$tmp_config_file" "$IPSEC_CONF"
+ set_restart_flag 1
+ else
+ rm -f "$tmp_config_file"
+ fi
+
+ return 0
+}
+
+clean_config() {
+ rm -f $IPSEC_CONF_DIR/*.conf $IPSEC_CONF_DIR/*.secret
+}
+
+config_cb() {
+ local var="CONFIG_${1}_SECTIONS"
+ export $var
+ append "$var" "$2"
+}
+
+generate_config() {
+ config_load libreswan
+ generate_daemon_config
+ config_foreach generate_tunnel_config tunnel
+}
+
+regenerate_config() {
+ clean_config
+ generate_config
+}
+
+active_conns() {
+ local active_conns file _file
+
+ active_conns=$(${IPSEC_BIN} --trafficstatus | awk -F'[":/]' '{print $3}' | sort -u)
+
+ for file in $IPSEC_CONF_DIR/*.conf; do
+ _file="${file##*/}"
+ list_contains active_conns "${_file%%.*}" || append active_conns "${_file%%.*}"
+ done
+
+ echo "$active_conns"
+}
+
+start_service() {
+ generate_config
+ checkconfig || return 1
+
+ ${IPSEC_BIN} _stackmanager start
+
+ procd_open_instance
+ procd_set_param command $PROG --nofork
+ procd_set_param respawn
+ procd_close_instance
+}
+
+stop_service() {
+ ${IPSEC_BIN} whack --shutdown
+ ${IPSEC_BIN} _stackmanager stop
+}
+
+stop_tunnel() {
+ ${IPSEC_AUTO} --delete "$1" > /dev/null 2>&1
+ rm -f ${IPSEC_CONF_DIR}/$1.*
+}
+
+start_tunnel() {
+ generate_tunnel_config "$1"
+ ${IPSEC_AUTO} --add "$1" > /dev/null 2>&1
+ ${IPSEC_AUTO} --rereadsecrets
+ ${IPSEC_AUTO} --up "$1" > /dev/null 2>&1 &
+}
+
+reload_tunnel() {
+ generate_tunnel_config "$1"
+
+ replace_flag "$1" || return 0
+
+ ${IPSEC_AUTO} --rereadsecrets
+ ${IPSEC_AUTO} --replace "$1" > /dev/null 2>&1
+ ${IPSEC_AUTO} --up "$1" > /dev/null 2>&1 &
+}
+
+reload_service() {
+ local active_tunnels uci_tunnels
+ uci_tunnels="$@"
+
+ config_load libreswan
+ generate_daemon_config
+
+ if restart_flag; then
+ restart
+ return 0
+ fi
+
+ [ -z "$uci_tunnels" ] && config_get uci_tunnels tunnel SECTIONS
+
+ active_tunnels="$(active_conns)"
+
+ for tunnel in $active_tunnels; do
+ list_contains uci_tunnels "$tunnel" || stop_tunnel "$tunnel"
+ done
+
+ for tunnel in $uci_tunnels; do
+ if list_contains active_tunnels "$tunnel"; then
+ reload_tunnel "$tunnel"
+ else
+ start_tunnel "$tunnel"
+ fi
+ done
+}
+
+service_triggers() {
+ procd_add_reload_trigger 'libreswan'
+}
--- /dev/null
+include /var/run/ipsec/setup.conf
+include /var/run/ipsec/conf.d/*.conf
+include /etc/ipsec.d/*.conf
--- /dev/null
+include /var/run/ipsec/conf.d/*.secret
+include /etc/ipsec.d/*.secrets
--- /dev/null
+#!/bin/sh
+
+FW4="$(command -v fw4)"
+[ -n "$FW4" ] && exit 0
+
+IPT_LEGACY="$(command -v iptables-legacy)"
+IPT="$(command -v iptables)"
+BIN="${IPT_LEGACY:-$IPT}"
+[ -z "$BIN" ] && exit 0
+
+LIBRESWAN_INPUT="libreswan_input"
+LIBRESWAN_FORWARD="libreswan_forward"
+LIBRESWAN_OUTPUT="libreswan_output"
+LIBRESWAN_NFLOG_INPUT="libreswan_nflog_input"
+LIBRESWAN_NFLOG_OUTPUT="libreswan_nflog_output"
+LIBRESWAN_POSTROUTING="libreswan_postrouting"
+
+FW_DIR="/tmp/libreswan/firewall.d"
+LIBRESWAN_RULES_FILE="$FW_DIR/libreswan.rules"
+
+flush_delete_chain() {
+ [ $# -lt 2 ] && return
+
+ $BIN -t $1 -nL $2 > /dev/null 2>&1 || return
+
+ $BIN -t $1 -F $2
+ $BIN -t $1 -X $2
+}
+
+cleanup_libreswan_rules() {
+ $BIN -t filter -C input_rule -j $LIBRESWAN_INPUT > /dev/null 2>&1
+ [ $? -eq 0 ] && $BIN -t filter -D input_rule -j $LIBRESWAN_INPUT
+
+ $BIN -t filter -C output_rule -j $LIBRESWAN_OUTPUT > /dev/null 2>&1
+ [ $? -eq 0 ] && $BIN -t filter -D output_rule -j $LIBRESWAN_OUTPUT
+
+ $BIN -t filter -C forwarding_rule -j $LIBRESWAN_FORWARD > /dev/null 2>&1
+ [ $? -eq 0 ] && $BIN -t filter -D forwarding_rule -j $LIBRESWAN_FORWARD
+
+ $BIN -t nat -C postrouting_rule -j $LIBRESWAN_POSTROUTING > /dev/null 2>&1
+ [ $? -eq 0 ] && $BIN -t nat -D postrouting_rule -j $LIBRESWAN_POSTROUTING
+
+ flush_delete_chain filter $LIBRESWAN_NFLOG_INPUT
+ flush_delete_chain filter $LIBRESWAN_INPUT
+ flush_delete_chain filter $LIBRESWAN_FORWARD
+ flush_delete_chain filter $LIBRESWAN_NFLOG_OUTPUT
+ flush_delete_chain filter $LIBRESWAN_OUTPUT
+ flush_delete_chain filter $LIBRESWAN_NFLOG_INPUT
+ flush_delete_chain filter $LIBRESWAN_NFLOG_OUTPUT
+ flush_delete_chain nat $LIBRESWAN_POSTROUTING
+}
+
+create_chain_jump() {
+ [ $# -lt 3 ] && return
+
+ local table=$1
+ local chain=$2
+ local base_chain=$3
+
+ $BIN -t $table -N $chain
+ $BIN -t $table -C $base_chain -j $chain
+ [ $? -ne 0 ] && $BIN -t $table -I $base_chain -j $chain
+ $BIN -t $table -F $chain
+}
+
+if ! /etc/init.d/ipsec running; then
+ cleanup_libreswan_rules
+ exit 0
+fi
+
+eval $(ipsec addconn --configsetup)
+
+create_chain_jump filter "$LIBRESWAN_INPUT" "insert_rule"
+create_chain_jump filter "$LIBRESWAN_FORWARD" "forwarding_rule"
+create_chain_jump filter "$LIBRESWAN_OUTPUT" "output_rule"
+
+create_chain_jump filter "$LIBRESWAN_NFLOG_INPUT" "$LIBRESWAN_INPUT"
+create_chain_jump filter "$LIBRESWAN_NFLOG_OUTPUT" "$LIBRESWAN_OUTPUT"
+
+create_chain_jump nat "$LIBRESWAN_POSTROUTING" "postrouting_rule"
+
+[ ! -f $LIBRESWAN_RULES_FILE ] && exit 0
+
+if [ -n "$nflog_all" ]; then
+ sed -i -e '/NFLOG/d' "$LIBRESWAN_RULES_FILE"
+ $BIN -t filter -I $LIBRESWAN_NFLOG_INPUT -m policy --dir in --pol ipsec -j NFLOG --nflog-group ${nflog_all} --nflog-prefix all-ipsec
+ $BIN -t filter -I $LIBRESWAN_NFLOG_OUTPUT -m policy --dir out --pol ipsec -j NFLOG --nflog-group ${nflog_all} --nflog-prefix all-ipsec
+fi
+
+sh $LIBRESWAN_RULES_FILE
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+
+uci_add firewall include libreswan
+uci_set firewall libreswan path '/etc/libreswan_firewall.sh'
+uci_set firewall libreswan reload 1
+uci_commit firewall
+++ /dev/null
-config setup
- # needed when using PSK only. Not needed for X.509 based servers
- uniqueids=no
- virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v4:!100.64.0.0/24
-
-conn ikev1
- authby=secret
- pfs=no
- auto=add
- rekey=no
- left=%defaultroute
- right=%any
- ikev2=never
- type=transport
- leftprotoport=17/1701
- rightprotoport=17/%any
- dpddelay=15
- dpdtimeout=30
- dpdaction=clear
-
-conn ikev1-nat
- also=ikev1
- rightsubnet=vhost:%priv
-
-# include /etc/ipsec.d/*.conf
+++ /dev/null
-#!/bin/sh /etc/rc.common
-
-START=90
-STOP=10
-
-USE_PROCD=1
-PROG="/usr/libexec/ipsec/pluto"
-IPSEC_SECRETS=/etc/ipsec.secrets
-IPSEC_CONF=/etc/ipsec.conf
-IPSEC_BIN=/usr/sbin/ipsec
-
-checkconfig() {
- ${IPSEC_BIN} addconn --checkconfig || return 1
- mkdir -p /var/run/pluto
-}
-
-start_service() {
- checkconfig || return 1
-
- ipsec _stackmanager start
- # Enable nflog if configured
- ipsec --checknflog > /dev/null
-
- procd_open_instance
- procd_set_param command $PROG --config ${IPSEC_CONF} --nofork --secretsfile ${IPSEC_SECRETS}
- procd_set_param respawn
- procd_close_instance
-}
-
-stop_service() {
- ipsec whack --shutdown
- ipsec _stackmanager stop
- ipsec --stopnflog > /dev/null
-
-}
-
+++ /dev/null
-# Unlike older openswan, this file does NOT contain any X.509 related
-# information such as private key :RSA statements as these now reside
-# in the NSS database. See:
-#
-# https://libreswan.org/wiki/Using_NSS_with_libreswan
-# https://libreswan.org/wiki/Migrating_from_Openswan
-
-# A.B.C.D %any : PSK "SsEeCcRrEeTt"
-: PSK "SsEeCcRrEeTt"
-# include /etc/ipsec.d/*.secrets
--- /dev/null
+#!/bin/sh
+
+/sbin/hotplug-call libreswan
--- /dev/null
+#!/bin/sh
+
+. /lib/functions.sh
+. /usr/share/libubox/jshn.sh
+
+RPC_SCRIPTS=/usr/libexec/libreswan/rpc
+
+[ -d $RPC_SCRIPTS ] && include $RPC_SCRIPTS
+
+IPSEC_TRAFFIC_STATES="/tmp/ipsec_traffic.$$"
+IPSEC_TUNNEL_STATUS="/tmp/ipsec_status.$$"
+
+__function__() {
+ type "$1" > /dev/null 2>&1
+}
+
+foreach_extra() {
+ local file obj
+
+ [ ! -d $RPC_SCRIPTS ] && return
+
+ for file in $RPC_SCRIPTS/*; do
+ obj="${file##*/}"
+ $1 "${obj%%.*}"
+ done
+}
+
+get_index() {
+ [ $# -lt 2 ] && return 1
+
+ local var=$1
+ local str=$2
+ local ele
+ local i=1
+
+ eval "val=\"\${$var}\""
+
+ for ele in ${val}; do
+ if [[ "$ele" = "$str" ]]; then
+ echo "$i"
+ return 0
+ fi
+ i="$((i+1))"
+ done
+
+ return 1
+}
+
+phase1_established() {
+ grep -q "\"${1%/*}\/.*(IKE SA established)\|\"${1%/*}\/.*(established IKE SA)" "$IPSEC_TUNNEL_STATUS"
+}
+
+phase2_established() {
+ grep -q "\"$1\".*(IPsec SA established)\|\"$1\".*(established Child SA)" "$IPSEC_TUNNEL_STATUS"
+}
+
+add_tunnel_object() {
+ local id="$1"
+ local leftsubnets rightsubnets right ctime active_right
+ local phase1=0 phase2=0 add_time inBytes outBytes
+
+ config_get right "$id" right
+ config_get leftsubnets "$id" leftsubnets
+ config_get rightsubnets "$id" rightsubnets
+
+ if [ -z "$right" ] || [ "$right" = "%any" ] || [ "$right" == "0.0.0.0" ]; then
+ active_right=$(awk -F'[: ]' '{ if ( $4 ~ "'"$id/"'") {print $5; exit 0};}' "$IPSEC_TUNNEL_STATUS")
+ fi
+
+ for lsubnet in $leftsubnets; do
+ lidx=$(get_index leftsubnets $lsubnet)
+ for rsubnet in $rightsubnets; do
+ ridx=$(get_index rightsubnets $rsubnet)
+ tid="${id}/${lidx}x${ridx}"
+
+ eval $(awk -F, '{if ($1 ~ "'"$tid"'" ) {printf("%s %s %s", $3, $4, $5)};}' "$IPSEC_TRAFFIC_STATES")
+ json_add_object tunnels
+ json_add_string name "$id"
+ json_add_string right "$right${active_right:+ (${active_right})}"
+ json_add_string leftsubnet "$lsubnet"
+ json_add_string rightsubnet "$rsubnet"
+ json_add_int tx "$outBytes"
+ json_add_int rx "$inBytes"
+
+ phase1_established "$tid" && phase1=1
+ phase2_established "$tid" && phase2=1
+
+ json_add_boolean phase1 "$phase1"
+ json_add_boolean phase2 "$phase2"
+
+ if [ "$phase1" = "1" ] && [ "$phase2" = "1" ]; then
+ ctime="$(date +%s)"
+ json_add_boolean connected 1
+ json_add_int uptime "$((ctime - add_time))"
+ else
+ json_add_boolean connected 0
+ json_add_int uptime 0
+ fi
+
+ json_close_object
+ done
+ done
+}
+
+generate_libreswan_states() {
+ ipsec trafficstatus > "$IPSEC_TRAFFIC_STATES"
+ ipsec status > "$IPSEC_TUNNEL_STATUS"
+}
+
+clean_libreswan_states() {
+ return
+ rm -f "$IPSEC_TRAFFIC_STATES" "$IPSEC_TUNNEL_STATUS"
+}
+
+libreswan_status() {
+ config_load libreswan
+
+ generate_libreswan_states
+
+ json_init
+ json_add_array tunnels
+ config_foreach add_tunnel_object tunnel
+ json_close_array
+ json_dump
+
+ clean_libreswan_states
+}
+
+call_extra() {
+ if __function__ "$1"; then
+ $1
+ else
+ json_init
+ json_add_string error "invalid call $1"
+ json_dump
+ fi
+}
+
+call_method() {
+ case "$1" in
+ status)
+ libreswan_status
+ ;;
+ *)
+ call_extra $1
+ ;;
+ esac
+}
+
+list_extra() {
+ if __function__ "${1}_help"; then
+ ${1}_help
+ else
+ json_add_object "$1"
+ json_close_object
+ fi
+}
+
+list_methods() {
+ local file
+
+ json_init
+
+ json_add_object status
+ json_close_object
+
+ foreach_extra list_extra ${1}
+
+ json_dump
+}
+
+main () {
+ case "$1" in
+ list)
+ list_methods
+ ;;
+ call)
+ call_method $2
+ ;;
+ esac
+}
+
+main "$@"
--- /dev/null
+jump libreswan_forward
--- /dev/null
+jump libreswan_nflog_input
+jump libreswan_input
--- /dev/null
+jump libreswan_nflog_output
+jump libreswan_output
--- /dev/null
+jump libreswan_srcnat
--- /dev/null
+chain libreswan_input {}
+chain libreswan_nflog_input {}
+chain libreswan_forward {}
+chain libreswan_output {}
+chain libreswan_nflog_output {}
+chain libreswan_srcnat {}
include $(TOPDIR)/rules.mk
PKG_NAME:=lighttpd
-PKG_VERSION:=1.4.72
+PKG_VERSION:=1.4.73
PKG_RELEASE:=1
# release candidate ~rcX testing; remove for release
#PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://download.lighttpd.net/lighttpd/releases-1.4.x
-PKG_HASH:=f7cade4d69b754a0748c01463c33cd8b456ca9cc03bb09e85a71bcbcd54e55ec
+PKG_HASH:=818816d0b314b0aa8728a7076513435f6d5eb227f3b61323468e1f10dbe84ca8
-PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_MAINTAINER:=Glenn Strauss <gstrauss@gluelogic.com>
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=COPYING
PKG_CPE_ID:=cpe:/a:lighttpd:lighttpd
PKG_NAME:=mDNSResponder
PKG_VERSION:=IETF104
-PKG_RELEASE:=6
+PKG_RELEASE:=5
PKG_SOURCE:=mDNSResponder-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://opensource.apple.com/tarballs/mDNSResponder/IETF/
endef
define Build/InstallDev
- $(INSTALL_DIR) $(1)/usr/include/mdns
- $(CP) $(PKG_INSTALL_DIR)/usr/include/dns_sd.h $(1)/usr/include/mdns
- $(INSTALL_DIR) $(1)/usr/lib/mdns
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdns_sd.so.1 $(1)/usr/lib/mdns
- $(LN) -s libdns_sd.so.1 $(1)/usr/lib/mdns/libdns_sd.so
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/dns_sd.h $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdns_sd.so.1 $(1)/usr/lib/
+ $(LN) -s libdns_sd.so.1 $(1)/usr/lib/libdns_sd.so
endef
define Package/mdns-utils/install
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/mdnsd.init $(1)/etc/init.d/mdnsd
- $(INSTALL_DIR) $(1)/usr/lib/mdns
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdns_sd.so.1 $(1)/usr/lib/mdns
- $(LN) -s libdns_sd.so.1 $(1)/usr/lib/mdns/libdns_sd.so
+ $(INSTALL_DIR) $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdns_sd.so.1 $(1)/usr/lib/
+ $(LN) -s libdns_sd.so.1 $(1)/usr/lib/libdns_sd.so
endef
define Package/mdnsresponder/install
include $(TOPDIR)/rules.mk
PKG_NAME:=modemmanager
-PKG_SOURCE_VERSION:=1.20.6
-PKG_RELEASE:=14
+PKG_SOURCE_VERSION:=1.22.0
+PKG_RELEASE:=7
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git
-PKG_MIRROR_HASH:=e90103e2e42bb826bbbac83937a9a69f50348cd6ce0d8da655a12b65494ce7c9
+PKG_MIRROR_HASH:=98daa1a15075c88afb3ed0de20dc83fe51d2ba3c66318ce3f731da4616a2e192
PKG_MAINTAINER:=Nicholas Smith <nicholas@nbembedded.com>
PKG_LICENSE:=GPL-2.0-or-later
-Dintrospection=false \
-Dman=false \
-Dbash_completion=false \
+ -Dbuiltin_plugins=true \
-Db_lto=true \
-Dmbim=$(if $(CONFIG_MODEMMANAGER_WITH_MBIM),true,false) \
-Dqmi=$(if $(CONFIG_MODEMMANAGER_WITH_QMI),true,false) \
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmm-glib.so.* $(1)/usr/lib
- $(INSTALL_DIR) $(1)/usr/lib/ModemManager
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/ModemManager/libmm-shared-*.so* $(1)/usr/lib/ModemManager
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/ModemManager/libmm-plugin-*.so* $(1)/usr/lib/ModemManager
-
$(INSTALL_DIR) $(1)/usr/lib/ModemManager/connection.d
$(INSTALL_BIN) ./files/10-report-down $(1)/usr/lib/ModemManager/connection.d
option lowpower '1'
option signalrate '30'
option allow_roaming '1'
+ option init_epsbearer '<none|default|custom>'
Only 'device' and 'proto' are mandatory options, the remaining ones are all
optional.
The 'signalrate' option set's the signal refresh rate (in seconds) for the device.
You can call signal info with command: mmcli -m 0 --signal-get
+
+If there is no Circuit switch network available, then an initial EPS
+bearer must be set, so this could be used during the network registration
+process in 4G and 5G network. For this resaon a new configuration option
+'init_epsbearer' was added, which could have the following values.
+* none: Do not set an initial EPS bearer (default)
+* default: Use the configuration option 'apn', 'iptype', 'allowedauth',
+ 'username' and 'password' for setting the initial EPS bearer.
+ These are the same options as when establishing a connection.
+* custom: This could be used to use diffrent options when establishing a
+ connection. The options are prefixed with an 'init'. So we have
+ the following options 'init_apn', 'init_iptype',
+ 'init_allowedauth', 'init_username' and 'init_password' for
+ setting the initial EPS bearer.
# Cleanup interfaces
mm_cleanup_interfaces() {
- local modemlist modemlength idx modeminfo modemsysfspath
-
- modemlist=$(mmcli --list-modems --output-keyvalue)
- [ -n "${modemlist}" ] || return 0
-
- modemlength=$(modemmanager_get_field "${modemlist}" "modem-list.length")
-
- # do nothing if no modem reported
- [ -n "${modemlength}" ] && [ "${modemlength}" -ge 1 ] && {
- idx=1
- while [ $idx -le "$modemlength" ]; do
- modempath=$(modemmanager_get_field "${modemlist}" "modem-list.value\[$idx\]")
- modeminfo=$(mmcli --modem "${modempath}" --output-keyvalue)
- modemsysfspath=$(modemmanager_get_field "${modeminfo}" "modem.generic.device")
- mm_cleanup_interface_by_sysfspath "${modemsysfspath}"
- idx=$((idx + 1))
- done
- }
+ local sysfs_path status
+
+ # Do nothing if there is no sysfs cache
+ [ -f "${MODEMMANAGER_SYSFS_CACHE}" ] || return
+
+ while IFS= read -r sysfs_cache_line; do
+ sysfs_path=$(echo "${sysfs_cache_line}" | awk '{print $1}')
+ status=$(echo "${sysfs_cache_line}" | awk '{print $2}')
+
+ if [ "${status}" = "processed" ]; then
+ mm_log "debug" "call cleanup for: ${sysfs_path}"
+ mm_cleanup_interface_by_sysfspath "${sysfs_path}"
+ fi
+ done < ${MODEMMANAGER_SYSFS_CACHE}
}
mm_cleanup_interface_by_sysfspath() {
local sysfspath="$4"
# Do not save virtual devices
- local virtual
+ local virtual result
virtual="$(echo "$sysfspath" | cut -d'/' -f4)"
[ "$virtual" = "virtual" ] && {
mm_log "debug" "sysfspath is a virtual device ($sysfspath)"
esac
# Report the event
- mm_log "debug" "event reported: action=${action}, name=${name}, subsystem=${subsystem}"
- mmcli --report-kernel-event="action=${action},name=${name},subsystem=${subsystem}" 1>/dev/null 2>&1 &
+ mm_log "debug" "Report event: action=${action}, name=${name}, subsystem=${subsystem}"
+ result=$(mmcli --report-kernel-event="action=${action},name=${name},subsystem=${subsystem}" 2>&1)
+ if [ "$?" -eq "0" ]; then
+ # Wait for added modem if a sysfspath is given
+ [ -n "${sysfspath}" ] && [ "$action" = "add" ] && mm_report_modem_wait "${sysfspath}"
+ else
+ mm_log "error" "Couldn't report kernel event: ${result}"
+ fi
- # Wait for added modem if a sysfspath is given
- [ -n "${sysfspath}" ] && [ "$action" = "add" ] && mm_report_modem_wait "${sysfspath}"
}
mm_report_event_from_cache_line() {
}
mm_report_events_from_cache() {
- # Remove the sysfs cache
- rm -f "${MODEMMANAGER_SYSFS_CACHE}"
-
local n=60
local step=1
local mmrunning=0
return
}
+ # Remove the sysfs cache
+ rm -f "${MODEMMANAGER_SYSFS_CACHE}"
+
# Report cached kernel events
while IFS= read -r event_line; do
mm_report_event_from_cache_line "${event_line}"
LOG_LEVEL="INFO"
-stop_service() {
- # Load common utils
- . /usr/share/ModemManager/modemmanager.common
- # Set all configured interfaces as unavailable
- mm_cleanup_interfaces
-}
-
start_service() {
# Setup ModemManager service
#
proto_config_add_int signalrate
proto_config_add_boolean lowpower
proto_config_add_boolean allow_roaming
+ proto_config_add_string init_epsbearer
+ proto_config_add_string init_iptype
+ proto_config_add_string 'init_allowedauth:list(string)'
+ proto_config_add_string init_password
+ proto_config_add_string init_user
+ proto_config_add_string init_apn
proto_config_add_defaults
}
}
}
+modemmanager_check_state() {
+ local device="$1"
+ local modemstatus="$2"
+ local pincode="$3"
+
+ local state reason
+
+ state="$(modemmanager_get_field "${modemstatus}" "state")"
+ state="${state%% *}"
+ reason="$(modemmanager_get_field "${modemstatus}" "state-failed-reason")"
+
+ case "$state" in
+ "failed")
+ case "$reason" in
+ "sim-missing")
+ echo "SIM missing"
+ proto_notify_error "${interface}" MM_FAILED_REASON_SIM_MISSING
+ proto_block_restart "${interface}"
+ return 1
+ ;;
+ *)
+ proto_notify_error "${interface}" MM_FAILED_REASON_UNKNOWN
+ proto_block_restart "${interface}"
+ return 1
+ ;;
+ esac
+ ;;
+ "locked")
+ if [ -n "$pincode" ]; then
+ mmcli --modem="${device}" -i any --pin=${pincode} || {
+ proto_notify_error "${interface}" MM_PINCODE_WRONG
+ proto_block_restart "${interface}"
+ return 1
+ }
+ else
+ echo "PIN required"
+ proto_notify_error "${interface}" MM_PINCODE_REQUIRED
+ proto_block_restart "${interface}"
+ return 1
+ fi
+ ;;
+ esac
+}
+
modemmanager_set_preferred_mode() {
local device="$1"
local interface="$2"
}
}
+modemmanager_init_epsbearer() {
+ local eps="$1"
+ local device="$2"
+ local connectargs="$3"
+ local apn="$4"
+
+ [ "$eps" != 'none' ] && [ -z "${apn}" ] && {
+ echo "No '$eps' init eps bearer apn configured"
+ proto_notify_error "${interface}" MM_INIT_EPS_BEARER_APN_NOT_CONFIGURED
+ proto_block_restart "${interface}"
+ return 1
+ }
+
+ if [ "$eps" = "none" ]; then
+ echo "Deleting inital EPS bearer..."
+ else
+ echo "Setting '$eps' inital EPS bearer apn to '$apn'..."
+ fi
+
+ mmcli --modem="${device}" \
+ --timeout 120 \
+ --3gpp-set-initial-eps-bearer-settings="${connectargs}" || {
+ proto_notify_error "${interface}" MM_INIT_EPS_BEARER_SET_FAILED
+ proto_block_restart "${interface}"
+ return 1
+ }
+
+ # Wait here so that the modem can set the init EPS bearer
+ # for registration
+ sleep 2
+}
+
proto_modemmanager_setup() {
local interface="$1"
local device apn allowedauth username password pincode
local iptype plmn metric signalrate allow_roaming
+ local init_epsbearer
+ local init_iptype init_allowedauth
+ local init_password init_user init_apn
+
local address prefix gateway mtu dns1 dns2
json_get_vars device apn allowedauth username password
json_get_vars pincode iptype plmn metric signalrate allow_roaming
json_get_vars allowedmode preferredmode
+ json_get_vars init_epsbearer
+ json_get_vars init_iptype init_allowedauth
+ json_get_vars init_password init_user init_apn
+
# validate sysfs path given in config
[ -n "${device}" ] || {
echo "No device specified"
}
echo "modem available at ${modempath}"
+ modemmanager_check_state "$device" "${modemstatus}" "$pincode"
+ [ "$?" -ne "0" ] && return 1
+
[ -z "${allowedmode}" ] || {
case "$allowedmode" in
"2g")
# always cleanup before attempting a new connection, just in case
modemmanager_cleanup_connection "${modemstatus}"
- # if allowedauth list given, build option string
- for auth in $allowedauth; do
- cliauth="${cliauth}${cliauth:+|}$auth"
- done
+ mmcli --modem="${device}" --timeout 120 --enable || {
+ proto_notify_error "${interface}" MM_MODEM_DISABLED
+ return 1
+ }
+
+ # set initial eps bearer settings
+ [ -z "${init_epsbearer}" ] || {
+ case "$init_epsbearer" in
+ "none")
+ connectargs=""
+ modemmanager_init_epsbearer "none" \
+ "$device" "${connectargs}" "$apn"
+ ;;
+ "default")
+ cliauth=""
+ for auth in $allowedauth; do
+ cliauth="${cliauth}${cliauth:+|}$auth"
+ done
+ connectargs=""
+ append_param "apn=${apn}"
+ append_param "${iptype:+ip-type=${iptype}}"
+ append_param "${cliauth:+allowed-auth=${cliauth}}"
+ append_param "${username:+user=${username}}"
+ append_param "${password:+password=${password}}"
+ modemmanager_init_epsbearer "default" \
+ "$device" "${connectargs}" "$apn"
+ ;;
+ "custom")
+ cliauth=""
+ for auth in $init_allowedauth; do
+ cliauth="${cliauth}${cliauth:+|}$auth"
+ done
+ connectargs=""
+ append_param "apn=${init_apn}"
+ append_param "${init_iptype:+ip-type=${init_iptype}}"
+ append_param "${cliauth:+allowed-auth=${cliauth}}"
+ append_param "${init_username:+user=${init_username}}"
+ append_param "${init_password:+password=${init_password}}"
+ modemmanager_init_epsbearer "custom" \
+ "$device" "${connectargs}" "$init_apn"
+ ;;
+ esac
+ # check error for init_epsbearer function call
+ [ "$?" -ne "0" ] && return 1
+ }
# setup connect args; APN mandatory (even if it may be empty)
echo "starting connection with apn '${apn}'..."
allow_roaming="yes"
fi
+ cliauth=""
+ for auth in $allowedauth; do
+ cliauth="${cliauth}${cliauth:+|}$auth"
+ done
# Append options to 'connectargs' variable
+ connectargs=""
append_param "apn=${apn}"
append_param "allow-roaming=${allow_roaming}"
append_param "${iptype:+ip-type=${iptype}}"
append_param "${cliauth:+allowed-auth=${cliauth}}"
append_param "${username:+user=${username}}"
append_param "${password:+password=${password}}"
- append_param "${pincode:+pin=${pincode}}"
mmcli --modem="${device}" --timeout 120 --simple-connect="${connectargs}" || {
proto_notify_error "${interface}" MM_CONNECT_FAILED
mkdir -p "${MODEMMANAGER_RUNDIR}"
chmod 0755 "${MODEMMANAGER_RUNDIR}"
- mm_cleanup_interfaces
/usr/sbin/ModemManager "$@" 1>/dev/null 2>/dev/null &
CHILD="$!"
mm_report_events_from_cache
wait "$CHILD"
+
+ # Set all configured interfaces as unavailable
+ mm_cleanup_interfaces
}
main "$@"
--- /dev/null
+--- a/src/plugins/ublox/77-mm-ublox-port-types.rules
++++ b/src/plugins/ublox/77-mm-ublox-port-types.rules
+@@ -88,8 +88,8 @@ SUBSYSTEMS=="usb", ATTRS{bInterfaceNumbe
+ # ttyUSB2 (if #2): secondary
+ # ttyUSB3 (if #3): unused (ignore)
+ ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_IGNORE}="1"
+-ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="01", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1", ENV{ID_MM_DEVICE_PROCESS}="1"
+-ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1", ENV{ID_MM_DEVICE_PROCESS}="1"
++ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="01", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1"
++ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1"
+ ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_IGNORE}="1"
+
+ LABEL="mm_ublox_port_types_end"
include $(TOPDIR)/rules.mk
PKG_NAME:=mosquitto
-PKG_VERSION:=2.0.17
+PKG_VERSION:=2.0.18
PKG_RELEASE:=1
-PKG_LICENSE:=EPL-2.0
-PKG_LICENSE_FILES:=LICENSE.txt
-PKG_CPE_ID:=cpe:/a:eclipse:mosquitto
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://mosquitto.org/files/source/
-PKG_HASH:=3be7a911236567c1a9fbe25baf3e3167004ba4a0c151a448ef1f7fc077dba52f
+PKG_HASH:=d665fe7d0032881b1371a47f34169ee4edab67903b2cd2b4c083822823f4448a
+
+PKG_LICENSE:=EPL-2.0
+PKG_LICENSE_FILES:=LICENSE.txt
+PKG_CPE_ID:=cpe:/a:eclipse:mosquitto
include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
define Package/mosquitto/default
SECTION:=net
define Package/mosquitto/install/default
$(INSTALL_DIR) $(1)/usr/sbin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/mosquitto $(1)/usr/sbin/mosquitto
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/mosquitto $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/mosquitto
- $(INSTALL_CONF) $(PKG_BUILD_DIR)/mosquitto.conf $(1)/etc/mosquitto/mosquitto.conf
+ $(INSTALL_CONF) $(PKG_INSTALL_DIR)/usr/etc/mosquitto/mosquitto.conf $(1)/etc/mosquitto
$(CP) ./files/* $(1)/
endef
$(call Package/mosquitto/install/default,$(1))
ifeq ($(CONFIG_MOSQUITTO_PASSWD),y)
$(INSTALL_DIR) $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/apps/mosquitto_passwd/mosquitto_passwd $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mosquitto_passwd $(1)/usr/bin
endif
ifeq ($(CONFIG_MOSQUITTO_DYNAMIC_SECURITY),y)
$(INSTALL_DIR) $(1)/usr/lib
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/plugins/dynamic-security/mosquitto_dynamic_security.so $(1)/usr/lib
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/mosquitto_dynamic_security.so $(1)/usr/lib
endif
endef
define Package/mosquitto-client-nossl/install
$(INSTALL_DIR) $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/client/mosquitto_pub $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/client/mosquitto_sub $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/client/mosquitto_rr $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mosquitto_pub $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mosquitto_sub $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mosquitto_rr $(1)/usr/bin
endef
define Package/mosquitto-client-ssl/install
$(call Package/mosquitto-client-nossl/install,$(1))
ifeq ($(CONFIG_MOSQUITTO_CTRL),y)
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/apps/mosquitto_ctrl/mosquitto_ctrl $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mosquitto_ctrl $(1)/usr/bin
endif
endef
# This installs files into ./staging_dir/. so that you can cross compile from the host
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
- $(CP) $(PKG_BUILD_DIR)/include/*.h $(1)/usr/include
- $(CP) $(PKG_BUILD_DIR)/lib/cpp/mosquittopp.h $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_BUILD_DIR)/lib/libmosquitto.so.1 $(1)/usr/lib/
- $(CP) $(PKG_BUILD_DIR)/lib/cpp/libmosquittopp.so.1 $(1)/usr/lib/
- $(LN) libmosquitto.so.1 $(1)/usr/lib/libmosquitto.so
- $(LN) libmosquittopp.so.1 $(1)/usr/lib/libmosquittopp.so
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libmosquitto.so* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libmosquittopp.so* $(1)/usr/lib/
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
- $(CP) $(PKG_BUILD_DIR)/libmosquitto.pc.in $(1)/usr/lib/pkgconfig/libmosquitto.pc
- sed -i -e "s#@CMAKE_INSTALL_PREFIX@#/usr#" \
- -e "s#@VERSION@#$(PKG_VERSION)#" \
- $(1)/usr/lib/pkgconfig/libmosquitto.pc
- $(CP) $(PKG_BUILD_DIR)/libmosquittopp.pc.in $(1)/usr/lib/pkgconfig/libmosquittopp.pc
- sed -i -e "s#@CMAKE_INSTALL_PREFIX@#/usr#" \
- -e "s#@VERSION@#$(PKG_VERSION)#" \
- $(1)/usr/lib/pkgconfig/libmosquittopp.pc
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc $(1)/usr/lib/pkgconfig
endef
# This installs files on the target. Compare with Build/InstallDev
define Package/libmosquitto-ssl/install
$(INSTALL_DIR) $(1)/usr/lib
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/libmosquitto.so.1 $(1)/usr/lib/
- $(LN) libmosquitto.so.1 $(1)/usr/lib/libmosquitto.so
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/libmosquitto.so.* $(1)/usr/lib/
endef
Package/libmosquitto-nossl/install = $(Package/libmosquitto-ssl/install)
define Package/libmosquittopp/install
$(INSTALL_DIR) $(1)/usr/lib
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/cpp/libmosquittopp.so.1 $(1)/usr/lib/
- $(LN) libmosquittopp.so.1 $(1)/usr/lib/libmosquittopp.so
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/libmosquittopp.so.* $(1)/usr/lib/
endef
# Applies to all...
-MAKE_FLAGS += WITH_DOCS=no UNAME=Linux
+CMAKE_OPTIONS += \
+ -DDOCUMENTATION=OFF \
+ -DWITH_ADNS=OFF \
+ -DWITH_BUNDLED_DEPS=ON \
+ -DWITH_DLT=OFF \
+ -DWITH_PERSISTENCE=OFF \
+ -DWITH_PIC=ON \
+ -DWITH_SOCKS=ON \
+ -DWITH_SRV=ON \
+ -DWITH_SYSTEMD=OFF \
+ -DWITH_SYS_TREE=OFF \
+ -DWITH_THREADING=ON
+
ifeq ($(BUILD_VARIANT),nossl)
- MAKE_FLAGS += WITH_TLS=no WITH_WEBSOCKETS=no
+ CMAKE_OPTIONS += -DWITH_TLS=OFF -DWITH_WEBSOCKETS=OFF
else
- MAKE_FLAGS += WITH_WEBSOCKETS=$(if $(CONFIG_MOSQUITTO_LWS),"yes","no")
- MAKE_FLAGS += WITH_TLS_PSK=$(if $(CONFIG_OPENSSL_WITH_PSK),"yes","no")
+ CMAKE_OPTIONS += -DWITH_TLS_PSK=O$(if $(CONFIG_OPENSSL_WITH_PSK),N,FF)
+ CMAKE_OPTIONS += -DWITH_WEBSOCKETS=O$(if $(CONFIG_MOSQUITTO_LWS),N,FF)
endif
$(eval $(call BuildPackage,mosquitto-ssl))
include $(TOPDIR)/rules.mk
PKG_NAME:=nebula
-PKG_VERSION:=1.7.2
+PKG_VERSION:=1.8.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/slackhq/nebula/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=c4771ce6eb3e142f88f5f4c12443cfca140bf96b2746c74f9536bd1a362f3f88
+PKG_HASH:=678ad2bda47258cce8c2d14b3fa56d17c0ba4f894d75b75afab8937d64e12da7
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
PKG_LICENSE:=MIT
TITLE:=nebula-proto
URL:=https://docs.openwrt.melmac.net/nebula/
DEPENDS:=nebula
+ DEPENDS+=+!BUSYBOX_DEFAULT_AWK:gawk
+ DEPENDS+=+!BUSYBOX_DEFAULT_GREP:grep
+ DEPENDS+=+!BUSYBOX_DEFAULT_SED:sed
PKGARCH:=all
endef
TITLE:=nebula-service
URL:=https://docs.openwrt.melmac.net/nebula/
DEPENDS:=nebula
+ DEPENDS+=+!BUSYBOX_DEFAULT_AWK:gawk
+ DEPENDS+=+!BUSYBOX_DEFAULT_SED:sed
CONFLICTS:=nebula-proto
PKGARCH:=all
endef
endef
define Package/nebula/description
- Nebula is a scalable overlay networking tool with a focus on performance, simplicity
- and security. It lets you seamlessly connect computers anywhere in the world.
- This package contains only nebula binary. Unless you want to start nebula manually,
- you may want to also install *either* 'nebula-service' *or* 'nebula-proto' package.
+Nebula is a scalable overlay networking tool with a focus on performance, simplicity
+and security. It lets you seamlessly connect computers anywhere in the world.
+This package contains only nebula binary. Unless you want to start nebula manually,
+you may want to also install *either* 'nebula-service' *or* 'nebula-proto' package.
endef
define Package/nebula-cert/description
- Nebula is a scalable overlay networking tool with a focus on performance, simplicity
- and security. It lets you seamlessly connect computers anywhere in the world.
- This package contains only nebula-cert binary.
+Nebula is a scalable overlay networking tool with a focus on performance, simplicity
+and security. It lets you seamlessly connect computers anywhere in the world.
+This package contains only nebula-cert binary.
endef
define Package/nebula-proto/description
- Nebula is a scalable overlay networking tool with a focus on performance, simplicity
- and security. It lets you seamlessly connect computers anywhere in the world.
- This package contains only OpenWrt protocol/interface support for nebula.
+Nebula is a scalable overlay networking tool with a focus on performance, simplicity
+and security. It lets you seamlessly connect computers anywhere in the world.
+This package contains only OpenWrt protocol/interface support for nebula.
endef
define Package/nebula-service/description
- Nebula is a scalable overlay networking tool with a focus on performance, simplicity
- and security. It lets you seamlessly connect computers anywhere in the world.
- This package contains only OpenWrt-specific init.d script for nebula.
+Nebula is a scalable overlay networking tool with a focus on performance, simplicity
+and security. It lets you seamlessly connect computers anywhere in the world.
+This package contains only OpenWrt-specific init.d script for nebula.
endef
define Package/nebula/install
[ -s "$config_file" ] || { log "Config file not found or empty!"; return 1; }
eval "$(yaml_parse "$config_file" "yaml_")"
+ yaml_tun_dev="${yaml_tun_dev%"${yaml_tun_dev##*[![:space:]]}"}"
[ "$yaml_tun_dev" = "$interface" ] || { log "Tunnel device in config file (${yaml_tun_dev}) doesn't match interface name (${interface})!"; return 1; }
log "Setting up ${interface} from $(basename "$config_file")."
json_close_array
proto_close_data
addresses="$(ip -4 a list dev "$interface" 2>/dev/null | grep inet | awk '{print $2}' | awk -F "/" '{print $1}')"
- log "Running ${interface} from $(basename "$config_file") with addresses: ${addresses}."
+ log "Running ${interface} from $(basename "$config_file")${addresses+: with addresses: $addresses}."
for address in ${addresses}; do
case "${address}" in
*:*/*)
PKG_NAME:=net-snmp
PKG_VERSION:=5.9.1
-PKG_RELEASE:=6
+PKG_RELEASE:=7
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/net-snmp
--- /dev/null
+From e5aadf1e78c624a8e4147d4b70a7795497a50e73 Mon Sep 17 00:00:00 2001
+From: Niels Baggesen <nba@users.sourceforge.net>
+Date: Mon, 22 May 2023 18:44:36 +0200
+Subject: [PATCH] if-mib/data_access/interface.c: plug a leak with pcre2
+
+---
+ agent/mibgroup/if-mib/data_access/interface.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/agent/mibgroup/if-mib/data_access/interface.c
++++ b/agent/mibgroup/if-mib/data_access/interface.c
+@@ -845,7 +845,7 @@ int netsnmp_access_interface_include(con
+ {
+ netsnmp_include_if_list *if_ptr;
+ #if defined(HAVE_PCRE2_H)
+- pcre2_match_data *ndx_match = pcre2_match_data_create(3, NULL);
++ pcre2_match_data *ndx_match;
+ #elif defined(HAVE_PCRE_H)
+ int found_ndx[3];
+ #endif
+@@ -860,6 +860,9 @@ int netsnmp_access_interface_include(con
+ */
+ return TRUE;
+
++#if defined(HAVE_PCRE2_H)
++ ndx_match = pcre2_match_data_create(3, NULL);
++#endif
+
+ for (if_ptr = include_list; if_ptr; if_ptr = if_ptr->next) {
+ #if defined(HAVE_PCRE2_H)
include $(TOPDIR)/rules.mk
PKG_NAME:=netavark
-PKG_VERSION:=1.8.0
+PKG_VERSION:=1.9.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/containers/netavark/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=b1422ef6927458e9f80f7d322b751e29ab5d04d8ed6cb065baa82fa4291af10f
+PKG_HASH:=9ec50b715ded0a0699134c001656fdd1411e3fb5325d347695c6cb8cc5fcf572
PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
PKG_LICENSE:=Apache-2.0
PKG_BUILD_DEPENDS:= \
rust/host \
protobuf/host
+PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
include ../../lang/rust/rust-package.mk
/etc/config/netavark
endef
-CARGO_VARS += \
+CARGO_PKG_VARS += \
PROTOC=$(STAGING_DIR_HOSTPKG)/bin/protoc
define Package/netavark/install
include $(TOPDIR)/rules.mk
PKG_NAME:=netbird
-PKG_VERSION:=0.23.6
+PKG_VERSION:=0.24.3
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/netbirdio/netbird/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=cb29e237652634f3a2a5774fdc239f615d46cf9339811c707744d1e03797126d
+PKG_HASH:=6590034fe8a8dc215242bbd7706197beef67a63a099a45a30c436373c892aab0
PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
PKG_LICENSE:=BSD-3-Clause
endef
define Package/netbird/description
- NetBird is an open-source VPN management platform built on top of WireGuard® making it easy to create
+ NetBird is an open-source VPN management platform built on top of WireGuard® making it easy to create
secure private networks for your organization or home.
- It requires zero configuration effort leaving behind the hassle of opening ports, complex firewall rules, VPN
+ It requires zero configuration effort leaving behind the hassle of opening ports, complex firewall rules, VPN
gateways, and so forth.
endef
/etc/netbird/config.json
endef
+# Workaround for musl 1.2.4 compability in mattn/go-sqlite3
+# https://github.com/mattn/go-sqlite3/issues/1164
+ifneq ($(CONFIG_USE_MUSL),)
+ TARGET_CFLAGS += -D_LARGEFILE64_SOURCE
+endif
+
define Package/netbird/install
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
$(INSTALL_DIR) $(1)/usr/bin $(1)/etc/init.d
#!/bin/sh /etc/rc.common
+. /lib/netifd/netifd-proto.sh
+
START=99
STOP=10
USE_PROCD=1
+service_triggers() {
+ procd_add_interface_trigger "interface.*" "wan" /etc/init.d/netbird restart
+}
+
start_service() {
+ local device
+
procd_open_instance
procd_set_param command /usr/bin/netbird
procd_append_param command service run
prompt "Enable HTTP sub module"
default n
+config NGINX_STREAM_REAL_IP
+ bool
+ prompt "Enable STREAM real ip module"
+ default n
+
endmenu
PKG_NAME:=nginx
PKG_VERSION:=1.25.2
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=nginx-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://nginx.org/download/
CONFIG_NGINX_PCRE \
CONFIG_NGINX_HTTP_REAL_IP \
CONFIG_NGINX_HTTP_SECURE_LINK \
+ CONFIG_NGINX_STREAM_REAL_IP \
CONFIG_OPENSSL_ENGINE \
CONFIG_OPENSSL_WITH_NPN \
$(foreach m,$(PKG_MOD_EXTRA),CONFIG_PACKAGE_$(m))
$(if $(call IsEnabled,NGINX_HTTP_SECURE_LINK),--with-http_secure_link_module) \
$(if $(call IsEnabled,NGINX_HTTP_SUB),--with-http_sub_module) \
$(if $(CONFIG_PACKAGE_nginx-mod-stream),--with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module) \
+ $(if $(call IsEnabled,NGINX_STREAM_REAL_IP),--with-stream_realip_module) \
$(if $(CONFIG_PACKAGE_nginx-mod-naxsi),--add-dynamic-module=$(PKG_BUILD_DIR)/nginx-mod-naxsi/naxsi_src) \
$(foreach m,$(filter-out lua-resty-core lua-resty-lrucache naxsi,$(PKG_MOD_EXTRA)), \
$(if $(CONFIG_PACKAGE_nginx-mod-$(m)),--add-dynamic-module=$(PKG_BUILD_DIR)/nginx-mod-$(m)))
--- /dev/null
+From f968d74c3af8259f325090d282aeb64854cdddf9 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Fri, 13 Oct 2023 20:23:51 +0200
+Subject: [PATCH] bugfix: don't include pcre.h with PCRE2 used
+
+pcre.h is a PCRE header and is not exposed by PCRE2 library causing
+compilation error as the header is not found.
+
+Don't include pcre.h if nginx is compiled with PCRE2 support enabled.
+
+Fixes: cb83e33e2657 ("feature: support pcre2")
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ nginx-mod-lua/src/ngx_http_lua_common.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/nginx-mod-lua/src/ngx_http_lua_common.h
++++ b/nginx-mod-lua/src/ngx_http_lua_common.h
+@@ -54,7 +54,7 @@ typedef struct {
+ #endif
+
+
+-#if (NGX_PCRE)
++#if defined(NGX_PCRE) && !(NGX_PCRE2)
+ #include <pcre.h>
+ # if (PCRE_MAJOR > 8) || (PCRE_MAJOR == 8 && PCRE_MINOR >= 21)
+ # define LUA_HAVE_PCRE_JIT 1
PKG_NAME:=nmap
PKG_VERSION:=7.93
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_MAINTAINER:=Nuno Gonçalves <nunojpg@gmail.com>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
--- /dev/null
+From d6bea8dcdee36a3902cece14097993350306f1b6 Mon Sep 17 00:00:00 2001
+From: dmiller <dmiller@e0a8ed71-7df4-0310-8962-fdc924857419>
+Date: Tue, 6 Sep 2022 22:39:34 +0000
+Subject: [PATCH] Build based on OpenSSL version, not API level. Fixes #2516
+
+---
+ ncat/http_digest.c | 2 +-
+ ncat/ncat_connect.c | 4 ++--
+ ncat/ncat_ssl.c | 6 +++---
+ ncat/ncat_ssl.h | 12 ------------
+ ncat/test/test-wildcard.c | 4 ++--
+ nse_openssl.cc | 28 +++++++---------------------
+ nse_ssl_cert.cc | 24 ++++++------------------
+ nsock/src/nsock_ssl.c | 4 ++--
+ nsock/src/nsock_ssl.h | 15 +--------------
+ 9 files changed, 24 insertions(+), 75 deletions(-)
+
+--- a/ncat/http_digest.c
++++ b/ncat/http_digest.c
+@@ -133,7 +133,7 @@ int http_digest_init_secret(void)
+ return 0;
+ }
+
+-#if OPENSSL_API_LEVEL < 10100
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ #define EVP_MD_CTX_new EVP_MD_CTX_create
+ #define EVP_MD_CTX_free EVP_MD_CTX_destroy
+ #endif
+--- a/ncat/ncat_connect.c
++++ b/ncat/ncat_connect.c
+@@ -82,8 +82,8 @@
+ #include <openssl/err.h>
+
+ /* Deprecated in OpenSSL 3.0 */
+-#if OPENSSL_API_LEVEL >= 30000
+-#define SSL_get_peer_certificate SSL_get1_peer_certificate
++#if OPENSSL_VERSION_NUMBER >= 0x30000000L
++# define SSL_get_peer_certificate SSL_get1_peer_certificate
+ #endif
+ #endif
+
+--- a/ncat/ncat_ssl.c
++++ b/ncat/ncat_ssl.c
+@@ -80,7 +80,7 @@
+ #define FUNC_ASN1_STRING_data ASN1_STRING_data
+ #endif
+
+-#if OPENSSL_API_LEVEL >= 30000
++#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ #include <openssl/provider.h>
+ /* Deprecated in OpenSSL 3.0 */
+ #define SSL_get_peer_certificate SSL_get1_peer_certificate
+@@ -117,7 +117,7 @@ SSL_CTX *setup_ssl_listen(void)
+ OpenSSL_add_all_algorithms();
+ ERR_load_crypto_strings();
+ SSL_load_error_strings();
+-#elif OPENSSL_API_LEVEL >= 30000
++#elif OPENSSL_VERSION_NUMBER >= 0x30000000L
+ if (NULL == OSSL_PROVIDER_load(NULL, "legacy"))
+ {
+ loguser("OpenSSL legacy provider failed to load.\n");
+@@ -477,7 +477,7 @@ static int ssl_gen_cert(X509 **cert, EVP
+ const char *commonName = "localhost";
+ char dNSName[128];
+ int rc;
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ int ret = 0;
+ RSA *rsa = NULL;
+ BIGNUM *bne = NULL;
+--- a/ncat/ncat_ssl.h
++++ b/ncat/ncat_ssl.h
+@@ -67,18 +67,6 @@
+ #include <openssl/ssl.h>
+ #include <openssl/err.h>
+
+-/* OPENSSL_API_LEVEL per OpenSSL 3.0: decimal MMmmpp */
+-#ifndef OPENSSL_API_LEVEL
+-# if OPENSSL_API_COMPAT < 0x900000L
+-# define OPENSSL_API_LEVEL (OPENSSL_API_COMPAT)
+-# else
+-# define OPENSSL_API_LEVEL \
+- (((OPENSSL_API_COMPAT >> 28) & 0xF) * 10000 \
+- + ((OPENSSL_API_COMPAT >> 20) & 0xFF) * 100 \
+- + ((OPENSSL_API_COMPAT >> 12) & 0xFF))
+-# endif
+-#endif
+-
+ #define NCAT_CA_CERTS_FILE "ca-bundle.crt"
+
+ enum {
+--- a/ncat/test/test-wildcard.c
++++ b/ncat/test/test-wildcard.c
+@@ -20,7 +20,7 @@ are rejected. The SSL transactions happe
+
+ #include "ncat_core.h"
+ #include "ncat_ssl.h"
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ #include <openssl/bn.h>
+ #endif
+
+@@ -294,7 +294,7 @@ stack_err:
+ static int gen_cert(X509 **cert, EVP_PKEY **key,
+ const struct lstr commonNames[], const struct lstr dNSNames[])
+ {
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ int rc, ret=0;
+ RSA *rsa = NULL;
+ BIGNUM *bne = NULL;
+--- a/nse_openssl.cc
++++ b/nse_openssl.cc
+@@ -20,6 +20,9 @@
+ #define FUNC_EVP_CIPHER_CTX_init EVP_CIPHER_CTX_reset
+ #define FUNC_EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_reset
+ #define PASS_EVP_CTX(ctx) (ctx)
++#if OPENSSL_VERSION_NUMBER >= 0x30000000L
++# include <openssl/provider.h>
++#endif
+ #else
+ #define FUNC_EVP_MD_CTX_init EVP_MD_CTX_init
+ #define FUNC_EVP_MD_CTX_cleanup EVP_MD_CTX_cleanup
+@@ -37,23 +40,6 @@ extern NmapOps o;
+
+ #include "nse_openssl.h"
+
+-/* OPENSSL_API_LEVEL per OpenSSL 3.0: decimal MMmmpp */
+-#ifndef OPENSSL_API_LEVEL
+-# if OPENSSL_API_COMPAT < 0x900000L
+-# define OPENSSL_API_LEVEL (OPENSSL_API_COMPAT)
+-# else
+-# define OPENSSL_API_LEVEL \
+- (((OPENSSL_API_COMPAT >> 28) & 0xF) * 10000 \
+- + ((OPENSSL_API_COMPAT >> 20) & 0xFF) * 100 \
+- + ((OPENSSL_API_COMPAT >> 12) & 0xFF))
+-# endif
+-#endif
+-
+-
+-#if OPENSSL_API_LEVEL >= 30000
+-#include <openssl/provider.h>
+-#endif
+-
+ #define NSE_SSL_LUA_ERR(_L) \
+ luaL_error(_L, "OpenSSL error: %s", ERR_error_string(ERR_get_error(), NULL))
+
+@@ -184,7 +170,7 @@ static int l_bignum_is_prime( lua_State
+ bignum_data_t * p = (bignum_data_t *) luaL_checkudata( L, 1, "BIGNUM" );
+ BN_CTX * ctx = BN_CTX_new();
+ int is_prime =
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ BN_is_prime_ex( p->bn, BN_prime_checks, ctx, NULL );
+ #else
+ BN_check_prime( p->bn, ctx, NULL );
+@@ -199,7 +185,7 @@ static int l_bignum_is_safe_prime( lua_S
+ bignum_data_t * p = (bignum_data_t *) luaL_checkudata( L, 1, "BIGNUM" );
+ BN_CTX * ctx = BN_CTX_new();
+ int is_prime =
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ BN_is_prime_ex( p->bn, BN_prime_checks, ctx, NULL );
+ #else
+ BN_check_prime( p->bn, ctx, NULL );
+@@ -210,7 +196,7 @@ static int l_bignum_is_safe_prime( lua_S
+ BN_sub_word( n, (BN_ULONG)1 );
+ BN_div_word( n, (BN_ULONG)2 );
+ is_safe =
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ BN_is_prime_ex( n, BN_prime_checks, ctx, NULL );
+ #else
+ BN_check_prime( n, ctx, NULL );
+@@ -582,7 +568,7 @@ LUALIB_API int luaopen_openssl(lua_State
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
+ OpenSSL_add_all_algorithms();
+ ERR_load_crypto_strings();
+-#elif OPENSSL_API_LEVEL >= 30000
++#elif OPENSSL_VERSION_NUMBER >= 0x30000000L
+ if (NULL == OSSL_PROVIDER_load(NULL, "legacy") && o.debugging > 1)
+ {
+ // Legacy provider may not be available.
+--- a/nse_ssl_cert.cc
++++ b/nse_ssl_cert.cc
+@@ -89,19 +89,7 @@
+ #define X509_get0_notAfter X509_get_notAfter
+ #endif
+
+-/* OPENSSL_API_LEVEL per OpenSSL 3.0: decimal MMmmpp */
+-#ifndef OPENSSL_API_LEVEL
+-# if OPENSSL_API_COMPAT < 0x900000L
+-# define OPENSSL_API_LEVEL (OPENSSL_API_COMPAT)
+-# else
+-# define OPENSSL_API_LEVEL \
+- (((OPENSSL_API_COMPAT >> 28) & 0xF) * 10000 \
+- + ((OPENSSL_API_COMPAT >> 20) & 0xFF) * 100 \
+- + ((OPENSSL_API_COMPAT >> 12) & 0xFF))
+-# endif
+-#endif
+-
+-#if OPENSSL_API_LEVEL >= 30000
++#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ #include <openssl/core_names.h>
+ /* Deprecated in OpenSSL 3.0 */
+ #define SSL_get_peer_certificate SSL_get1_peer_certificate
+@@ -459,7 +447,7 @@ static const char *pkey_type_to_string(i
+ }
+
+ int lua_push_ecdhparams(lua_State *L, EVP_PKEY *pubkey) {
+-#if OPENSSL_API_LEVEL >= 30000
++#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ char tmp[64] = {0};
+ size_t len = 0;
+ /* This structure (ecdhparams.curve_params) comes from tls.lua */
+@@ -634,7 +622,7 @@ static int parse_ssl_cert(lua_State *L,
+ else
+ #endif
+ if (pkey_type == EVP_PKEY_RSA) {
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ RSA *rsa = EVP_PKEY_get1_RSA(pubkey);
+ if (rsa) {
+ #endif
+@@ -643,7 +631,7 @@ static int parse_ssl_cert(lua_State *L,
+ luaL_getmetatable( L, "BIGNUM" );
+ lua_setmetatable( L, -2 );
+ #if HAVE_OPAQUE_STRUCTS
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ const BIGNUM *n = NULL, *e = NULL;
+ data->should_free = false;
+ RSA_get0_key(rsa, &n, &e, NULL);
+@@ -663,7 +651,7 @@ static int parse_ssl_cert(lua_State *L,
+ luaL_getmetatable( L, "BIGNUM" );
+ lua_setmetatable( L, -2 );
+ #if HAVE_OPAQUE_STRUCTS
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ data->should_free = false;
+ #else
+ data->should_free = true;
+@@ -673,7 +661,7 @@ static int parse_ssl_cert(lua_State *L,
+ data->bn = rsa->n;
+ #endif
+ lua_setfield(L, -2, "modulus");
+-#if OPENSSL_API_LEVEL < 30000
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ RSA_free(rsa);
+ }
+ #endif
+--- a/nsock/src/nsock_ssl.c
++++ b/nsock/src/nsock_ssl.c
+@@ -64,7 +64,7 @@
+ #include "netutils.h"
+
+ #if HAVE_OPENSSL
+-#if OPENSSL_API_LEVEL >= 30000
++#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ #include <openssl/provider.h>
+ #endif
+
+@@ -120,7 +120,7 @@ static SSL_CTX *ssl_init_helper(const SS
+ SSL_library_init();
+ #else
+ OPENSSL_atexit(nsock_ssl_atexit);
+-#if OPENSSL_API_LEVEL >= 30000
++#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ if (NULL == OSSL_PROVIDER_load(NULL, "legacy"))
+ {
+ nsock_log_error("OpenSSL legacy provider failed to load.\n");
+--- a/nsock/src/nsock_ssl.h
++++ b/nsock/src/nsock_ssl.h
+@@ -69,20 +69,7 @@
+ #include <openssl/err.h>
+ #include <openssl/rand.h>
+
+-/* OPENSSL_API_LEVEL per OpenSSL 3.0: decimal MMmmpp */
+-#ifndef OPENSSL_API_LEVEL
+-# if OPENSSL_API_COMPAT < 0x900000L
+-# define OPENSSL_API_LEVEL (OPENSSL_API_COMPAT)
+-# else
+-# define OPENSSL_API_LEVEL \
+- (((OPENSSL_API_COMPAT >> 28) & 0xF) * 10000 \
+- + ((OPENSSL_API_COMPAT >> 20) & 0xFF) * 100 \
+- + ((OPENSSL_API_COMPAT >> 12) & 0xFF))
+-# endif
+-#endif
+-
+-
+-#if OPENSSL_API_LEVEL >= 30000
++#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ /* Deprecated in OpenSSL 3.0 */
+ #define SSL_get_peer_certificate SSL_get1_peer_certificate
+ #endif
+++ /dev/null
-#
-# Copyright (C) 2020-2021 CZ.NIC, z. s. p. o. (https://www.nic.cz/)
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=ooniprobe
-PKG_VERSION:=3.18.0
-PKG_RELEASE:=1
-
-PKG_SOURCE:=probe-cli-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/ooni/probe-cli/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=d28c050226c9282d7155da6cabf5547ddd43dc11eecacc485b6c05161c2d1d88
-
-PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com>
-PKG_LICENSE:=GPL-3.0-or-later
-PKG_LICENSE_FILES:=LICENSE
-
-PKG_BUILD_DIR:=$(BUILD_DIR)/probe-cli-$(PKG_VERSION)
-PKG_BUILD_DEPENDS:=golang/host
-PKG_BUILD_PARALLEL:=1
-PKG_BUILD_FLAGS:=no-mips16
-
-GO_PKG:=github.com/ooni/probe-cli
-GO_PKG_BUILD_PKG:=github.com/ooni/probe-cli/v3/cmd/ooniprobe
-
-include $(INCLUDE_DIR)/package.mk
-include ../../lang/golang/golang-package.mk
-
-define Package/ooniprobe
- SECTION:=net
- CATEGORY:=Network
- TITLE:=OONI probe-cli
- URL:=https://ooni.org
- DEPENDS:=$(GO_ARCH_DEPENDS)
-endef
-
-define Package/ooniprobe/description
- The next generation of Open Observatory of Network Interference (OONI)
- Probe Command Line Interface.
-endef
-
-# Workaround for musl 1.2.4 compability in mattn/go-sqlite3
-# https://github.com/mattn/go-sqlite3/issues/1164
-ifneq ($(CONFIG_USE_MUSL),)
- TARGET_CFLAGS += -D_LARGEFILE64_SOURCE
-endif
-
-$(eval $(call GoBinPackage,ooniprobe))
-$(eval $(call BuildPackage,ooniprobe))
+++ /dev/null
-#!/bin/sh
-
-ooniprobe version | grep "$2"
PKG_NAME:=openconnect
PKG_VERSION:=9.01
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=ftp://ftp.infradead.org/pub/openconnect/
proto_config_add_int "juniper"
proto_config_add_int "reconnect_timeout"
proto_config_add_string "vpn_protocol"
+ proto_config_add_boolean "pfs"
proto_config_add_boolean "no_dtls"
proto_config_add_string "interface"
proto_config_add_string "username"
os \
password \
password2 \
+ pfs \
port \
proxy \
reconnect_timeout \
[ -n "$port" ] && port=":$port"
append_args "$server$port" -i "$ifname" --non-inter --syslog --script /lib/netifd/vpnc-script
+ [ "$pfs" = 1 ] && append_args --pfs
[ "$no_dtls" = 1 ] && append_args --no-dtls
[ -n "$mtu" ] && append_args --mtu "$mtu"
PKG_NAME:=openthread-br
PKG_SOURCE_DATE:=2023-08-01
PKG_SOURCE_VERSION:=1738d8cd8b42106c2ef1262fbbac2f06beab83ba
-PKG_RELEASE:=2
+PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/openthread/ot-br-posix.git
-DOTBR_SRP_SERVER_AUTO_ENABLE:BOOL=ON \
-DOTBR_TREL:BOOL=ON
-TARGET_CFLAGS += -DOPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME=\\\"/var/run/openthread-%s\\\" \
- -I$(STAGING_DIR)/usr/include/mdns \
- -L$(STAGING_DIR)/usr/lib/mdns
+TARGET_CFLAGS += -DOPENTHREAD_POSIX_CONFIG_DAEMON_SOCKET_BASENAME=\\\"/var/run/openthread-%s\\\"
define Package/luci-app-openthread/install
$(INSTALL_DIR) \
define Package/openthread-br/install
$(INSTALL_DIR) \
+ $(1)/etc/init.d \
$(1)/lib/netifd/proto \
$(1)/usr/sbin \
$(1)/var/lib/thread
src/rest/resource.hpp | 1 +
3 files changed, 57 insertions(+)
+diff --git a/src/rest/openapi.yaml b/src/rest/openapi.yaml
+index 2ba2a4dd56..2edc4af29a 100644
--- a/src/rest/openapi.yaml
+++ b/src/rest/openapi.yaml
@@ -248,6 +248,18 @@ paths:
components:
schemas:
LeaderData:
+diff --git a/src/rest/resource.cpp b/src/rest/resource.cpp
+index a60e9d9483..829835341a 100644
--- a/src/rest/resource.cpp
+++ b/src/rest/resource.cpp
@@ -767,12 +767,47 @@ exit:
case HttpMethod::kGet:
GetDataset(aDatasetType, aRequest, aResponse);
break;
+diff --git a/src/rest/resource.hpp b/src/rest/resource.hpp
+index d79085dbfc..362e501471 100644
--- a/src/rest/resource.hpp
+++ b/src/rest/resource.hpp
@@ -150,6 +150,7 @@ private:
void DeleteOutDatedDiagnostic(void);
void UpdateDiag(std::string aKey, std::vector<otNetworkDiagTlv> &aDiag);
+--
+2.41.0
+
PKG_NAME:=openvpn
-PKG_VERSION:=2.6.6
+PKG_VERSION:=2.6.8
PKG_RELEASE:=1
PKG_SOURCE_URL:=\
https://build.openvpn.net/downloads/releases/ \
https://swupdate.openvpn.net/community/releases/
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_HASH:=3b074f392818b31aa529b84f76e8b5e4ad03fca764924f46d906bceaaf421034
+PKG_HASH:=5ede1565c8a6d880100f7f235317a7ee9eea83d5052db5547f13a9e76af7805d
PKG_MAINTAINER:=Magnus Kroken <mkroken@gmail.com>
--- a/src/openvpn/ssl_mbedtls.c
+++ b/src/openvpn/ssl_mbedtls.c
-@@ -1535,7 +1535,7 @@ const char *
+@@ -1533,7 +1533,7 @@ const char *
get_ssl_library_version(void)
{
static char mbedtls_version[30];
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
-@@ -51,7 +51,7 @@
+@@ -49,7 +49,7 @@
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/kdf.h>
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
-@@ -1436,7 +1436,7 @@ engine_load_key(const char *file, SSL_CT
- #endif /* if HAVE_OPENSSL_ENGINE */
+@@ -1374,7 +1374,7 @@ memcmp_constant_time(const void *a, cons
+ return CRYPTO_memcmp(a, b, size);
}
-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
-@@ -1351,7 +1351,7 @@ err:
+@@ -1347,7 +1347,7 @@ err:
return 0;
}
/* called when EC_KEY is destroyed */
static void
-@@ -1512,7 +1512,7 @@ tls_ctx_use_management_external_key(stru
+@@ -1508,7 +1508,7 @@ tls_ctx_use_management_external_key(stru
goto cleanup;
}
}
--- a/src/openvpn/ssl_verify_openssl.c
+++ b/src/openvpn/ssl_verify_openssl.c
-@@ -269,6 +269,9 @@ backend_x509_get_username(char *common_n
+@@ -267,6 +267,9 @@ backend_x509_get_username(char *common_n
return FAILURE;
}
}
include $(TOPDIR)/rules.mk
PKG_NAME:=pdns-recursor
-PKG_VERSION:=4.9.1
+PKG_VERSION:=4.9.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://downloads.powerdns.com/releases/
-PKG_HASH:=0a1edc13e8f2bd661f39e316387d941e22de6a03b8a7a2fc662fdf8b942ea2be
+PKG_HASH:=4cb8180458ecfb528a3d9a34ba2844b6cd2ed69ca1c461dde24a0ebd66829144
PKG_MAINTAINER:=Peter van Dijk <peter.van.dijk@powerdns.com>
PKG_LICENCE:=GPL-2.0-only
endef
define Package/pdns-recursor/conffiles
-/etc/powerdns/pdns-recursor.conf
+/etc/powerdns/recursor.conf
/etc/init.d/pdns-recursor
endef
include $(TOPDIR)/rules.mk
PKG_NAME:=pdns
-PKG_VERSION:=4.8.2
+PKG_VERSION:=4.8.3
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://downloads.powerdns.com/releases/
-PKG_HASH:=3b173fda4c51bb07b5a51d8c599eedd7962a02056b410e3c9d9d69ed97be35b9
+PKG_HASH:=77b91199bdf71874334501c67e26469c2667a373d8423803fe657417295c77ba
PKG_MAINTAINER:=Peter van Dijk <peter.van.dijk@powerdns.com>
PKG_LICENCE:=GPL-2.0-only
#
# default-api-rectify=yes
+#################################
+# default-catalog-zone Catalog zone to assign newly created primary zones (via the API) to
+#
+# default-catalog-zone=
+
#################################
# default-ksk-algorithm Default KSK algorithm
#
#
# secondary=no
+#################################
+# secondary-check-signature-freshness Check signatures in SOA freshness check. Sets DO flag on SOA queries. Outside some very problematic scenarios, say yes here.
+#
+# secondary-check-signature-freshness=yes
+
#################################
# secondary-do-renotify If this secondary should send out notifications after receiving zone transfers from a primary
#
# slave-renotify=no
#################################
-# socket-dir Where the controlsocket will live, /var/run/pdns when unset and not chrooted. Set to the RUNTIME_DIRECTORY environment variable when that variable has a value (e.g. under systemd).
+# socket-dir Where the controlsocket will live, /var/run/pdns when unset and not chrooted
#
# socket-dir=
#
# webserver-print-arguments=no
+#################################
+# workaround-11804 Workaround for issue 11804: send single RR per AXFR chunk
+#
+# workaround-11804=no
+
#################################
# write-pid Write a PID file
#
PKG_NAME:=pptpd
PKG_VERSION:=1.4.0
-PKG_RELEASE:=5
+PKG_RELEASE:=6
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/poptop
validate_pptpd_section() {
uci_load_validate pptpd service "$1" "$2" \
- 'enabled:uinteger' \
+ 'enabled:bool:1' \
'localip:string' \
'remoteip:string' \
'mppe:list(string):required no40 no56 stateless' \
- 'logwtmp:uinteger'
+ 'logwtmp:bool:0'
}
setup_login() {
include $(TOPDIR)/rules.mk
PKG_NAME:=privoxy
-PKG_VERSION:=3.0.33
-PKG_RELEASE:=4
+PKG_VERSION:=3.0.34
+PKG_RELEASE:=1
-PKG_SOURCE:=privoxy-$(PKG_VERSION)-stable-src.tar.gz
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-stable-src.tar.gz
PKG_SOURCE_URL:=@SF/ijbswa
-PKG_HASH:=04b104e70dac61561b9dd110684b250fafc8c13dbe437a60fae18ddd9a881fae
-PKG_BUILD_DIR:=$(BUILD_DIR)/privoxy-$(PKG_VERSION)-stable
+PKG_HASH:=e6ccbca1656f4e616b4657f8514e33a70f6697e9d7294356577839322a3c5d2c
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)-stable
PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
URL:=http://www.privoxy.org/
USERID:=privoxy=8118:privoxy=8118
MENU:=1
- DEPENDS:=+!PRIVOXY_no_pcre:libpcre +!PRIVOXY_no_pthread:libpthread +!PRIVOXY_no_zlib:zlib
+ DEPENDS:=+!PRIVOXY_no_pcre:libpcre2 +!PRIVOXY_no_pthread:libpthread +!PRIVOXY_no_zlib:zlib
endef
# shown in LuCI package description
--- /dev/null
+From 53748ca8ca3c893025be34dd4f104546fcbd0602 Mon Sep 17 00:00:00 2001
+From: Fabian Keil <fk@fabiankeil.de>
+Date: Sat, 17 Jun 2023 13:20:24 +0200
+Subject: [PATCH] Add pcre2 support
+
+This is currently expected to cause crashes on Windows
+when compiled with GUI support.
+
+Closes bug #935.
+Initial patch submitted by: Gagan Sidhu
+---
+ acconfig.h | 6 ++
+ actions.c | 8 +++
+ cgi.c | 9 ++-
+ client-tags.c | 5 ++
+ configure.in | 64 ++++++++++++++++-
+ pcrs.c | 148 +++++++++++++++++++++++++++++----------
+ pcrs.h | 40 +++++++----
+ project.h | 54 +++++++++-----
+ templates/show-status | 5 +-
+ urlmatch.c | 159 ++++++++++++++++++++++++++++++++++++++++++
+ urlmatch.h | 4 ++
+ w32log.c | 3 +
+ 12 files changed, 430 insertions(+), 75 deletions(-)
+
+--- a/acconfig.h
++++ b/acconfig.h
+@@ -225,11 +225,17 @@
+ /* Define if pcre.h must be included as <pcre/pcre.h>
+ */
+ #undef PCRE_H_IN_SUBDIR
++#undef PCRE2_H_IN_SUBDIR
++
++#undef HAVE_PCRE2
++#undef HAVE_PCRE2POSIX
+
+ /* Define if pcreposix.h must be included as <pcre/pcreposix.h>
+ */
+ #undef PCREPOSIX_H_IN_SUBDIR
+
++#undef PCRE2POSIX_H_IN_SUBDIR
++
+ @BOTTOM@
+
+ /*
+--- a/actions.c
++++ b/actions.c
+@@ -828,8 +828,12 @@ int update_action_bits_for_tag(struct cl
+ continue;
+ }
+
++#ifdef HAVE_PCRE2
++ if (pcre2_pattern_matches(b->url->pattern.tag_regex, tag))
++#else
+ /* and check if one of the tag patterns matches the tag, */
+ if (0 == regexec(b->url->pattern.tag_regex, tag, 0, NULL, 0))
++#endif
+ {
+ /* if it does, update the action bit map, */
+ if (merge_current_action(csp->action, b->action))
+@@ -884,7 +888,11 @@ jb_err check_negative_tag_patterns(struc
+ }
+ for (tag = csp->tags->first; NULL != tag; tag = tag->next)
+ {
++#ifdef HAVE_PCRE2
++ if (pcre2_pattern_matches(b->url->pattern.tag_regex, tag->str))
++#else
+ if (0 == regexec(b->url->pattern.tag_regex, tag->str, 0, NULL, 0))
++#endif
+ {
+ /*
+ * The pattern matches at least one tag, thus the action
+--- a/cgi.c
++++ b/cgi.c
+@@ -2023,7 +2023,7 @@ jb_err template_fill(char **template_ptr
+ char buf[BUFFER_SIZE];
+ char *tmp_out_buffer;
+ char *file_buffer;
+- size_t size;
++ size_t buffer_size, new_size;
+ int error;
+ const char *flags;
+
+@@ -2032,7 +2032,7 @@ jb_err template_fill(char **template_ptr
+ assert(exports);
+
+ file_buffer = *template_ptr;
+- size = strlen(file_buffer) + 1;
++ buffer_size = strlen(file_buffer) + 1;
+
+ /*
+ * Assemble pcrs joblist from exports map
+@@ -2082,7 +2082,10 @@ jb_err template_fill(char **template_ptr
+ }
+ else
+ {
+- error = pcrs_execute(job, file_buffer, size, &tmp_out_buffer, &size);
++ error = pcrs_execute(job, file_buffer, buffer_size, &tmp_out_buffer,
++ &new_size);
++
++ buffer_size = new_size;
+
+ pcrs_free_job(job);
+ if (NULL == tmp_out_buffer)
+--- a/client-tags.c
++++ b/client-tags.c
+@@ -43,6 +43,7 @@
+ #include "miscutil.h"
+ #include "errlog.h"
+ #include "parsers.h"
++#include "urlmatch.h"
+
+ struct client_specific_tag
+ {
+@@ -658,7 +659,11 @@ int client_tag_match(const struct patter
+
+ for (tag = tags->first; tag != NULL; tag = tag->next)
+ {
++#ifdef HAVE_PCRE2
++ if (pcre2_pattern_matches(pattern->pattern.tag_regex, tag->str))
++#else
+ if (0 == regexec(pattern->pattern.tag_regex, tag->str, 0, NULL, 0))
++#endif
+ {
+ log_error(LOG_LEVEL_TAGGING, "Client tag '%s' matches.", tag->str);
+ return 1;
+--- a/configure.in
++++ b/configure.in
+@@ -863,12 +863,47 @@ else
+ ])
+ fi
+
++AC_ARG_ENABLE(pcre2,
++[ --disable-pcre2 Don't try to use pcre2 even if it's available],
++[enableval2=$enableval],
++[enableval2=yes])
++if test $enableval2 = yes; then
++ try_pcre2=yes
++else
++ AC_MSG_WARN([Ignoring pcre2 even if it's available])
++ try_pcre2=no
++fi
++
++if test $try_pcre2 != no; then
+ dnl =================================================================
+ dnl Checks for libraries.
+ dnl =================================================================
+ dnl Note: Some systems may have the library but not the system header
+ dnl file, so we must check for both.
+ dnl Also check for correct version
++AC_CHECK_LIB(pcre2-8, pcre2_compile_8, [
++ AC_CHECK_HEADER(pcre2.h, [
++ AC_EGREP_HEADER(pcre2_pattern_info, pcre2.h,[have_pcre2=yes; AC_DEFINE(HAVE_PCRE2)], [AC_MSG_WARN([[pcre2 old version installed]]); have_pcre2=no])
++ ], [
++ AC_CHECK_HEADER(pcre2/pcre2.h, [
++ AC_EGREP_HEADER(pcre2_pattern_info, pcre2/pcre2.h, [have_pcre2=yes; AC_DEFINE(PCRE2_H_IN_SUBDIR)], [AC_MSG_WARN([[pcre2 old version installed]]); have_pcre2=no])
++ ], [have_pcre2=no])
++ ], [#define PCRE2_CODE_UNIT_WIDTH 8])
++], [have_pcre2=no])
++
++AC_CHECK_LIB(pcre2-posix, regcomp, [
++ AC_CHECK_HEADER(pcre2posix.h, [
++ AC_EGREP_HEADER(pcre2_regerror, pcre2posix.h, [have_pcre2posix=yes],[AC_MSG_WARN([[pcre2posix old version installed]]); have_pcre2posix=no])
++ ], [
++ AC_CHECK_HEADER(pcre/pcre2posix.h, [
++ AC_EGREP_HEADER(pcre2_regerror, pcre2/pcre2posix.h, [have_pcre2posix=yes; AC_DEFINE(PCRE2POSIX_H_IN_SUBDIR)],[AC_MSG_WARN([[pcre2posix old version installed]]); have_pcre2posix=no])
++ ], [have_pcre2posix=no])
++ ])
++], [have_pcre2posix=no], -lpcre2-8)
++fi
++
++if test $have_pcre2 = "no"; then
++
+ AC_CHECK_LIB(pcre, pcre_compile, [
+ AC_CHECK_HEADER(pcre.h, [
+ AC_EGREP_HEADER(pcre_fullinfo, pcre.h, [have_pcre=yes], [AC_MSG_WARN([[pcre old version installed]]); have_pcre=no])
+@@ -889,6 +924,7 @@ AC_CHECK_LIB(pcreposix, regcomp, [
+ ])
+ ], [have_pcreposix=no], -lpcre)
+
++fi
+ dnl ================================================================
+ dnl libpcrs is temporarily disabled.
+ dnl
+@@ -1095,6 +1131,31 @@ fi
+ # we don't need pcreposix, then link pcre dynamically; else
+ # build it and link statically
+ #
++
++#check for libpcre2 first. then regular pcre
++
++if test $have_pcre2 = "yes"; then
++ echo "using libpcre2"
++ STATIC_PCRE_ONLY=#
++ LIBS="$LIBS -lpcre2-8 -lpcre2-posix"
++ if test "$use_static_pcre" = "yes"; then
++ pcre_dyn=no
++ AC_DEFINE(PCRE_STATIC,1,[Define to statically link to pcre library on Windows.])
++# see /usr/i686-w64-mingw32/sys-root/mingw/include/pcre.h line 54
++# #if defined(_WIN32) && !defined(PCRE_STATIC)
++# # ifndef PCRE_EXP_DECL
++# # define PCRE_EXP_DECL extern __declspec(dllimport)
++# # endif
++# If you want to statically link a program against a PCRE library in the form of
++# a non-dll .a file, you must define PCRE_STATIC before including pcre.h or
++# pcrecpp.h, otherwise the pcre_malloc() and pcre_free() exported functions will
++# be declared __declspec(dllimport), with unwanted results.
++ else
++ pcre_dyn=yes
++ AC_DEFINE(FEATURE_DYNAMIC_PCRE,1,[Define to dynamically link to pcre.])
++ fi
++else
++
+ if test $have_pcre = "yes"; then
+ echo "using libpcre"
+ STATIC_PCRE_ONLY=#
+@@ -1116,7 +1177,8 @@ if test $have_pcre = "yes"; then
+ AC_DEFINE(FEATURE_DYNAMIC_PCRE,1,[Define to dynamically link to pcre.])
+ fi
+ else
+- AC_MSG_ERROR(pcre library not detected.)
++ AC_MSG_ERROR(Detected neither pcre2 nor pcre library.)
++fi
+ fi
+
+ AC_DEFINE(FEATURE_CONNECTION_KEEP_ALIVE)
+--- a/pcrs.c
++++ b/pcrs.c
+@@ -57,7 +57,7 @@
+ * Internal prototypes
+ */
+
+-static int pcrs_parse_perl_options(const char *optstring, int *flags);
++static int pcrs_parse_perl_options(const char *optstring, unsigned int *flags);
+ static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int trivialflag,
+ int capturecount, int *errptr);
+ static int is_hex_sequence(const char *sequence);
+@@ -83,25 +83,25 @@ const char *pcrs_strerror(const int erro
+ switch (error)
+ {
+ /* Passed-through PCRE error: */
+- case PCRE_ERROR_NOMEMORY: return "(pcre:) No memory";
++ case PCREn(ERROR_NOMEMORY): return "(pcre:) No memory";
+
+ /* Shouldn't happen unless PCRE or PCRS bug, or user messed with compiled job: */
+- case PCRE_ERROR_NULL: return "(pcre:) NULL code or subject or ovector";
+- case PCRE_ERROR_BADOPTION: return "(pcre:) Unrecognized option bit";
+- case PCRE_ERROR_BADMAGIC: return "(pcre:) Bad magic number in code";
++ case PCREn(ERROR_NULL): return "(pcre:) NULL code or subject or ovector";
++ case PCREn(ERROR_BADOPTION): return "(pcre:) Unrecognized option bit";
++ case PCREn(ERROR_BADMAGIC): return "(pcre:) Bad magic number in code";
++#if defined(PCRE_ERROR_UNKNOWN_NODE)
+ case PCRE_ERROR_UNKNOWN_NODE: return "(pcre:) Bad node in pattern";
+-
++#endif
+ /* Can't happen / not passed: */
+- case PCRE_ERROR_NOSUBSTRING: return "(pcre:) Fire in power supply";
+- case PCRE_ERROR_NOMATCH: return "(pcre:) Water in power supply";
++ case PCREn(ERROR_NOSUBSTRING): return "(pcre:) Fire in power supply";
++ case PCREn(ERROR_NOMATCH): return "(pcre:) Water in power supply";
+
+ #ifdef PCRE_ERROR_MATCHLIMIT
+ /*
+ * Only reported by PCRE versions newer than our own.
+ */
+- case PCRE_ERROR_MATCHLIMIT: return "(pcre:) Match limit reached";
++ case PCREn(ERROR_MATCHLIMIT): return "(pcre:) Match limit reached";
+ #endif /* def PCRE_ERROR_MATCHLIMIT */
+-
+ /* PCRS errors: */
+ case PCRS_ERR_NOMEM: return "(pcrs:) No memory";
+ case PCRS_ERR_CMDSYNTAX: return "(pcrs:) Syntax error while parsing command";
+@@ -111,16 +111,14 @@ const char *pcrs_strerror(const int erro
+ case PCRS_WARN_TRUNCATION:
+ return "(pcrs:) At least one variable was too big and has been truncated before compilation";
+
+- /*
+- * XXX: With the exception of PCRE_ERROR_MATCHLIMIT we
+- * only catch PCRE errors that can happen with our internal
+- * version. If Privoxy is linked against a newer
+- * PCRE version all bets are off ...
+- */
+ default:
++#ifdef HAVE_PCRE2
++ pcre2_get_error_message(error, (PCRE2_UCHAR8*)buf, sizeof(buf));
++#else
+ snprintf(buf, sizeof(buf),
+ "Error code %d. For details, check the pcre documentation.",
+ error);
++#endif
+ return buf;
+ }
+ }
+@@ -149,7 +147,7 @@ const char *pcrs_strerror(const int erro
+ * Returns : option integer suitable for pcre
+ *
+ *********************************************************************/
+-static int pcrs_parse_perl_options(const char *optstring, int *flags)
++static int pcrs_parse_perl_options(const char *optstring, unsigned int *flags)
+ {
+ size_t i;
+ int rc = 0;
+@@ -163,13 +161,13 @@ static int pcrs_parse_perl_options(const
+ {
+ case 'e': break; /* ToDo ;-) */
+ case 'g': *flags |= PCRS_GLOBAL; break;
+- case 'i': rc |= PCRE_CASELESS; break;
+- case 'm': rc |= PCRE_MULTILINE; break;
++ case 'i': rc |= PCREn(CASELESS); break;
++ case 'm': rc |= PCREn(MULTILINE); break;
+ case 'o': break;
+- case 's': rc |= PCRE_DOTALL; break;
+- case 'x': rc |= PCRE_EXTENDED; break;
++ case 's': rc |= PCREn(DOTALL); break;
++ case 'x': rc |= PCREn(EXTENDED); break;
+ case 'D': *flags |= PCRS_DYNAMIC; break;
+- case 'U': rc |= PCRE_UNGREEDY; break;
++ case 'U': rc |= PCREn(UNGREEDY); break;
+ case 'T': *flags |= PCRS_TRIVIAL; break;
+ default: break;
+ }
+@@ -471,7 +469,15 @@ pcrs_job *pcrs_free_job(pcrs_job *job)
+ else
+ {
+ next = job->next;
+- if (job->pattern != NULL) free(job->pattern);
++ if (job->pattern != NULL)
++ {
++#ifdef HAVE_PCRE2
++ pcre2_code_free(job->pattern);
++#else
++ free(job->pattern);
++#endif
++ }
++#ifndef HAVE_PCRE2
+ if (job->hints != NULL)
+ {
+ #ifdef PCRE_CONFIG_JIT
+@@ -480,6 +486,7 @@ pcrs_job *pcrs_free_job(pcrs_job *job)
+ free(job->hints);
+ #endif
+ }
++#endif
+ if (job->substitute != NULL)
+ {
+ if (job->substitute->text != NULL) free(job->substitute->text);
+@@ -626,10 +633,14 @@ pcrs_job *pcrs_compile_command(const cha
+ pcrs_job *pcrs_compile(const char *pattern, const char *substitute, const char *options, int *errptr)
+ {
+ pcrs_job *newjob;
+- int flags;
++ unsigned int flags;
+ int capturecount;
+- const char *error;
++#ifdef HAVE_PCRE2
++ int ret;
++#else
+ int pcre_study_options = 0;
++ const char *error;
++#endif
+
+ *errptr = 0;
+
+@@ -661,25 +672,43 @@ pcrs_job *pcrs_compile(const char *patte
+ /*
+ * Compile the pattern
+ */
++#ifdef HAVE_PCRE2
++ PCRE2_SIZE error_offset;
++ newjob->pattern = pcre2_compile((const unsigned char *)pattern,
++ PCRE2_ZERO_TERMINATED, (unsigned)newjob->options, errptr,
++ &error_offset, NULL);
++#else
+ newjob->pattern = pcre_compile(pattern, newjob->options, &error, errptr, NULL);
++#endif
+ if (newjob->pattern == NULL)
+ {
+ pcrs_free_job(newjob);
+ return NULL;
+ }
+
+-
+-#ifdef PCRE_STUDY_JIT_COMPILE
++#if defined(PCRE_STUDY_JIT_COMPILE) || defined(HAVE_PCRE2)
+ #ifdef DISABLE_PCRE_JIT_COMPILATION
+ #warning PCRE_STUDY_JIT_COMPILE is supported but Privoxy has been configured not to use it
+ #else
+ if (!(flags & PCRS_DYNAMIC))
+ {
++#ifdef HAVE_PCRE2
++ /* Try to enable JIT compilation but continue if it's unsupported. */
++ if ((ret = pcre2_jit_compile(newjob->pattern, PCRE2_JIT_COMPLETE)) &&
++ (ret != PCRE2_ERROR_JIT_BADOPTION))
++ {
++ *errptr = ret;
++ pcrs_free_job(newjob);
++ return NULL;
++ }
++#else
+ pcre_study_options = PCRE_STUDY_JIT_COMPILE;
++#endif
+ }
+ #endif
+ #endif
+
++#ifndef HAVE_PCRE2
+ /*
+ * Generate hints. This has little overhead, since the
+ * hints will be NULL for a boring pattern anyway.
+@@ -691,13 +720,17 @@ pcrs_job *pcrs_compile(const char *patte
+ pcrs_free_job(newjob);
+ return NULL;
+ }
+-
++#endif
+
+ /*
+ * Determine the number of capturing subpatterns.
+ * This is needed for handling $+ in the substitute.
+ */
++#ifdef HAVE_PCRE2
++ if (0 > (*errptr = pcre2_pattern_info(newjob->pattern, PCRE2_INFO_CAPTURECOUNT, &capturecount)))
++#else
+ if (0 > (*errptr = pcre_fullinfo(newjob->pattern, newjob->hints, PCRE_INFO_CAPTURECOUNT, &capturecount)))
++#endif
+ {
+ pcrs_free_job(newjob);
+ return NULL;
+@@ -809,14 +842,20 @@ int pcrs_execute_list(pcrs_job *joblist,
+ *********************************************************************/
+ int pcrs_execute(pcrs_job *job, const char *subject, size_t subject_length, char **result, size_t *result_length)
+ {
+- int offsets[3 * PCRS_MAX_SUBMATCHES],
+- offset,
++ int offset,
+ i, k,
+ matches_found,
+ submatches,
+ max_matches = PCRS_MAX_MATCH_INIT;
+ size_t newsize;
++#ifdef HAVE_PCRE2
+ pcrs_match *matches, *dummy;
++ pcre2_match_data *pcre2_matches;
++ size_t *offsets;
++#else
++ pcrs_match *matches, *dummy;
++ int offsets[3 * PCRS_MAX_SUBMATCHES];
++#endif
+ char *result_offset;
+
+ offset = i = 0;
+@@ -830,27 +869,38 @@ int pcrs_execute(pcrs_job *job, const ch
+ return(PCRS_ERR_BADJOB);
+ }
+
++#ifdef HAVE_PCRE2
++ if (NULL == (pcre2_matches = pcre2_match_data_create_from_pattern(job->pattern, NULL)))
++ {
++ return(PCRS_ERR_NOMEM);
++ }
++ offsets = pcre2_get_ovector_pointer(pcre2_matches);
++#endif
+ if (NULL == (matches = (pcrs_match *)malloc((size_t)max_matches * sizeof(pcrs_match))))
+ {
+ return(PCRS_ERR_NOMEM);
+ }
+ memset(matches, '\0', (size_t)max_matches * sizeof(pcrs_match));
+
+-
+ /*
+ * Find the pattern and calculate the space
+ * requirements for the result
+ */
+ newsize = subject_length;
+
++#ifdef HAVE_PCRE2
++ while ((submatches = pcre2_match(job->pattern, (const unsigned char *)subject,
++ subject_length, (size_t)offset, 0, pcre2_matches, NULL)) > 0)
++#else
+ while ((submatches = pcre_exec(job->pattern, job->hints, subject, (int)subject_length, offset, 0, offsets, 3 * PCRS_MAX_SUBMATCHES)) > 0)
++#endif
+ {
+ job->flags |= PCRS_SUCCESS;
+ matches[i].submatches = submatches;
+
+ for (k = 0; k < submatches; k++)
+ {
+- matches[i].submatch_offset[k] = offsets[2 * k];
++ matches[i].submatch_offset[k] = (int)offsets[2 * k];
+
+ /* Note: Non-found optional submatches have length -1-(-1)==0 */
+ matches[i].submatch_length[k] = (size_t)(offsets[2 * k + 1] - offsets[2 * k]);
+@@ -867,7 +917,7 @@ int pcrs_execute(pcrs_job *job, const ch
+ newsize += (size_t)offsets[0] * (size_t)job->substitute->backref_count[PCRS_MAX_SUBMATCHES];
+
+ /* chunk after match */
+- matches[i].submatch_offset[PCRS_MAX_SUBMATCHES + 1] = offsets[1];
++ matches[i].submatch_offset[PCRS_MAX_SUBMATCHES + 1] = (int)offsets[1];
+ matches[i].submatch_length[PCRS_MAX_SUBMATCHES + 1] = subject_length - (size_t)offsets[1] - 1;
+ newsize += (subject_length - (size_t)offsets[1]) * (size_t)job->substitute->backref_count[PCRS_MAX_SUBMATCHES + 1];
+
+@@ -894,12 +944,19 @@ int pcrs_execute(pcrs_job *job, const ch
+ break;
+ /* Go find the next one */
+ else
+- offset = offsets[1];
++ offset = (int)offsets[1];
+ }
+ /* Pass pcre error through if (bad) failure */
++#ifdef HAVE_PCRE2
++ if (submatches < PCRE2_ERROR_NOMATCH)
++#else
+ if (submatches < PCRE_ERROR_NOMATCH)
++#endif
+ {
+ free(matches);
++#ifdef HAVE_PCRE2
++ pcre2_match_data_free(pcre2_matches);
++#endif
+ return submatches;
+ }
+ matches_found = i;
+@@ -909,9 +966,19 @@ int pcrs_execute(pcrs_job *job, const ch
+ * Get memory for the result (must be freed by caller!)
+ * and append terminating null byte.
+ */
+- if ((*result = (char *)malloc(newsize + 1)) == NULL)
++ if ((*result = (char *)malloc(newsize + 1
++#ifdef HAVE_PCRE2
++ /*
++ * Work around to prevent invalid reads in the jit code.
++ */
++ + 16
++#endif
++ )) == NULL)
+ {
+ free(matches);
++#ifdef HAVE_PCRE2
++ pcre2_match_data_free(pcre2_matches);
++#endif
+ return PCRS_ERR_NOMEM;
+ }
+ else
+@@ -964,6 +1031,9 @@ int pcrs_execute(pcrs_job *job, const ch
+ memcpy(result_offset, subject + offset, subject_length - (size_t)offset);
+
+ *result_length = newsize;
++#ifdef HAVE_PCRE2
++ pcre2_match_data_free(pcre2_matches);
++#endif
+ free(matches);
+ return matches_found;
+
+@@ -1101,7 +1171,7 @@ char pcrs_get_delimiter(const char *stri
+ *********************************************************************/
+ char *pcrs_execute_single_command(const char *subject, const char *pcrs_command, int *hits)
+ {
+- size_t size;
++ size_t buffer_size, new_size;
+ char *result = NULL;
+ pcrs_job *job;
+
+@@ -1109,12 +1179,14 @@ char *pcrs_execute_single_command(const
+ assert(pcrs_command);
+
+ *hits = 0;
+- size = strlen(subject);
++ buffer_size = strlen(subject);
+
+ job = pcrs_compile_command(pcrs_command, hits);
+ if (NULL != job)
+ {
+- *hits = pcrs_execute(job, subject, size, &result, &size);
++ *hits = pcrs_execute(job, subject, buffer_size, &result, &new_size);
++ buffer_size = new_size;
++
+ if (*hits < 0)
+ {
+ freez(result);
+--- a/pcrs.h
++++ b/pcrs.h
+@@ -33,9 +33,18 @@
+ *********************************************************************/
+
+
++#ifdef HAVE_PCRE2
++#define PCRE2_CODE_UNIT_WIDTH 8
++#define PCREn(x) PCRE2_ ## x
++#ifndef _PCRE2_H
++#include <pcre2.h>
++#endif
++#else
++#define PCREn(x) PCRE_ ## x
+ #ifndef _PCRE_H
+ #include <pcre.h>
+ #endif
++#endif
+
+ /*
+ * Constants:
+@@ -55,22 +64,23 @@
+ * They are supposed to be handled together with PCRE error
+ * codes and have to start with an offset to prevent overlaps.
+ *
+- * PCRE 6.7 uses error codes from -1 to -21, PCRS error codes
+- * below -100 should be safe for a while.
++ * PCRE 6.7 uses error codes from -1 to -21,
++ * PCRE2 10.42 uses error codes from -66 to 101.
++ * PCRS error codes below -300 should be safe for a while.
+ */
+-#define PCRS_ERR_NOMEM -100 /* Failed to acquire memory. */
+-#define PCRS_ERR_CMDSYNTAX -101 /* Syntax of s///-command */
+-#define PCRS_ERR_STUDY -102 /* pcre error while studying the pattern */
+-#define PCRS_ERR_BADJOB -103 /* NULL job pointer, pattern or substitute */
+-#define PCRS_WARN_BADREF -104 /* Backreference out of range */
+-#define PCRS_WARN_TRUNCATION -105 /* At least one pcrs variable was too big,
++#define PCRS_ERR_NOMEM -300 /* Failed to acquire memory. */
++#define PCRS_ERR_CMDSYNTAX -301 /* Syntax of s///-command */
++#define PCRS_ERR_STUDY -302 /* pcre error while studying the pattern */
++#define PCRS_ERR_BADJOB -303 /* NULL job pointer, pattern or substitute */
++#define PCRS_WARN_BADREF -304 /* Backreference out of range */
++#define PCRS_WARN_TRUNCATION -305 /* At least one pcrs variable was too big,
+ * only the first part was used. */
+
+ /* Flags */
+-#define PCRS_GLOBAL 1 /* Job should be applied globally, as with perl's g option */
+-#define PCRS_TRIVIAL 2 /* Backreferences in the substitute are ignored */
+-#define PCRS_SUCCESS 4 /* Job did previously match */
+-#define PCRS_DYNAMIC 8 /* Job is dynamic (used to disable JIT compilation) */
++#define PCRS_GLOBAL 0x08000000u /* Job should be applied globally, as with perl's g option */
++#define PCRS_TRIVIAL 0x10000000u /* Backreferences in the substitute are ignored */
++#define PCRS_SUCCESS 0x20000000u /* Job did previously match */
++#define PCRS_DYNAMIC 0x40000000u /* Job is dynamic (used to disable JIT compilation) */
+
+
+ /*
+@@ -107,10 +117,14 @@ typedef struct {
+ /* A PCRS job */
+
+ typedef struct PCRS_JOB {
++#ifdef HAVE_PCRE2
++ pcre2_code *pattern;
++#else
+ pcre *pattern; /* The compiled pcre pattern */
+ pcre_extra *hints; /* The pcre hints for the pattern */
++#endif
+ int options; /* The pcre options (numeric) */
+- int flags; /* The pcrs and user flags (see "Flags" above) */
++ unsigned int flags; /* The pcrs and user flags (see "Flags" above) */
+ pcrs_substitute *substitute; /* The compiled pcrs substitute */
+ struct PCRS_JOB *next; /* Pointer for chaining jobs to joblists */
+ } pcrs_job;
+--- a/project.h
++++ b/project.h
+@@ -94,12 +94,38 @@
+ */
+
+ #ifdef STATIC_PCRE
++#ifdef HAVE_PCRE2
++# include "pcre2.h"
++# include "pcre2posix.h"
++#else
+ # include "pcre.h"
++# include "pcreposix.h"
++#endif
+ #else
+-# ifdef PCRE_H_IN_SUBDIR
+-# include <pcre/pcre.h>
++# ifdef HAVE_PCRE2
++# ifdef PCRE2_H_IN_SUBDIR
++# define PCRE2_CODE_UNIT_WIDTH 8
++# include <pcre2/pcre2.h>
++# else
++# define PCRE2_CODE_UNIT_WIDTH 8
++# include <pcre2.h>
++# endif
++# ifdef PCRE2POSIX_H_IN_SUBDIR
++# include <pcre2/pcre2posix.h>
++# else
++# include <pcre2posix.h>
++# endif
+ # else
+-# include <pcre.h>
++# ifdef PCRE_H_IN_SUBDIR
++# include <pcre/pcre.h>
++# else
++# include <pcre.h>
++# endif
++# ifdef PCREPOSIX_H_IN_SUBDIR
++# include <pcre/pcreposix.h>
++# else
++# include <pcreposix.h>
++# endif
+ # endif
+ #endif
+
+@@ -109,16 +135,6 @@
+ # include <pcrs.h>
+ #endif
+
+-#ifdef STATIC_PCRE
+-# include "pcreposix.h"
+-#else
+-# ifdef PCRE_H_IN_SUBDIR
+-# include <pcre/pcreposix.h>
+-# else
+-# include <pcreposix.h>
+-# endif
+-#endif
+-
+ #ifdef _WIN32
+ /*
+ * I don't want to have to #include all this just for the declaration
+@@ -404,10 +420,16 @@ struct http_response
+ enum crunch_reason crunch_reason; /**< Why the response was generated in the first place. */
+ };
+
++#ifdef HAVE_PCRE2
++#define REGEX_TYPE pcre2_code
++#else
++#define REGEX_TYPE regex_t
++#endif
++
+ struct url_spec
+ {
+ #ifdef FEATURE_PCRE_HOST_PATTERNS
+- regex_t *host_regex;/**< Regex for host matching */
++ REGEX_TYPE *host_regex;/**< Regex for host matching */
+ enum host_regex_type { VANILLA_HOST_PATTERN, PCRE_HOST_PATTERN } host_regex_type;
+ #endif /* defined FEATURE_PCRE_HOST_PATTERNS */
+ int dcount; /**< How many parts to this domain? (length of dvec) */
+@@ -417,7 +439,7 @@ struct url_spec
+
+ char *port_list; /**< List of acceptable ports, or NULL to match all ports */
+
+- regex_t *preg; /**< Regex for matching path part */
++ REGEX_TYPE *preg; /**< Regex for matching path part */
+ };
+
+ /**
+@@ -432,7 +454,7 @@ struct pattern_spec
+ union
+ {
+ struct url_spec url_spec;
+- regex_t *tag_regex;
++ REGEX_TYPE *tag_regex;
+ } pattern;
+
+ unsigned int flags; /**< Bitmap with various pattern properties. */
+--- a/templates/show-status
++++ b/templates/show-status
+@@ -298,10 +298,7 @@
+ <tr>
+ <td><code>FEATURE_DYNAMIC_PCRE</code></td>
+ <td>@if-FEATURE_DYNAMIC_PCRE-then@ Yes @else-not-FEATURE_DYNAMIC_PCRE@ No @endif-FEATURE_DYNAMIC_PCRE@</td>
+- <td>Dynamically link to the PCRE library. This is set automatically
+- by <code>./configure</code> if you do not have libpcre installed.
+- Dynamically linking to an external libpcre is recommended as the one that is distributed
+- with Privoxy itself is outdated and lacks various features and bug-fixes you may be interested in.</td>
++ <td>Dynamically link to the PCRE(2) library (recommended).</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_EXTENDED_STATISTICS</code></td>
+--- a/urlmatch.c
++++ b/urlmatch.c
+@@ -604,6 +604,100 @@ jb_err parse_http_request(const char *re
+ }
+
+
++#ifdef HAVE_PCRE2
++/*********************************************************************
++ *
++ * Function : compile_pattern
++ *
++ * Description : Compiles a host, domain or TAG pattern.
++ *
++ * Parameters :
++ * 1 : pattern = The pattern to compile.
++ * 2 : anchoring = How the regex should be modified
++ * before compilation. Can be either
++ * one of NO_ANCHORING, LEFT_ANCHORED,
++ * RIGHT_ANCHORED or RIGHT_ANCHORED_HOST.
++ * 3 : url = In case of failures, the spec member is
++ * logged and the structure freed.
++ * 4 : regex = Where the compiled regex should be stored.
++ *
++ * Returns : JB_ERR_OK - Success
++ * JB_ERR_PARSE - Cannot parse regex
++ *
++ *********************************************************************/
++static jb_err compile_pattern(const char *pattern, enum regex_anchoring anchoring,
++ struct pattern_spec *url, pcre2_code **regex)
++{
++ int errcode;
++ const char *fmt = NULL;
++ char *rebuf;
++ size_t rebuf_size;
++ PCRE2_SIZE error_offset;
++ int ret;
++
++ assert(pattern);
++
++ if (pattern[0] == '\0')
++ {
++ *regex = NULL;
++ return JB_ERR_OK;
++ }
++
++ switch (anchoring)
++ {
++ case NO_ANCHORING:
++ fmt = "%s";
++ break;
++ case RIGHT_ANCHORED:
++ fmt = "%s$";
++ break;
++ case RIGHT_ANCHORED_HOST:
++ fmt = "%s\\.?$";
++ break;
++ case LEFT_ANCHORED:
++ fmt = "^%s";
++ break;
++ default:
++ log_error(LOG_LEVEL_FATAL,
++ "Invalid anchoring in compile_pattern %d", anchoring);
++ }
++ rebuf_size = strlen(pattern) + strlen(fmt);
++ rebuf = malloc_or_die(rebuf_size);
++
++ snprintf(rebuf, rebuf_size, fmt, pattern);
++
++ *regex = pcre2_compile((const unsigned char *)pattern,
++ PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &errcode,
++ &error_offset, NULL);
++ if (*regex == NULL)
++ {
++ log_error(LOG_LEVEL_ERROR, "error compiling %s from %s: %s",
++ pattern, url->spec, rebuf);
++ freez(rebuf);
++
++ return JB_ERR_PARSE;
++ }
++
++#ifndef DISABLE_PCRE_JIT_COMPILATION
++ /* Try to enable JIT compilation but continue if it's unsupported. */
++ if ((ret = pcre2_jit_compile(*regex, PCRE2_JIT_COMPLETE)) &&
++ (ret != PCRE2_ERROR_JIT_BADOPTION))
++ {
++ log_error(LOG_LEVEL_ERROR,
++ "Unexpected error enabling JIT compilation for %s from %s: %s",
++ pattern, url->spec, rebuf);
++ freez(rebuf);
++
++ return JB_ERR_PARSE;
++ }
++#endif
++
++ freez(rebuf);
++
++ return JB_ERR_OK;
++
++}
++#else
+ /*********************************************************************
+ *
+ * Function : compile_pattern
+@@ -686,6 +780,7 @@ static jb_err compile_pattern(const char
+ return JB_ERR_OK;
+
+ }
++#endif
+
+
+ /*********************************************************************
+@@ -1051,6 +1146,49 @@ static int simplematch(const char *patte
+ }
+
+
++#ifdef HAVE_PCRE2
++/*********************************************************************
++ *
++ * Function : pcre2_pattern_matches
++ *
++ * Description : Checks if a compiled pcre2 pattern matches a string.
++ *
++ * Parameters :
++ * 1 : pattern = The compiled pattern
++ * 2 : string = The string to check
++ *
++ * Returns : TRUE for yes, FALSE otherwise.
++ *
++ *********************************************************************/
++int pcre2_pattern_matches(const pcre2_code *pattern, const char *string)
++{
++ PCRE2_SIZE offset;
++ int ret;
++ pcre2_match_data *pcre2_matches;
++
++ assert(pattern != NULL);
++ assert(string != NULL);
++
++ offset = 0;
++
++ pcre2_matches = pcre2_match_data_create_from_pattern(pattern, NULL);
++ if (NULL == pcre2_matches)
++ {
++ log_error(LOG_LEVEL_ERROR,
++ "Out of memory while matching pattern against %s", string);
++ return FALSE;
++ }
++
++ ret = pcre2_match(pattern, (const unsigned char *)string, strlen(string),
++ offset, 0, pcre2_matches, NULL);
++
++ pcre2_match_data_free(pcre2_matches);
++
++ return (ret >= 0);
++}
++#endif
++
++
+ /*********************************************************************
+ *
+ * Function : simple_domaincmp
+@@ -1268,8 +1406,12 @@ void free_pattern_spec(struct pattern_sp
+ {
+ if (pattern->pattern.tag_regex)
+ {
++#ifdef HAVE_PCRE2
++ pcre2_code_free(pattern->pattern.tag_regex);
++#else
+ regfree(pattern->pattern.tag_regex);
+ freez(pattern->pattern.tag_regex);
++#endif
+ }
+ return;
+ }
+@@ -1277,8 +1419,12 @@ void free_pattern_spec(struct pattern_sp
+ #ifdef FEATURE_PCRE_HOST_PATTERNS
+ if (pattern->pattern.url_spec.host_regex)
+ {
++#ifdef HAVE_PCRE2
++ pcre2_code_free(pattern->pattern.url_spec.host_regex);
++#else
+ regfree(pattern->pattern.url_spec.host_regex);
+ freez(pattern->pattern.url_spec.host_regex);
++#endif
+ }
+ #endif /* def FEATURE_PCRE_HOST_PATTERNS */
+ freez(pattern->pattern.url_spec.dbuffer);
+@@ -1287,8 +1433,12 @@ void free_pattern_spec(struct pattern_sp
+ freez(pattern->pattern.url_spec.port_list);
+ if (pattern->pattern.url_spec.preg)
+ {
++#ifdef HAVE_PCRE2
++ pcre2_code_free(pattern->pattern.url_spec.preg);
++#else
+ regfree(pattern->pattern.url_spec.preg);
+ freez(pattern->pattern.url_spec.preg);
++#endif
+ }
+ }
+
+@@ -1333,8 +1483,13 @@ static int host_matches(const struct htt
+ if (pattern->pattern.url_spec.host_regex_type == PCRE_HOST_PATTERN)
+ {
+ return ((NULL == pattern->pattern.url_spec.host_regex)
++#ifdef HAVE_PCRE2
++ || pcre2_pattern_matches(pattern->pattern.url_spec.host_regex,
++ http->host));
++#else
+ || (0 == regexec(pattern->pattern.url_spec.host_regex,
+ http->host, 0, NULL, 0)));
++#endif
+ }
+ #endif
+ return ((NULL == pattern->pattern.url_spec.dbuffer) || (0 == domain_match(pattern, http)));
+@@ -1357,7 +1512,11 @@ static int host_matches(const struct htt
+ static int path_matches(const char *path, const struct pattern_spec *pattern)
+ {
+ return ((NULL == pattern->pattern.url_spec.preg)
++#ifdef HAVE_PCRE2
++ || (pcre2_pattern_matches(pattern->pattern.url_spec.preg, path)));
++#else
+ || (0 == regexec(pattern->pattern.url_spec.preg, path, 0, NULL, 0)));
++#endif
+ }
+
+
+--- a/urlmatch.h
++++ b/urlmatch.h
+@@ -50,6 +50,10 @@ extern int url_requires_percent_encoding
+ extern int url_match(const struct pattern_spec *pattern,
+ const struct http_request *http);
+
++#ifdef HAVE_PCRE2
++extern int pcre2_pattern_matches(const pcre2_code *pattern, const char *string);
++#endif
++
+ extern jb_err create_pattern_spec(struct pattern_spec *url, char *buf);
+ extern void free_pattern_spec(struct pattern_spec *url);
+ extern int match_portlist(const char *portlist, int port);
+--- a/w32log.c
++++ b/w32log.c
+@@ -316,6 +316,9 @@ void TermLogWindow(void)
+ void LogCreatePatternMatchingBuffers(void)
+ {
+ int i;
++#ifdef HAVE_PCRE2
++#warning The win32 build of Privoxy is expected to crash when compiled with pcre2 support.
++#endif
+ for (i = 0; patterns_to_highlight[i].str != NULL; i++)
+ {
+ regcomp(&patterns_to_highlight[i].buffer, patterns_to_highlight[i].str, REG_ICASE);
--- /dev/null
+From 662426360b8d10202feabdcd3515d64ea8833798 Mon Sep 17 00:00:00 2001
+From: Fabian Keil <fk@fabiankeil.de>
+Date: Tue, 11 Jul 2023 06:22:16 +0200
+Subject: [PATCH] Add regex_matches() to reduce HAVE_PCRE2 ifdefs
+
+---
+ actions.c | 12 ++----------
+ client-tags.c | 6 +-----
+ urlmatch.c | 39 ++++++++++++++++++++++++++-------------
+ urlmatch.h | 4 +---
+ 4 files changed, 30 insertions(+), 31 deletions(-)
+
+--- a/actions.c
++++ b/actions.c
+@@ -828,12 +828,8 @@ int update_action_bits_for_tag(struct cl
+ continue;
+ }
+
+-#ifdef HAVE_PCRE2
+- if (pcre2_pattern_matches(b->url->pattern.tag_regex, tag))
+-#else
+ /* and check if one of the tag patterns matches the tag, */
+- if (0 == regexec(b->url->pattern.tag_regex, tag, 0, NULL, 0))
+-#endif
++ if (regex_matches(b->url->pattern.tag_regex, tag))
+ {
+ /* if it does, update the action bit map, */
+ if (merge_current_action(csp->action, b->action))
+@@ -888,11 +884,7 @@ jb_err check_negative_tag_patterns(struc
+ }
+ for (tag = csp->tags->first; NULL != tag; tag = tag->next)
+ {
+-#ifdef HAVE_PCRE2
+- if (pcre2_pattern_matches(b->url->pattern.tag_regex, tag->str))
+-#else
+- if (0 == regexec(b->url->pattern.tag_regex, tag->str, 0, NULL, 0))
+-#endif
++ if (regex_matches(b->url->pattern.tag_regex, tag->str))
+ {
+ /*
+ * The pattern matches at least one tag, thus the action
+--- a/client-tags.c
++++ b/client-tags.c
+@@ -659,11 +659,7 @@ int client_tag_match(const struct patter
+
+ for (tag = tags->first; tag != NULL; tag = tag->next)
+ {
+-#ifdef HAVE_PCRE2
+- if (pcre2_pattern_matches(pattern->pattern.tag_regex, tag->str))
+-#else
+- if (0 == regexec(pattern->pattern.tag_regex, tag->str, 0, NULL, 0))
+-#endif
++ if (regex_matches(pattern->pattern.tag_regex, tag->str))
+ {
+ log_error(LOG_LEVEL_TAGGING, "Client tag '%s' matches.", tag->str);
+ return 1;
+--- a/urlmatch.c
++++ b/urlmatch.c
+@@ -1160,7 +1160,7 @@ static int simplematch(const char *patte
+ * Returns : TRUE for yes, FALSE otherwise.
+ *
+ *********************************************************************/
+-int pcre2_pattern_matches(const pcre2_code *pattern, const char *string)
++static int pcre2_pattern_matches(const pcre2_code *pattern, const char *string)
+ {
+ PCRE2_SIZE offset;
+ int ret;
+@@ -1191,6 +1191,29 @@ int pcre2_pattern_matches(const pcre2_co
+
+ /*********************************************************************
+ *
++ * Function : regex_matches
++ *
++ * Description : Checks if a compiled regex pattern matches a string
++ * using either pcre2 or pcre1 code.
++ *
++ * Parameters :
++ * 1 : pattern = The compiled pattern
++ * 2 : string = The string to check
++ *
++ * Returns : TRUE for yes, FALSE otherwise.
++ *
++ *********************************************************************/
++int regex_matches(const REGEX_TYPE *pattern, const char *string)
++{
++#ifdef HAVE_PCRE2
++ return pcre2_pattern_matches(pattern, string);
++#else
++ return (0 == regexec(pattern, string, 0, NULL, 0));
++#endif
++}
++
++/*********************************************************************
++ *
+ * Function : simple_domaincmp
+ *
+ * Description : Domain-wise Compare fqdn's. The comparison is
+@@ -1483,13 +1506,7 @@ static int host_matches(const struct htt
+ if (pattern->pattern.url_spec.host_regex_type == PCRE_HOST_PATTERN)
+ {
+ return ((NULL == pattern->pattern.url_spec.host_regex)
+-#ifdef HAVE_PCRE2
+- || pcre2_pattern_matches(pattern->pattern.url_spec.host_regex,
+- http->host));
+-#else
+- || (0 == regexec(pattern->pattern.url_spec.host_regex,
+- http->host, 0, NULL, 0)));
+-#endif
++ || regex_matches(pattern->pattern.url_spec.host_regex, http->host));
+ }
+ #endif
+ return ((NULL == pattern->pattern.url_spec.dbuffer) || (0 == domain_match(pattern, http)));
+@@ -1512,11 +1529,7 @@ static int host_matches(const struct htt
+ static int path_matches(const char *path, const struct pattern_spec *pattern)
+ {
+ return ((NULL == pattern->pattern.url_spec.preg)
+-#ifdef HAVE_PCRE2
+- || (pcre2_pattern_matches(pattern->pattern.url_spec.preg, path)));
+-#else
+- || (0 == regexec(pattern->pattern.url_spec.preg, path, 0, NULL, 0)));
+-#endif
++ || regex_matches(pattern->pattern.url_spec.preg, path));
+ }
+
+
+--- a/urlmatch.h
++++ b/urlmatch.h
+@@ -50,9 +50,7 @@ extern int url_requires_percent_encoding
+ extern int url_match(const struct pattern_spec *pattern,
+ const struct http_request *http);
+
+-#ifdef HAVE_PCRE2
+-extern int pcre2_pattern_matches(const pcre2_code *pattern, const char *string);
+-#endif
++int regex_matches(const REGEX_TYPE *pattern, const char *string);
+
+ extern jb_err create_pattern_spec(struct pattern_spec *url, char *buf);
+ extern void free_pattern_spec(struct pattern_spec *url);
--- /dev/null
+From 7fb978c74a8a46bd105d9f0ced92a4be0c9647e6 Mon Sep 17 00:00:00 2001
+From: Fabian Keil <fk@fabiankeil.de>
+Date: Sun, 27 Aug 2023 12:13:48 +0200
+Subject: [PATCH] configure: Fix --disable-pcre2
+
+Previously it would result in neither pcre library being detected:
+
+ checking for getnameinfo... (cached) yes
+ configure: WARNING: Ignoring pcre2 even if it's available
+ test: =: unexpected operator
+ Enabling support for client-specific tags.
+ checking for zlibVersion in -lz... (cached) yes
+ Enabling compression support.
+ test: =: unexpected operator
+ test: =: unexpected operator
+ configure: error: Detected neither pcre2 nor pcre library.
+---
+ configure.in | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/configure.in
++++ b/configure.in
+@@ -872,6 +872,7 @@ if test $enableval2 = yes; then
+ else
+ AC_MSG_WARN([Ignoring pcre2 even if it's available])
+ try_pcre2=no
++ have_pcre2=no
+ fi
+
+ if test $try_pcre2 != no; then
--- /dev/null
+From e73b93ea9ad1f3e980bd78ed3ebf65dedbb598a2 Mon Sep 17 00:00:00 2001
+From: Fabian Keil <fk@fabiankeil.de>
+Date: Sun, 27 Aug 2023 12:26:02 +0200
+Subject: [PATCH] pcre2 compile_pattern(): Actually pass the anchored pattern
+ to pcre2_compile()
+
+Previously the un-anchoring pattern was compiled resulting
+in incorrect matches.
+
+For example requests to:
+
+ https://www.privoxy.org/user-manual/config.html
+
+were redirected because of the default.action section:
+
+ {+redirect{http://config.privoxy.org/}}
+ # Sticky Actions = +redirect{http://config.privoxy.org/}
+ # URL = http://www.privoxy.org/config
+ # Redirected URL = http://www.privoxy.org/config
+ # Redirect Destination = http://config.privoxy.org/
+ .privoxy.org/config
+
+As the path pattern is left-anchored it should not match.
+---
+ urlmatch.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/urlmatch.c
++++ b/urlmatch.c
+@@ -666,7 +666,7 @@ static jb_err compile_pattern(const char
+
+ snprintf(rebuf, rebuf_size, fmt, pattern);
+
+- *regex = pcre2_compile((const unsigned char *)pattern,
++ *regex = pcre2_compile((const unsigned char *)rebuf,
+ PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &errcode,
+ &error_offset, NULL);
+ if (*regex == NULL)
+++ /dev/null
-#
-# Copyright (C) 2016 Ben Rosser <rosser.bjr@gmail.com>
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=quassel-irssi
-PKG_SOURCE_DATE:=2017-11-30
-PKG_SOURCE_VERSION:=079be662dde374a383646256108a4974c2bc7796
-PKG_RELEASE:=3
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/phhusson/quassel-irssi/tar.gz/$(PKG_SOURCE_VERSION)?
-PKG_HASH:=c276a92a47f8edf5ae1d9db0e72a69d078f2f3f80e055853fc6d06099d898966
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION)
-
-PKG_MAINTAINER:=Ben Rosser <rosser.bjr@gmail.com>
-PKG_LICENSE:=GPL-3.0-or-later
-PKG_LICENSE_FILES:=core/COPYING
-
-PKG_BUILD_PARALLEL:=1
-PKG_INSTALL:=1
-
-include $(INCLUDE_DIR)/package.mk
-include $(INCLUDE_DIR)/nls.mk
-
-MAKE_PATH := core
-MAKE_VARS += SYSTEM_QUASSELC=1 IRSSI_CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" IRSSI_INCLUDE=$(STAGING_DIR)/usr/include/irssi
-
-define Package/quassel-irssi
- SECTION:=net
- CATEGORY:=Network
- DEPENDS:=+irssi +quasselc
- SUBMENU:=Instant Messaging
- URL:=https://github.com/phhusson/quassel-irssi
- TITLE:=An irssi plugin to connect to quassel core
-endef
-
-define Package/quassel-irssi/description
- An irssi plugin that supports connecting to a quassel core.
-endef
-
-define Package/quassel-irssi/install
- $(INSTALL_DIR) $(1)/usr/lib/irssi/modules/
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/irssi/modules/libquassel_core.so* $(1)/usr/lib/irssi/modules/
-endef
-
-$(eval $(call BuildPackage,quassel-irssi))
+++ /dev/null
---- a/core/Makefile
-+++ b/core/Makefile
-@@ -3,7 +3,7 @@ DESTDIR ?=
- LIBDIR ?= /usr/lib
-
- #IRSSI_INCLUDE:=/home/phh/irssi-0.8.16-rc1.phh/
--IRSSI_INCLUDE:=/usr/include/irssi/
-+IRSSI_INCLUDE?=/usr/include/irssi/
- IRSSI_LIB?=$(DESTDIR)/$(LIBDIR)/irssi
- IRSSI_CFLAGS+=-I$(IRSSI_INCLUDE)/src/
- IRSSI_CFLAGS+=-I$(IRSSI_INCLUDE)/src/core/
-@@ -28,7 +28,7 @@ else
- LDFLAGS += -lquasselc
- endif
-
--CFLAGS=-std=gnu11 -Wall -Wextra -Werror -g -O2 $(IRSSI_CFLAGS) $(QUASSELC_FLAGS) -Wmissing-prototypes -Wmissing-declarations
-+CFLAGS+=-std=gnu11 -Wall -Wextra -g $(IRSSI_CFLAGS) $(QUASSELC_FLAGS) -Wmissing-prototypes -Wmissing-declarations
-
- CFLAGS += $(SSL_CFLAGS)
- LDFLAGS+= $(SSL_LDLAGS)
+++ /dev/null
---- a/core/Makefile
-+++ b/core/Makefile
-@@ -49,7 +49,7 @@ irssi/network-openssl.o: CFLAGS:=$(IRSSI
- quasselc-connector.o: CFLAGS:=$(CFLAGS)
-
- $(TARGET): $(OBJECTS)
-- gcc -shared $^ -o $@ -lz $(LDFLAGS)
-+ $(CC) -shared $^ -o $@ -lz $(LDFLAGS)
-
- install: $(TARGET)
- $(INSTALL) -d $(IRSSI_LIB)/modules
+++ /dev/null
---- a/core/Makefile
-+++ b/core/Makefile
-@@ -25,7 +25,7 @@ ifndef SYSTEM_QUASSELC
- QUASSELC_FLAGS:=-Ilib
- else
- QUASSELC_FLAGS:=$(shell pkg-config --cflags quasselc)
-- LDFLAGS += -lquasselc
-+ LDFLAGS += $(shell pkg-config --libs quasselc)
- endif
-
- CFLAGS+=-std=gnu11 -Wall -Wextra -g $(IRSSI_CFLAGS) $(QUASSELC_FLAGS) -Wmissing-prototypes -Wmissing-declarations
+++ /dev/null
-From 19e810405789a35b92026b56ea49d01a3f544b07 Mon Sep 17 00:00:00 2001
-From: Pierre-Hugues Husson <phh@phh.me>
-Date: Tue, 17 Jan 2017 23:09:24 +0100
-Subject: [PATCH] Get compatible with potential irssi abi 8, and drop polling
-
----
- core/Makefile | 1 -
- core/quassel-net.c | 64 ++++++++++++++++++++++++++++++++++++++--------
- 2 files changed, 53 insertions(+), 10 deletions(-)
-
---- a/core/Makefile
-+++ b/core/Makefile
-@@ -16,7 +16,6 @@ SSL_CFLAGS=$(shell pkg-config --cflags o
- SSL_LDLAGS=$(shell pkg-config --libs openssl)
- OBJECTS:=quasselc-connector.o quassel-core.o
- OBJECTS+=quassel-net.o quassel-msgs.o quassel-cmds.o
--OBJECTS+=irssi/network-openssl.o
- OBJECTS+=quassel-fe-window.o quassel-fe-level.o quassel-cfg.o
-
- LDFLAGS ?=
---- a/core/quassel-net.c
-+++ b/core/quassel-net.c
-@@ -132,10 +132,10 @@ static SERVER_REC* quassel_server_init_c
- ret->got = 0;
- server_connect_ref(SERVER_CONNECT(conn));
-
-- if(conn->use_ssl) {
-+ if(conn->use_tls) {
- ret->ssl = 1;
- }
-- ret->connrec->use_ssl = 0;
-+ ret->connrec->use_tls = 0;
-
- ret->channels_join = quassel_irssi_channels_join;
- ret->send_message = quassel_irssi_send_message;
-@@ -161,12 +161,59 @@ void quassel_net_init(CHAT_PROTOCOL_REC*
- signal_add_first("server connected", (SIGNAL_FUNC) sig_connected);
- }
-
--GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server);
-+static void quassel_net_final_setup(SERVER_REC* server, GIOChannel *handle) {
-+ quassel_login(handle, server->connrec->nick, server->connrec->password);
-+ server->handle->handle = handle;
-+
-+ server->readtag =
-+ g_input_add(handle,
-+ G_INPUT_READ,
-+ (GInputFunction) quassel_parse_incoming, server);
-+}
-+
-+static void quassel_net_ssl_callback(SERVER_REC *server, GIOChannel *handle) {
-+ int error;
-+
-+ g_return_if_fail(IS_SERVER(server));
-+
-+ error = irssi_ssl_handshake(handle);
-+ if (error == -1) {
-+ server->connection_lost = TRUE;
-+ server_connect_failed(server, NULL);
-+ return;
-+ }
-+ if (error & 1) {
-+ if (server->connect_tag != -1)
-+ g_source_remove(server->connect_tag);
-+ server->connect_tag = g_input_add(handle, error == 1 ? G_INPUT_READ : G_INPUT_WRITE,
-+ (GInputFunction)
-+ quassel_net_ssl_callback,
-+ server);
-+ return;
-+ }
-+
-+ if (server->connect_tag != -1) {
-+ g_source_remove(server->connect_tag);
-+ server->connect_tag = -1;
-+ }
-+
-+ quassel_net_final_setup(server, handle);
-+}
-+
- void quassel_irssi_init_ack(void *arg) {
- Quassel_SERVER_REC *server = (Quassel_SERVER_REC*)arg;
-- if(!server->ssl)
-- goto login;
-- GIOChannel* ssl_handle = irssi_ssl_get_iochannel(server->handle->handle, 1337, SERVER(server));
-+ GIOChannel* ssl_handle = net_start_ssl((SERVER_REC*)server);
-+
-+ if(server->readtag != -1) {
-+ g_source_remove(server->readtag);
-+ server->readtag = -1;
-+ }
-+
-+ if(!server->ssl) {
-+ quassel_net_final_setup((SERVER_REC*)server, server->handle->handle);
-+ return;
-+ }
-+
- int error;
- //That's polling, and that's really bad...
- while( (error=irssi_ssl_handshake(ssl_handle)) & 1) {
-@@ -175,10 +222,7 @@ void quassel_irssi_init_ack(void *arg) {
- return;
- }
- }
-- server->handle->handle = ssl_handle;
--
--login:
-- quassel_login(server->handle->handle, server->connrec->nick, server->connrec->password);
-+ quassel_net_ssl_callback((SERVER_REC*)server, ssl_handle);
- }
-
- void quassel_irssi_init_nack(void *arg) {
include $(TOPDIR)/rules.mk
PKG_NAME:=rclone
-PKG_VERSION:=1.64.0
+PKG_VERSION:=1.65.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/rclone/rclone/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=3297838fdcf611a5ad605835f41c0e51031ce9f220c77a4ad0af6283b7805329
+PKG_HASH:=22a15cbc381bab351c0698c83c1666344a07e1bde39ba44f33b95c5fb22cfaf4
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=restic-rest-server
-PKG_VERSION:=0.11.0
-PKG_RELEASE:=2
+PKG_VERSION:=0.12.1
+PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/rest-server-$(PKG_VERSION)
PKG_SOURCE:=rest-server-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/restic/rest-server/tar.gz/v${PKG_VERSION}?
-PKG_HASH:=cd9b35ad2224244207a967ebbc78d84f4298d725e95c1fa9341ed95a350ea68f
+PKG_HASH:=cfbeb4a66cac6fc36b1cb11256f06c6e4fcc7a28c2ef590550adf1c199b9aa4b
PKG_LICENSE:=BSD-2-Clause
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=samba
-PKG_VERSION:=4.18.6
+PKG_VERSION:=4.18.8
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
http://www.nic.funet.fi/index/samba/pub/samba/stable/ \
http://samba.mirror.bit.nl/samba/ftp/stable/ \
https://download.samba.org/pub/samba/stable/
-PKG_HASH:=284c8a994ce989c87cd6808c390fcb9d00c36b21a0dc1a8a75474b67c9e715e7
+PKG_HASH:=4fb87bceaeb01d832a59046c197a044b7e8e8000581548b5d577a6cda03344d1
PKG_BUILD_FLAGS:=gc-sections
include $(TOPDIR)/rules.mk
PKG_NAME:=ser2net
-PKG_VERSION:=4.3.6
-PKG_RELEASE:=2
+PKG_VERSION:=4.5.0
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/ser2net
-PKG_HASH:=65515c7e9a5289167ae64c4032450904449a87ce20653241022af4f5db2e9510
+PKG_HASH:=6ee1b217aad026948fd17ea00c5ecf6e982de822384c4349118461ad83caa0da
PKG_LICENSE:=GPL-2.0-or-later
PKG_LICENSE_FILES:=COPYING
define Package/ser2net/conffiles
/etc/config/ser2net
-/etc/ser2net.conf
+/etc/ser2net.yaml
endef
define Package/ser2net/install
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ser2net $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/etc
- $(INSTALL_CONF) ./files/ser2net.conf $(1)/etc/
+ $(INSTALL_CONF) ./files/ser2net.yaml $(1)/etc/
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/ser2net.config $(1)/etc/config/ser2net
+++ /dev/null
-#
-# This is a minimal example configuration file for ser2net. For a version with
-# detailed comments and all possible configuration directives, please visit:
-# https://github.com/cminyard/ser2net/blob/master/ser2net.conf
-#
-# On OpenWrt/LEDE systems, this configuration serves as a base configuration.
-# During boot of the system, the UCI configuration file /etc/config/ser2net is
-# parsed and converted to additional configuration lines which are _appended_
-# to this file. The ser2net daemon is then started with the combined
-# configuration file /tmp/ser2net.conf.
-#
-# A basic service configuration line has the following format:
-# <network port>:<state>:<timeout>:<device>:<options>
-# network port
-# Name or number of the port to accept connections
-# from for this device. A port number may be of the form
-# [ipv4,|ipv6,][tcp,|udp,][host,]port, such as
-# 127.0.0.1,2000 or ipv4,tcp,localhost,2000. If the host is
-# specified, it will only bind to the IP address
-# specified. Otherwise it will bind to all the ports on the
-# machine. If ipv4 or ipv6 is specified, it will only bind
-# to that network type.
-#
-# state
-# Either raw or rawlp or telnet or off. off disables
-# the port from accepting connections. It can be
-# turned on later from the control port. raw enables
-# the port and transfers all data as-is between the
-# port and the long. rawlp enables the port and
-# transfers all input data to device, device is open
-# without any termios setting. It allow to use
-# /dev/lpX devices and printers connected to them.
-# telnet enables the port and runs the telnet proto-
-# col on the port to set up telnet parameters. This
-# is most useful for using telnet.
-#
-# timeout
-# The time (in seconds) before the port will be dis-
-# connected if there is no activity on it. A zero
-# value disables this function.
-#
-# device
-# The name of the device to connect to. This
-# must be in the form of /dev/<device>.
-#
-# options
-# Sets operational parameters for the serial port.
-# For a serial device (not IPMI SOL):
-# Options 300, 1200, 2400, 4800, 9600, 19200, 38400,
-# 57600, 115200 set the various baud rates. EVEN,
-# ODD, NONE (MARK and SPACE if supported) set the parity.
-# Note that MARK and SPACE are not available on all systems
-# or hardware, if it is not supported then it will be
-# silently set to ODD or EVEN parity.
-# 1STOPBIT, 2STOPBITS set
-# the number of stop bits. 5DATABITS, 6DATABITS,
-# 7DATABITS, 8DATABITS set the number of data bits.
-# [-]XONXOFF turns on (- off) XON/XOFF support.
-# [-]RTSCTS turns on (- off) hardware flow control,
-# [-]LOCAL turns off (- on) monitoring of the modem lines,
-# and [-]HANGUP_WHEN_DONE turns on (- off) lowering the
-# modem control lines when the connection is done.
-# [-]NOBREAK disables automatic setting of the break
-# setting of the serial port.
-#
-# The "[-]remctl" option allow remote control (ala RFC
-# 2217) of serial-port configuration.
-#
-# Example:
-# 5000:telnet:0:/dev/ttyAPP0:115200 8DATABITS NONE 1STOPBIT -XONXOFF -LOCAL -RTSCTS remctl
USE_PROCD=1
PROG=/usr/sbin/ser2net
-STATICCFGFILE="/etc/ser2net.conf"
-DYNAMICCFGFILE="/tmp/ser2net.conf"
+STATICCFGFILE="/etc/ser2net.yaml"
+DYNAMICCFGFILE="/tmp/ser2net.yaml"
list_cb_append() {
local var="$2"
local value="$1"
- local sep="${3:- }"
+ local sep="${3:-,}"
eval "export ${NO_EXPORT:+-n} -- \"$var=\${$var:+\${$var}\${value:+\$sep}}\$value\""
}
-append_bool() {
- local var="$1"
- local key="$2"
- local val="$3"
- local uc="$4"
- local s=""
-
- [ "$uc" -eq 1 ] && key=`echo "$key" | tr '[a-z]' '[A-Z]'`
- [ "$val" -eq 0 ] && s="-"
-
- append "$var" "$s$key"
-}
-
ser2net_default() {
local cfg="$1"
local key val
+ local baudrate parity databits stopbits
+
+ config_get baudrate "$cfg" speed
+ if [ -n "$baudrate" ]; then
+ config_get parity "$cfg" parity
+ case "$parity" in
+ [Nn]one) parity=n ;;
+ [Oo]dd) parity=o ;;
+ [Ee]ven) parity=e ;;
+ "") ;;
+ *) return 1
+ esac
+
+ if [ -n "$parity" ]; then
+ config_get databits "$cfg" databits 8
+ [ "$databits" -ge 5 ] && [ "$databits" -le 9 ] || return 1
+
+ config_get stopbits "$cfg" stopbits 1
+ case "$stopbits" in
+ 1) ;;
+ 2) ;;
+ *) return 1
+ esac
+ fi
+
+ echo "default:"
+ echo " name: speed"
+ echo " value: $baudrate${parity:+$parity$databits$stopbits}"
+ fi
- for key in speed baudrate databits stopbits parity chardelay_scale chardelay_min; do
+ for key in chardelay_scale chardelay_min; do
config_get val "$cfg" "$key"
[ -n "$val" ] || continue
-
- case "$key" in
- baudrate) key="speed" ;;
- hangup_when_done) ;;
- telnet_brk_on_sync) ;;
- deassert_CTS_DCD_DSR_on_connect) ;;
- *) key=`echo "$key" | tr '_' '-'`
- esac
-
- echo "DEFAULT:$key:$val"
+ key=`echo "$key" | tr '_' '-'`
+ echo "default:"
+ echo " name: $key"
+ echo " value: $val"
done
for key in chardelay deassert_CTS_DCD_DSR_on_connect hangup_when_done kickolduser \
local nobreak remctl rtscts telnet_brk_on_sync xonxoff; do
+ case "$key" in
+ remctl) key=rfc2217 ;;
+ esac
config_get_bool val "$cfg" "$key"
[ -n "$val" ] || continue
+ key=`echo "$key" | tr '_' '-'`
[ "$val" -eq 0 ] && val="false" || val="true"
- echo "DEFAULT:$key:$val"
+ echo "default:"
+ echo " name: $key"
+ echo " value: $val"
done
echo
config_get host "$cfg" host
config_get port "$cfg" port
+ [ "$port" -ge 1 ] && [ "$port" -le 65535 ] || return 1
+
+ echo "admin:"
+ echo " accepter: tcp,${host:+$host,}$port"
- echo -e "CONTROLPORT:${host:+$host,}$port\n"
+ echo
}
ser2net_led() {
config_get driver "$cfg" driver sysfs
config_get device "$cfg" device
- config_get state "$cfg" state 1
- config_get duration "$cfg" duration 20
+ [ -z "$device" ] && return 1
+ config_get duration "$cfg" duration
+ config_get state "$cfg" state
+
+ echo "led: &$cfg"
+ echo " driver: $driver"
+ echo " options:"
+ echo " device: \"$device\""
+ [ -n "$duration" ] && echo " duration: $duration"
+ [ -n "$state" ] && echo " state: $state"
- echo -e "LED:$cfg:$driver:device=$device state=$state duration=$duration\n"
+ echo
}
ser2net_proxy() {
local cfg="$1"
local enabled port protocol timeout device baudrate databits parity stopbits
- local led_tx led_rx key boolval options
+ local key boolval options custom_options
+ local echo_options=1
config_get_bool enabled "$cfg" enabled 0
- [ "$enabled" -eq 0 ] && return 0
+
+ config_get device "$cfg" device
+ [ -z "$device" ] && return 1
config_get port "$cfg" port
- [ "$port" -le 0 -o "$port" -gt 65535 ] && return 1
+ [ "$port" -ge 1 ] && [ "$port" -le 65535 ] || return 1
config_get protocol "$cfg" protocol
case "$protocol" in
- raw|rawlp|telnet|off) ;;
+ raw)
+ protocol="tcp"
+ ;;
+ rawlp)
+ protocol="tcp"
+ options="wronly"
+ ;;
+ telnet)
+ protocol="telnet,tcp"
+
+ config_get_bool boolval "$cfg" remctl 0
+ [ "$boolval" -eq 1 ] && protocol="telnet(rfc2217),tcp"
+ ;;
+ off)
+ enabled=0
+ ;;
*) return 1
esac
- config_get timeout "$cfg" timeout 0
- config_get device "$cfg" device
- [ -z "$device" ] && return 1
-
config_get baudrate "$cfg" baudrate
- [ -n "$baudrate" ] && append options "$baudrate"
+ if [ -n "$baudrate" ]; then
+ config_get parity "$cfg" parity
+ case "$parity" in
+ [Nn]one) parity=n ;;
+ [Oo]dd) parity=o ;;
+ [Ee]ven) parity=e ;;
+ "") ;;
+ *) return 1
+ esac
- config_get databits "$cfg" databits
- if [ -n "$databits" ]; then
- [ "$databits" -lt 5 -o "$databits" -gt 8 ] && return 1
- append options "${databits}DATABITS"
+ if [ -n "$parity" ]; then
+ config_get databits "$cfg" databits 8
+ [ "$databits" -ge 5 ] && [ "$databits" -le 9 ] || return 1
+
+ config_get stopbits "$cfg" stopbits 1
+ case "$stopbits" in
+ 1) ;;
+ 2) ;;
+ *) return 1
+ esac
+ fi
fi
- config_get parity "$cfg" parity
- parity=`echo "$parity" | tr '[a-z]' '[A-Z]'`
- case "$parity" in
- EVEN|ODD|NONE|MARK|SPACE) append options "$parity" ;;
- "") ;;
- *) return 1
- esac
-
- config_get stopbits "$cfg" stopbits
- case "$stopbits" in
- 1) append options "${stopbits}STOPBIT" ;;
- 2) append options "${stopbits}STOPBITS" ;;
- "") ;;
- *) return 1
- esac
-
- config_get led_tx "$cfg" led_tx
- [ -n "$led_tx" ] && append options "led-tx=$led_tx"
-
- config_get led_rx "$cfg" led_rx
- [ -n "$led_rx" ] && append options "led-rx=$led_rx"
+ config_get timeout "$cfg" timeout 0
for key in rtscts local xonxoff nobreak hangup_when_done; do
config_get_bool boolval "$cfg" "$key"
[ -n "$boolval" ] || continue
- append_bool options "$key" "$boolval" 1
+ key=`echo "$key" | tr '_' '-'`
+ options="${options:+$options,}$key"
+ [ "$boolval" -eq 0 ] && options="$options=false"
+ done
+
+ config_list_foreach "$cfg" options list_cb_append custom_options
+
+ echo "connection: &$cfg"
+ echo " accepter: $protocol,$port"
+ echo " timeout: $timeout"
+ [ "$enabled" -eq 0 ] && echo " enable: off"
+ echo " connector: serialdev,$device${baudrate:+,$baudrate${parity:+$parity$databits$stopbits}}${options:+,$options}${custom_options:+,$custom_options}"
+
+ for key in led_tx led_rx; do
+ config_get val "$cfg" "$key"
+ [ -n "$val" ] || continue
+ [ "$echo_options" -eq 1 ] && echo " options:" && echo_options=0
+ key=`echo "$key" | tr '_' '-'`
+ echo " $key: *$val"
done
- for key in chardelay telnet_brk_on_sync kickolduser remctl; do
+ for key in chardelay telnet_brk_on_sync kickolduser; do
config_get_bool boolval "$cfg" "$key"
[ -n "$boolval" ] || continue
- append_bool options "$key" "$boolval" 0
+ [ "$echo_options" -eq 1 ] && echo " options:" && echo_options=0
+ key=`echo "$key" | tr '_' '-'`
+ echo " $key: $boolval"
done
- config_list_foreach "$cfg" options list_cb_append options
-
- if [ "`echo "$device" | sed 's/://g'`" != "$device" ]; then
- echo "DEVICE:$cfg:$device"
- device="$cfg"
- fi
-
- echo -e "$port:$protocol:$timeout:$device:$options\n"
+ echo
}
start_service() {
[ "$enabled" -gt 0 ] || return 0
cat "$STATICCFGFILE" - 2>/dev/null <<-EOF > "$DYNAMICCFGFILE"
-
+
#
# Following part is auto-generated from UCI settings in /etc/config/ser2net
#
EOF
- config_foreach ser2net_controlport controlport >> "$DYNAMICCFGFILE"
config_foreach ser2net_default default >> "$DYNAMICCFGFILE"
config_foreach ser2net_led led >> "$DYNAMICCFGFILE"
+ config_foreach ser2net_controlport controlport >> "$DYNAMICCFGFILE"
config_foreach ser2net_proxy proxy >> "$DYNAMICCFGFILE"
procd_open_instance
--- /dev/null
+# This is a minimal example configuration file for ser2net. For a version with
+# detailed comments and all possible configuration directives, please visit:
+# https://github.com/cminyard/ser2net/blob/master/ser2net.yaml
+#
+# On OpenWrt/LEDE systems, this configuration serves as a base configuration.
+# During boot of the system, the UCI configuration file /etc/config/ser2net is
+# parsed and converted to additional configuration lines which are _appended_
+# to this file. The ser2net daemon is then started with the combined
+# configuration file /tmp/ser2net.yaml.
+
+++ /dev/null
---- a/configure.ac
-+++ b/configure.ac
-@@ -39,7 +39,7 @@ AC_ARG_WITH(pam,
- fi,
- )
-
--if test "use_pam" != "no"; then
-+if test "$use_pam" != "no"; then
- have_pam=yes
- AC_CHECK_HEADER(security/pam_appl.h, [], [have_pam=no])
- if test "$have_pam" = "yes"; then
#
PKG_NAME:=shadowsocks-libev
PKG_VERSION:=3.3.5
-PKG_RELEASE:=9
+PKG_RELEASE:=10
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-libev/releases/download/v$(PKG_VERSION)
PKG_INSTALL:=1
PKG_BUILD_FLAGS:=no-mips16 lto
PKG_BUILD_PARALLEL:=1
-PKG_BUILD_DEPENDS:=c-ares pcre
+PKG_BUILD_DEPENDS:=c-ares pcre2
include $(INCLUDE_DIR)/package.mk
endef
-DEPENDS_ss-local = +libpcre
-DEPENDS_ss-server = +libcares +libpcre
+DEPENDS_ss-local = +libpcre2
+DEPENDS_ss-server = +libcares +libpcre2
SHADOWSOCKS_COMPONENTS:=ss-local ss-redir ss-tunnel ss-server
define shadowsocks-libev/templates
--- /dev/null
+From d4f4d9761cbd41c3ab6de79383ff39b9f97bf452 Mon Sep 17 00:00:00 2001
+From: Syrone Wong <wong.syrone@gmail.com>
+Date: Sat, 18 Nov 2017 20:06:50 +0800
+Subject: [PATCH] Upgrade PCRE to PCRE2
+
+- Use 8bit variant by default
+
+This comes from a PR closed and never reopen as at times PCRE2 was too
+new(???.)
+
+Ref: https://github.com/shadowsocks/shadowsocks-libev/pull/1792
+Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
+[ squash the first 2 patch from PR, drop the last one ]
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ .travis.yml | 9 ++-
+ configure.ac | 8 +--
+ m4/pcre.m4 | 152 ------------------------------------------
+ m4/pcre2.m4 | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/rule.c | 53 ++++++++++++---
+ src/rule.h | 23 +++++--
+ 6 files changed, 253 insertions(+), 173 deletions(-)
+ delete mode 100644 m4/pcre.m4
+ create mode 100644 m4/pcre2.m4
+
+# diff --git a/.travis.yml b/.travis.yml
+# index ee3424c..e7da08c 100644
+# --- a/.travis.yml
+# +++ b/.travis.yml
+# @@ -11,11 +11,12 @@ env:
+# global:
+# - LIBSODIUM_VER=1.0.12
+# - MBEDTLS_VER=2.4.0
+# + - PCRE2_VER=10.30
+# before_install:
+# - |
+# if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
+# # All dependencies for macOS build. Some packages has been installed by travis so use reinstall.
+# - brew reinstall autoconf automake xmlto c-ares libev mbedtls libsodium asciidoc >> /dev/null 2>&1;
+# + brew reinstall autoconf automake xmlto pcre2 c-ares libev mbedtls libsodium asciidoc >> /dev/null 2>&1;
+# else
+# wget https://github.com/jedisct1/libsodium/releases/download/$LIBSODIUM_VER/libsodium-$LIBSODIUM_VER.tar.gz;
+# tar xvf libsodium-$LIBSODIUM_VER.tar.gz;
+# @@ -29,6 +30,12 @@ before_install:
+# make SHARED=1;
+# sudo make install;
+# popd;
+# + wget https://ftp.pcre.org/pub/pcre/pcre2-$PCRE2_VER.tar.gz;
+# + tar xvf pcre2-$PCRE2_VER.tar.gz;
+# + pushd pcre2-$PCRE2_VER;
+# + ./configure --prefix=/usr --enable-pcre2-16 --enable-pcre2-32 && make;
+# + sudo make install;
+# + popd;
+# # Load cached docker images
+# if [[ -d $HOME/docker ]]; then
+# ls $HOME/docker/*.tar.gz | xargs -I {file} sh -c "zcat {file} | docker load";
+--- a/configure.ac
++++ b/configure.ac
+@@ -20,10 +20,10 @@ AC_DISABLE_STATIC
+ AC_DISABLE_SHARED
+ LT_INIT([dlopen])
+
+-dnl Check for pcre library
+-TS_CHECK_PCRE
+-if test "x${enable_pcre}" != "xyes"; then
+- AC_MSG_ERROR([Cannot find pcre library. Configure --with-pcre=DIR])
++dnl Check for pcre2 library
++TS_CHECK_PCRE2
++if test "x${enable_pcre2}" != "xyes"; then
++ AC_MSG_ERROR([Cannot find pcre2 library. Configure --with-pcre2=DIR])
+ fi
+
+ dnl Checks for using shared libraries from system
+--- a/m4/pcre.m4
++++ /dev/null
+@@ -1,152 +0,0 @@
+-dnl -------------------------------------------------------- -*- autoconf -*-
+-dnl Licensed to the Apache Software Foundation (ASF) under one or more
+-dnl contributor license agreements. See the NOTICE file distributed with
+-dnl this work for additional information regarding copyright ownership.
+-dnl The ASF licenses this file to You under the Apache License, Version 2.0
+-dnl (the "License"); you may not use this file except in compliance with
+-dnl the License. You may obtain a copy of the License at
+-dnl
+-dnl http://www.apache.org/licenses/LICENSE-2.0
+-dnl
+-dnl Unless required by applicable law or agreed to in writing, software
+-dnl distributed under the License is distributed on an "AS IS" BASIS,
+-dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-dnl See the License for the specific language governing permissions and
+-dnl limitations under the License.
+-
+-dnl
+-dnl TS_ADDTO(variable, value)
+-dnl
+-dnl Add value to variable
+-dnl
+-AC_DEFUN([TS_ADDTO], [
+- if test "x$$1" = "x"; then
+- test "x$verbose" = "xyes" && echo " setting $1 to \"$2\""
+- $1="$2"
+- else
+- ats_addto_bugger="$2"
+- for i in $ats_addto_bugger; do
+- ats_addto_duplicate="0"
+- for j in $$1; do
+- if test "x$i" = "x$j"; then
+- ats_addto_duplicate="1"
+- break
+- fi
+- done
+- if test $ats_addto_duplicate = "0"; then
+- test "x$verbose" = "xyes" && echo " adding \"$i\" to $1"
+- $1="$$1 $i"
+- fi
+- done
+- fi
+-])dnl
+-
+-dnl
+-dnl TS_ADDTO_RPATH(path)
+-dnl
+-dnl Adds path to variable with the '-rpath' directive.
+-dnl
+-AC_DEFUN([TS_ADDTO_RPATH], [
+- AC_MSG_NOTICE([adding $1 to RPATH])
+- TS_ADDTO(LIBTOOL_LINK_FLAGS, [-R$1])
+-])dnl
+-
+-dnl
+-dnl pcre.m4: Trafficserver's pcre autoconf macros
+-dnl
+-
+-dnl
+-dnl TS_CHECK_PCRE: look for pcre libraries and headers
+-dnl
+-AC_DEFUN([TS_CHECK_PCRE], [
+-enable_pcre=no
+-AC_ARG_WITH(pcre, [AC_HELP_STRING([--with-pcre=DIR],[use a specific pcre library])],
+-[
+- if test "x$withval" != "xyes" && test "x$withval" != "x"; then
+- pcre_base_dir="$withval"
+- if test "$withval" != "no"; then
+- enable_pcre=yes
+- case "$withval" in
+- *":"*)
+- pcre_include="`echo $withval |sed -e 's/:.*$//'`"
+- pcre_ldflags="`echo $withval |sed -e 's/^.*://'`"
+- AC_MSG_CHECKING(checking for pcre includes in $pcre_include libs in $pcre_ldflags )
+- ;;
+- *)
+- pcre_include="$withval/include"
+- pcre_ldflags="$withval/lib"
+- AC_MSG_CHECKING(checking for pcre includes in $withval)
+- ;;
+- esac
+- fi
+- fi
+-],
+-[
+- AC_CHECK_PROG(PCRE_CONFIG, pcre-config, pcre-config)
+- if test "x$PCRE_CONFIG" != "x"; then
+- enable_pcre=yes
+- pcre_base_dir="`$PCRE_CONFIG --prefix`"
+- pcre_include="`$PCRE_CONFIG --cflags | sed -es/-I//`"
+- pcre_ldflags="`$PCRE_CONFIG --libs | sed -es/-lpcre// -es/-L//`"
+- fi
+-])
+-
+-if test "x$pcre_base_dir" = "x"; then
+- AC_MSG_CHECKING([for pcre location])
+- AC_CACHE_VAL(ats_cv_pcre_dir,[
+- for dir in /usr/local /usr ; do
+- if test -d $dir && ( test -f $dir/include/pcre.h || test -f $dir/include/pcre/pcre.h ); then
+- ats_cv_pcre_dir=$dir
+- break
+- fi
+- done
+- ])
+- pcre_base_dir=$ats_cv_pcre_dir
+- if test "x$pcre_base_dir" = "x"; then
+- enable_pcre=no
+- AC_MSG_RESULT([not found])
+- else
+- enable_pcre=yes
+- pcre_include="$pcre_base_dir/include"
+- pcre_ldflags="$pcre_base_dir/lib"
+- AC_MSG_RESULT([$pcre_base_dir])
+- fi
+-else
+- AC_MSG_CHECKING(for pcre headers in $pcre_include)
+- if test -d $pcre_include && test -d $pcre_ldflags && ( test -f $pcre_include/pcre.h || test -f $pcre_include/pcre/pcre.h ); then
+- AC_MSG_RESULT([ok])
+- else
+- AC_MSG_RESULT([not found])
+- fi
+-fi
+-
+-pcreh=0
+-pcre_pcreh=0
+-if test "$enable_pcre" != "no"; then
+- saved_ldflags=$LDFLAGS
+- saved_cppflags=$CFLAGS
+- pcre_have_headers=0
+- pcre_have_libs=0
+- if test "$pcre_base_dir" != "/usr"; then
+- TS_ADDTO(CFLAGS, [-I${pcre_include}])
+- TS_ADDTO(CFLAGS, [-DPCRE_STATIC])
+- TS_ADDTO(LDFLAGS, [-L${pcre_ldflags}])
+- TS_ADDTO_RPATH(${pcre_ldflags})
+- fi
+- AC_SEARCH_LIBS([pcre_exec], [pcre], [pcre_have_libs=1])
+- if test "$pcre_have_libs" != "0"; then
+- AC_CHECK_HEADERS(pcre.h, [pcre_have_headers=1])
+- AC_CHECK_HEADERS(pcre/pcre.h, [pcre_have_headers=1])
+- fi
+- if test "$pcre_have_headers" != "0"; then
+- AC_DEFINE(HAVE_LIBPCRE,1,[Compiling with pcre support])
+- AC_SUBST(LIBPCRE, [-lpcre])
+- else
+- enable_pcre=no
+- CFLAGS=$saved_cppflags
+- LDFLAGS=$saved_ldflags
+- fi
+-fi
+-AC_SUBST(pcreh)
+-AC_SUBST(pcre_pcreh)
+-])
+--- /dev/null
++++ b/m4/pcre2.m4
+@@ -0,0 +1,181 @@
++dnl -------------------------------------------------------- -*- autoconf -*-
++dnl Licensed to the Apache Software Foundation (ASF) under one or more
++dnl contributor license agreements. See the NOTICE file distributed with
++dnl this work for additional information regarding copyright ownership.
++dnl The ASF licenses this file to You under the Apache License, Version 2.0
++dnl (the "License"); you may not use this file except in compliance with
++dnl the License. You may obtain a copy of the License at
++dnl
++dnl http://www.apache.org/licenses/LICENSE-2.0
++dnl
++dnl Unless required by applicable law or agreed to in writing, software
++dnl distributed under the License is distributed on an "AS IS" BASIS,
++dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++dnl See the License for the specific language governing permissions and
++dnl limitations under the License.
++
++dnl Modified by Syrone Wong <wong.syrone@gmail.com> to support pcre2 8bit variant only
++
++dnl
++dnl TS_ADDTO(variable, value)
++dnl
++dnl Add value to variable
++dnl
++AC_DEFUN([TS_ADDTO], [
++ if test "x$$1" = "x"; then
++ test "x$verbose" = "xyes" && echo " setting $1 to \"$2\""
++ $1="$2"
++ else
++ ats_addto_bugger="$2"
++ for i in $ats_addto_bugger; do
++ ats_addto_duplicate="0"
++ for j in $$1; do
++ if test "x$i" = "x$j"; then
++ ats_addto_duplicate="1"
++ break
++ fi
++ done
++ if test $ats_addto_duplicate = "0"; then
++ test "x$verbose" = "xyes" && echo " adding \"$i\" to $1"
++ $1="$$1 $i"
++ fi
++ done
++ fi
++])dnl
++
++dnl
++dnl TS_ADDTO_RPATH(path)
++dnl
++dnl Adds path to variable with the '-rpath' directive.
++dnl
++AC_DEFUN([TS_ADDTO_RPATH], [
++ AC_MSG_NOTICE([adding $1 to RPATH])
++ TS_ADDTO(LIBTOOL_LINK_FLAGS, [-R$1])
++])dnl
++
++dnl
++dnl pcre2.m4: Trafficserver's pcre2 autoconf macros
++dnl
++
++dnl
++dnl TS_CHECK_PCRE2: look for pcre2 libraries and headers
++dnl
++AC_DEFUN([TS_CHECK_PCRE2], [
++enable_pcre2=no
++AC_ARG_WITH(pcre2, [AC_HELP_STRING([--with-pcre2=DIR],[use a specific pcre2 library])],
++[
++ if test "x$withval" != "xyes" && test "x$withval" != "x"; then
++ pcre2_base_dir="$withval"
++ if test "$withval" != "no"; then
++ enable_pcre2=yes
++ case "$withval" in
++ *":"*)
++ pcre2_include="`echo $withval |sed -e 's/:.*$//'`"
++ pcre2_ldflags="`echo $withval |sed -e 's/^.*://'`"
++ AC_MSG_CHECKING(checking for pcre2 includes in $pcre2_include libs in $pcre2_ldflags )
++ ;;
++ *)
++ pcre2_include="$withval/include"
++ pcre2_ldflags="$withval/lib"
++ AC_MSG_CHECKING(checking for pcre2 includes in $withval)
++ ;;
++ esac
++ fi
++ fi
++],
++[
++ AC_CHECK_PROG(PCRE2_CONFIG, pcre2-config, pcre2-config)
++ if test "x$PCRE2_CONFIG" != "x"; then
++ enable_pcre2=yes
++ pcre2_base_dir="`$PCRE2_CONFIG --prefix`"
++ pcre2_include="`$PCRE2_CONFIG --cflags | sed -es/-I//`"
++ pcre2_ldflags="`$PCRE2_CONFIG --libs8 | sed -es/-lpcre2-8// -es/-L//`"
++ fi
++])
++
++if test "x$pcre2_base_dir" = "x"; then
++ AC_MSG_CHECKING([for pcre2 location])
++ AC_CACHE_VAL(ats_cv_pcre2_dir,[
++ for dir in /usr/local /usr ; do
++ if test -d $dir && ( test -f $dir/include/pcre2.h || test -f $dir/include/pcre2/pcre2.h ); then
++ ats_cv_pcre2_dir=$dir
++ break
++ fi
++ done
++ ])
++ pcre2_base_dir=$ats_cv_pcre2_dir
++ if test "x$pcre2_base_dir" = "x"; then
++ enable_pcre2=no
++ AC_MSG_RESULT([not found])
++ else
++ enable_pcre2=yes
++ pcre2_include="$pcre2_base_dir/include"
++ pcre2_ldflags="$pcre2_base_dir/lib"
++ AC_MSG_RESULT([$pcre2_base_dir])
++ fi
++else
++ AC_MSG_CHECKING(for pcre2 headers in $pcre2_include)
++ if test -d $pcre2_include && test -d $pcre2_ldflags && ( test -f $pcre2_include/pcre2.h || test -f $pcre2_include/pcre2/pcre2.h ); then
++ AC_MSG_RESULT([ok])
++ else
++ AC_MSG_RESULT([not found])
++ fi
++fi
++
++pcre2h=0
++pcre2_pcre2h=0
++if test "$enable_pcre2" != "no"; then
++ saved_ldflags=$LDFLAGS
++ saved_cppflags=$CFLAGS
++ pcre2_have_headers=0
++ pcre2_have_libs=0
++ if test "$pcre2_base_dir" != "/usr"; then
++ TS_ADDTO(CFLAGS, [-I${pcre2_include}])
++ TS_ADDTO(CFLAGS, [-DPCRE2_STATIC])
++ TS_ADDTO(LDFLAGS, [-L${pcre2_ldflags}])
++ TS_ADDTO_RPATH(${pcre2_ldflags})
++ fi
++ AC_SEARCH_LIBS([pcre2_match_8], [pcre2-8], [pcre2_have_libs=1])
++ if test "$pcre2_have_libs" != "0"; then
++ AC_MSG_CHECKING([pcre2.h])
++ AC_COMPILE_IFELSE(
++ [AC_LANG_PROGRAM(
++ [[
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
++ ]],
++ [[
++ ]]
++ )],
++ [pcre2_have_headers=1
++ AC_MSG_RESULT([ok])],
++ [AC_MSG_RESULT([not found])]
++ )
++
++ AC_MSG_CHECKING([pcre2/pcre2.h])
++ AC_COMPILE_IFELSE(
++ [AC_LANG_PROGRAM(
++ [[
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2/pcre2.h>
++ ]],
++ [[
++ ]]
++ )],
++ [pcre2_have_headers=1
++ AC_MSG_RESULT([ok])],
++ [AC_MSG_RESULT([not found])]
++ )
++ fi
++ if test "$pcre2_have_headers" != "0"; then
++ AC_DEFINE(HAVE_LIBPCRE2,1,[Compiling with pcre2 support])
++ AC_SUBST(LIBPCRE2, [-lpcre2-8])
++ else
++ enable_pcre2=no
++ CFLAGS=$saved_cppflags
++ LDFLAGS=$saved_ldflags
++ fi
++fi
++AC_SUBST(pcre2h)
++AC_SUBST(pcre2_pcre2h)
++])
+--- a/src/rule.c
++++ b/src/rule.c
+@@ -1,6 +1,7 @@
+ /*
+ * Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
+ * Copyright (c) 2011 Manuel Kasper <mk@neon1.net>
++ * Copyright (c) 2017 Syrone Wong <wong.syrone@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+@@ -74,18 +75,37 @@ add_rule(struct cork_dllist *rules, rule
+ cork_dllist_add(rules, &rule->entries);
+ }
+
++/*
++ * XXX: As pattern and subject are char arguments, they can be straightforwardly
++ * cast to PCRE2_SPTR as we are working in 8-bit code units.
++ */
++
+ int
+ init_rule(rule_t *rule)
+ {
+ if (rule->pattern_re == NULL) {
+- const char *reerr;
+- int reerroffset;
++ int errornumber;
++ PCRE2_SIZE erroroffset;
++ rule->pattern_re = pcre2_compile(
++ (PCRE2_SPTR)rule->pattern, /* the pattern */
++ PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */
++ 0, /* default options */
++ &errornumber, /* for error number */
++ &erroroffset, /* for error offset */
++ NULL); /* use default compile context */
+
+- rule->pattern_re =
+- pcre_compile(rule->pattern, 0, &reerr, &reerroffset, NULL);
+ if (rule->pattern_re == NULL) {
+- LOGE("Regex compilation of \"%s\" failed: %s, offset %d",
+- rule->pattern, reerr, reerroffset);
++ PCRE2_UCHAR errbuffer[512];
++ pcre2_get_error_message(errornumber, errbuffer, sizeof(errbuffer));
++ LOGE("PCRE2 regex compilation failed at offset %d: %s\n", (int)erroroffset,
++ errbuffer);
++ return 0;
++ }
++
++ rule->pattern_re_match_data = pcre2_match_data_create_from_pattern(rule->pattern_re, NULL);
++
++ if (rule->pattern_re_match_data == NULL) {
++ ERROR("PCRE2: the memory for the block could not be obtained");
+ return 0;
+ }
+ }
+@@ -105,8 +125,15 @@ lookup_rule(const struct cork_dllist *ru
+
+ cork_dllist_foreach_void(rules, curr, next) {
+ rule_t *rule = cork_container_of(curr, rule_t, entries);
+- if (pcre_exec(rule->pattern_re, NULL,
+- name, name_len, 0, 0, NULL, 0) >= 0)
++ if (pcre2_match(
++ rule->pattern_re, /* the compiled pattern */
++ (PCRE2_SPTR)name, /* the subject string */
++ name_len, /* the length of the subject */
++ 0, /* start at offset 0 in the subject */
++ 0, /* default options */
++ rule->pattern_re_match_data, /* block for storing the result */
++ NULL /* use default match context */
++ ) >= 0)
+ return rule;
+ }
+
+@@ -127,7 +154,13 @@ free_rule(rule_t *rule)
+ return;
+
+ ss_free(rule->pattern);
+- if (rule->pattern_re != NULL)
+- pcre_free(rule->pattern_re);
++ if (rule->pattern_re != NULL) {
++ pcre2_code_free(rule->pattern_re); /* data and the compiled pattern. */
++ rule->pattern_re = NULL;
++ }
++ if (rule->pattern_re_match_data != NULL) {
++ pcre2_match_data_free(rule->pattern_re_match_data); /* Release memory used for the match */
++ rule->pattern_re_match_data = NULL;
++ }
+ ss_free(rule);
+ }
+--- a/src/rule.h
++++ b/src/rule.h
+@@ -1,6 +1,7 @@
+ /*
+ * Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
+ * Copyright (c) 2011 Manuel Kasper <mk@neon1.net>
++ * Copyright (c) 2017 Syrone Wong <wong.syrone@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+@@ -33,17 +34,27 @@
+
+ #include <libcork/ds.h>
+
+-#ifdef HAVE_PCRE_H
+-#include <pcre.h>
+-#elif HAVE_PCRE_PCRE_H
+-#include <pcre/pcre.h>
+-#endif
++/*
++ * The PCRE2_CODE_UNIT_WIDTH macro must be defined before including pcre2.h.
++ * For a program that uses only one code unit width, setting it to 8, 16, or 32
++ * makes it possible to use generic function names such as pcre2_compile(). Note
++ * that just changing 8 to 16 (for example) is not sufficient to convert this
++ * program to process 16-bit characters. Even in a fully 16-bit environment, where
++ * string-handling functions such as strcmp() and printf() work with 16-bit
++ * characters, the code for handling the table of named substrings will still need
++ * to be modified.
++ */
++/* we only need to support ASCII chartable, thus set it to 8 */
++#define PCRE2_CODE_UNIT_WIDTH 8
++
++#include <pcre2.h>
+
+ typedef struct rule {
+ char *pattern;
+
+ /* Runtime fields */
+- pcre *pattern_re;
++ pcre2_code *pattern_re;
++ pcre2_match_data *pattern_re_match_data;
+
+ struct cork_dllist_item entries;
+ } rule_t;
include $(TOPDIR)/rules.mk
PKG_NAME:=sing-box
-PKG_VERSION:=1.5.2
+PKG_VERSION:=1.7.4
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/SagerNet/sing-box/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=ad344a5fe0a515e3e5d0ab8102482b4a3d38932cf754756e1d48db17d36a5609
+PKG_HASH:=483c7188f054dffc37211a4c6d50edc7473f9cbbe57c5687bb3551aba3919e52
PKG_LICENSE:=GPL-3.0-or-later
PKG_LICENSE_FILES:=LICENSE
define Package/sing-box/description
Sing-box is a universal proxy platform which supports hysteria, SOCKS, Shadowsocks,
- ShadowsocksR, ShadowTLS, Tor, trojan, VLess, VMess, WireGuard and so on.
+ ShadowTLS, Tor, trojan, VLess, VMess, WireGuard and so on.
endef
define Package/sing-box/config
bool "Build with reality TLS server support, see TLS."
default y
- config SINGBOX_WITH_SHADOWSOCKSR
- bool "Build with ShadowsocksR support"
- help
- It will be marked deprecated in 1.5.0 and removed entirely in 1.6.0.
-
config SINGBOX_WITH_UTLS
bool "Build with uTLS support for TLS outbound"
default y
CONFIG_SINGBOX_WITH_LWIP \
CONFIG_SINGBOX_WITH_QUIC \
CONFIG_SINGBOX_WITH_REALITY_SERVER \
- CONFIG_SINGBOX_WITH_SHADOWSOCKSR \
CONFIG_SINGBOX_WITH_UTLS \
CONFIG_SINGBOX_WITH_V2RAY_API \
CONFIG_SINGBOX_WITH_WIREGUARD
$(if $(CONFIG_SINGBOX_WITH_GVISOR),with_gvisor) \
$(if $(CONFIG_SINGBOX_WITH_LWIP),with_lwip) \
$(if $(CONFIG_SINGBOX_WITH_QUIC),with_quic) \
- $(if $(CONFIG_SINGBOX_WITH_SHADOWSOCKSR),with_shadowsocksr) \
$(if $(CONFIG_SINGBOX_WITH_REALITY_SERVER),with_reality_server) \
$(if $(CONFIG_SINGBOX_WITH_UTLS),with_utls) \
$(if $(CONFIG_SINGBOX_WITH_V2RAY_API),with_v2ray_api) \
include $(TOPDIR)/rules.mk
PKG_NAME:=snort
-PKG_VERSION:=2.9.19
-PKG_RELEASE:=2
+PKG_VERSION:=2.9.20
+PKG_RELEASE:=1
PKG_LICENSE:=GPL-2.0
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.snort.org/downloads/archive/snort/ \
@SF/$(PKG_NAME)
-PKG_HASH:=b12fc6db72afb58987a2bf1954b8f45bde02047c235513c7663857b9506369c7
+PKG_HASH:=29400e13f53b1831e0b8b10ec1224a1cbaa6dc1533a5322a20dd80bb84b4981c
PKG_BUILD_DEPENDS:=libtirpc
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(PKG_NAME)-$(PKG_VERSION)
SUBMENU:=Firewall
SECTION:=net
CATEGORY:=Network
- DEPENDS:=+libdaq +libdnet +libnghttp2 +libopenssl +libpcap +libpcre +libpthread +libtirpc +libuuid +zlib @HAS_LUAJIT_ARCH +luajit +SNORT_LZMA:liblzma
+ DEPENDS:=+libdaq +libdnet +libnghttp2 +libopenssl +libpcap +libpcre2 +libpthread +libtirpc +libuuid +zlib @HAS_LUAJIT_ARCH +luajit +SNORT_LZMA:liblzma
TITLE:=Lightweight Network Intrusion Detection System
URL:=http://www.snort.org/
CONFLICTS:=snort3
--with-dnet-libraries="$(STAGING_DIR)/usr/lib" \
--with-libpcap-includes="$(STAGING_DIR)/usr/include" \
--with-libpcap-libraries="$(STAGING_DIR)/usr/lib" \
- --with-libpcre-includes="$(STAGING_DIR)/usr/include" \
- --with-libpcre-libraries="$(STAGING_DIR)/usr/lib" \
+ --with-libpcre2-includes="$(STAGING_DIR)/usr/include" \
+ --with-libpcre2-libraries="$(STAGING_DIR)/usr/lib" \
--with-daq-includes="$(STAGING_DIR)/usr/include/daq2" \
--with-daq-libraries="$(STAGING_DIR)/usr/lib/daq2" \
--disable-static-daq
--- /dev/null
+From 514af7b25f1f49d87963baf4fd057d9c85f518a7 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sat, 4 Nov 2023 01:30:37 +0100
+Subject: [PATCH] Convert project to PCRE2
+
+Convert project to PCRE2. Convert every example to PCRE2.
+
+Due to API changes examples needs to be updated accordingly with the new
+struct and API.
+
+The API name were voluntary changes to make sure the user of plugins is
+aware of the change and manually refresh the plugin with new code.
+
+Most of the time it's just PcreMatch to Pcre2Match and PCREInfo to
+PCRE2Info and the relative options (that are 1:1 compared to PCRE
+library).
+
+For complex case where ovector extraction is needed, refer to example
+36733 where new way with match data is used. Follow comments there for
+additional info.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ config.h.in | 8 +-
+ configure.in | 67 ++++----
+ src/detection-plugins/sp_pcre.c | 149 +++++++++---------
+ src/detection-plugins/sp_pcre.h | 9 +-
+ src/dynamic-plugins/sf_convert_dynamic.c | 59 ++++---
+ src/dynamic-plugins/sf_dynamic_engine.h | 32 ++--
+ src/dynamic-plugins/sf_dynamic_plugins.c | 109 +++++++------
+ src/dynamic-plugins/sf_engine/examples/3036.c | 8 +-
+ src/dynamic-plugins/sf_engine/examples/3052.c | 8 +-
+ src/dynamic-plugins/sf_engine/examples/3099.c | 8 +-
+ .../sf_engine/examples/36733.c | 40 +++--
+ src/dynamic-plugins/sf_engine/examples/3682.c | 11 +-
+ .../sf_engine/examples/bug31842.c | 9 +-
+ .../sf_engine/examples/bug35218.c | 15 +-
+ .../sf_engine/examples/sid1902.c | 9 +-
+ .../sf_engine/examples/sid2389.c | 9 +-
+ .../sf_engine/examples/sid9999.c | 2 +-
+ .../sf_engine/examples/web-client_test.c | 18 +--
+ .../sf_engine/sf_snort_detection_engine.c | 20 +--
+ .../sf_engine/sf_snort_detection_engine.h | 2 +-
+ .../sf_engine/sf_snort_plugin_api.c | 10 +-
+ .../sf_engine/sf_snort_plugin_api.h | 39 +++--
+ .../sf_engine/sf_snort_plugin_pcre.c | 132 ++++++++++------
+ .../appid/luaDetectorApi.c | 63 +++++---
+ src/dynamic-preprocessors/imap/snort_imap.h | 6 +-
+ src/dynamic-preprocessors/pop/snort_pop.h | 3 +-
+ src/dynamic-preprocessors/smtp/snort_smtp.h | 3 +-
+ src/snort.c | 3 -
+ src/snort.h | 1 -
+ src/util.c | 9 +-
+ 30 files changed, 497 insertions(+), 364 deletions(-)
+ mode change 100755 => 100644 src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h
+ mode change 100755 => 100644 src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c
+
+--- a/config.h.in
++++ b/config.h.in
+@@ -133,8 +133,8 @@
+ /* Define to 1 if you have the `pcap' library (-lpcap). */
+ #undef HAVE_LIBPCAP
+
+-/* Define to 1 if you have the `pcre' library (-lpcre). */
+-#undef HAVE_LIBPCRE
++/* Define to 1 if you have the `pcre2' library (-lpcre2-8). */
++#undef HAVE_LIBPCRE2
+
+ /* Define to 1 if you have the `pfring' library (-lpfring). */
+ #undef HAVE_LIBPFRING
+@@ -190,8 +190,8 @@
+ /* Can output the library version. */
+ #undef HAVE_PCAP_LIB_VERSION
+
+-/* Define to 1 if you have the <pcre.h> header file. */
+-#undef HAVE_PCRE_H
++/* Define to 1 if you have the <pcre2.h> header file. */
++#undef HAVE_PCRE2_H
+
+ /* Define to 1 if you have the <pfring.h> header file. */
+ #undef HAVE_PFRING_H
+--- a/configure.in
++++ b/configure.in
+@@ -455,65 +455,70 @@ AC_DEFUN([FAIL_MESSAGE],[
+ exit 1
+ ])
+
+-AC_ARG_WITH(libpcre_includes,
+- [ --with-libpcre-includes=DIR libpcre include directory],
+- [with_libpcre_includes="$withval"],[with_libpcre_includes="no"])
+-
+-AC_ARG_WITH(libpcre_libraries,
+- [ --with-libpcre-libraries=DIR libpcre library directory],
+- [with_libpcre_libraries="$withval"],[with_libpcre_libraries="no"])
+-
+-if test "x$with_libpcre_includes" != "xno"; then
+- CPPFLAGS="${CPPFLAGS} -I${with_libpcre_includes}"
+- ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_libpcre_includes}"
++AC_ARG_WITH(libpcre2_includes,
++ [ --with-libpcre2-includes=DIR libpcre2 include directory],
++ [with_libpcre2_includes="$withval"],[with_libpcre2_includes="no"])
++
++AC_ARG_WITH(libpcre2_libraries,
++ [ --with-libpcre2-libraries=DIR libpcre2 library directory],
++ [with_libpcre2_libraries="$withval"],[with_libpcre2_libraries="no"])
++
++if test "x$with_libpcre2_includes" != "xno"; then
++ CPPFLAGS="${CPPFLAGS} -I${with_libpcre2_includes}"
++ ICONFIGFLAGS="${ICONFIGFLAGS} -I${with_libpcre2_includes}"
+ else
+- CPPFLAGS="${CPPFLAGS} `pcre-config --cflags`"
++ CPPFLAGS="${CPPFLAGS} `pcre2-config --cflags`"
+ fi
+
+-if test "x$with_libpcre_libraries" != "xno"; then
+- LDFLAGS="${LDFLAGS} -L${with_libpcre_libraries}"
++if test "x$with_libpcre2_libraries" != "xno"; then
++ LDFLAGS="${LDFLAGS} -L${with_libpcre2_libraries}"
+ else
+- LDFLAGS="${LDFLAGS} `pcre-config --libs`"
++ LDFLAGS="${LDFLAGS} `pcre2-config --libs8`"
+ fi
+
+-# PCRE configuration (required)
++# PCRE2 configuration (required)
+ # Verify that we have the headers
+-PCRE_H=""
+-AC_CHECK_HEADERS(pcre.h,, PCRE_H="no")
+-if test "x$PCRE_H" = "xno"; then
++PCRE2_H=""
++AC_CHECK_HEADERS(pcre2.h,, PCRE2_H="no",[#define PCRE2_CODE_UNIT_WIDTH 8])
++if test "x$PCRE2_H" = "xno"; then
+ echo
+- echo " ERROR! Libpcre header not found."
++ echo " ERROR! Libpcre2 header not found."
+ echo " Get it from http://www.pcre.org"
+ exit 1
+ fi
+
+ # Verify that we have the library
+-PCRE_L=""
+-pcre_version_six=""
+-AC_CHECK_LIB(pcre, pcre_compile, ,PCRE_L="no")
++PCRE2_L=""
++pcre2_version_six=""
++AC_CHECK_LIB(pcre2-8, pcre2_compile_8, ,PCRE2_L="no")
+ if test "x$PCRE_L" = "xno"; then
+ echo
+- echo " ERROR! Libpcre library not found."
++ echo " ERROR! Libpcre2 library not found."
+ echo " Get it from http://www.pcre.org"
+ echo
+ exit 1
+ else
+- AC_MSG_CHECKING(for libpcre version 6.0 or greater)
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pcre.h>]], [[
+- #if (PCRE_MAJOR < 6)
++ AC_MSG_CHECKING(for libpcre2 version 10.0 or greater)
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
++ #define PCRE2_CODE_UNIT_WIDTH 8
++ #include <pcre2.h>
++ ]], [[
++ #if (PCRE2_MAJOR < 10)
+ #error "Version failure"
+ #else
+- int a, b = 0, c = 0, d = 0;
+- pcre *tmp = NULL;
+- a = pcre_copy_named_substring(tmp, "", &b, c, "", "", d);
++ int a;
++ PCRE2_UCHAR b = { 0 };
++ PCRE2_SIZE c;
++ pcre2_match_data *match_data = NULL;
++ a = pcre2_substring_copy_byname(match_data, (PCRE2_SPTR )"", &b, &c);
+ #endif
+- ]])],[pcre_version_six="yes"],[pcre_version_six="no"])
++ ]])],[pcre2_version_ten="yes"],[pcre2_version_ten="no"])
+ fi
+
+-if test "x$pcre_version_six" != "xyes"; then
++if test "x$pcre2_version_ten" != "xyes"; then
+ AC_MSG_RESULT(no)
+ echo
+- echo " ERROR! Libpcre library version >= 6.0 not found."
++ echo " ERROR! Libpcre2 library version >= 10.0 not found."
+ echo " Get it from http://www.pcre.org"
+ echo
+ exit 1
+--- a/src/detection-plugins/sp_pcre.c
++++ b/src/detection-plugins/sp_pcre.c
+@@ -46,7 +46,8 @@
+
+ #include "sp_pcre.h"
+
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+
+ #include "snort.h"
+ #include "profiler.h"
+@@ -60,7 +61,7 @@ extern PreprocStats ruleOTNEvalPerfStats
+ #include "detection_util.h"
+
+ /*
+- * we need to specify the vector length for our pcre_exec call. we only care
++ * we need to specify the vector length for our pcre2_match call. we only care
+ * about the first vector, which if the match is successful will include the
+ * offset to the end of the full pattern match. If we decide to store other
+ * matches, make *SURE* that this is a multiple of 3 as pcre requires it.
+@@ -77,8 +78,8 @@ void PcreFree(void *d)
+ PcreData *data = (PcreData *)d;
+
+ free(data->expression);
+- free(data->re);
+- free(data->pe);
++ pcre2_match_context_free(data->match_context);
++ pcre2_code_free(data->re);
+ free(data);
+ }
+
+@@ -161,7 +162,6 @@ void PcreDuplicatePcreData(void *src, Pc
+ pcre_dup->expression = pcre_src->expression;
+ pcre_dup->options = pcre_src->options;
+ pcre_dup->search_offset = 0;
+- pcre_dup->pe = pcre_src->pe;
+ pcre_dup->re = pcre_src->re;
+ }
+
+@@ -197,7 +197,7 @@ static void Ovector_Init(struct _SnortCo
+ * configuraton, we won't pcre capture count again, so save the max. */
+ static int s_ovector_max = 0;
+
+- /* The pcre_fullinfo() function can be used to find out how many
++ /* The pcre2_pattern_info() function can be used to find out how many
+ * capturing subpatterns there are in a compiled pattern. The
+ * smallest size for ovector that will allow for n captured
+ * substrings, in addition to the offsets of the substring matched
+@@ -207,8 +207,6 @@ static void Ovector_Init(struct _SnortCo
+
+ if (sc->pcre_ovector_size > s_ovector_max)
+ s_ovector_max = sc->pcre_ovector_size;
+-
+- sc->pcre_ovector = (int *) SnortAlloc(s_ovector_max*sizeof(int));
+ }
+
+ #if SNORT_RELOAD
+@@ -218,12 +216,12 @@ static void Ovector_Reload(struct _Snort
+ }
+ #endif
+
+-void PcreCapture(struct _SnortConfig *sc, const void *code, const void *extra)
++void Pcre2Capture(struct _SnortConfig *sc, const void *code)
+ {
+ int tmp_ovector_size = 0;
+
+- pcre_fullinfo((const pcre *)code, (const pcre_extra *)extra,
+- PCRE_INFO_CAPTURECOUNT, &tmp_ovector_size);
++ pcre2_pattern_info((const pcre2_code *)code,
++ PCRE2_INFO_CAPTURECOUNT, &tmp_ovector_size);
+
+ if (tmp_ovector_size > sc->pcre_ovector_size)
+ sc->pcre_ovector_size = tmp_ovector_size;
+@@ -268,10 +266,10 @@ void SnortPcreInit(struct _SnortConfig *
+
+ if (pcre_data->expression)
+ free(pcre_data->expression);
+- if (pcre_data->pe)
+- free(pcre_data->pe);
++ if (pcre_data->match_context)
++ pcre2_match_context_free(pcre_data->match_context);
+ if (pcre_data->re)
+- free(pcre_data->re);
++ pcre2_code_free(pcre_data->re);
+
+ free(pcre_data);
+ pcre_data = pcre_dup;
+@@ -305,11 +303,12 @@ static inline void ValidatePcreHttpConte
+
+ void SnortPcreParse(struct _SnortConfig *sc, char *data, PcreData *pcre_data, OptTreeNode *otn)
+ {
+- const char *error;
++ PCRE2_UCHAR error[128];
+ char *re, *free_me;
+ char *opts;
+ char delimit = '/';
+- int erroffset;
++ int errorcode;
++ PCRE2_SIZE erroffset;
+ int compile_flags = 0;
+ unsigned http = 0;
+
+@@ -381,17 +380,17 @@ void SnortPcreParse(struct _SnortConfig
+ /* process any /regex/ismxR options */
+ while(*opts != '\0') {
+ switch(*opts) {
+- case 'i': compile_flags |= PCRE_CASELESS; break;
+- case 's': compile_flags |= PCRE_DOTALL; break;
+- case 'm': compile_flags |= PCRE_MULTILINE; break;
+- case 'x': compile_flags |= PCRE_EXTENDED; break;
++ case 'i': compile_flags |= PCRE2_CASELESS; break;
++ case 's': compile_flags |= PCRE2_DOTALL; break;
++ case 'm': compile_flags |= PCRE2_MULTILINE; break;
++ case 'x': compile_flags |= PCRE2_EXTENDED; break;
+
+ /*
+ * these are pcre specific... don't work with perl
+ */
+- case 'A': compile_flags |= PCRE_ANCHORED; break;
+- case 'E': compile_flags |= PCRE_DOLLAR_ENDONLY; break;
+- case 'G': compile_flags |= PCRE_UNGREEDY; break;
++ case 'A': compile_flags |= PCRE2_ANCHORED; break;
++ case 'E': compile_flags |= PCRE2_DOLLAR_ENDONLY; break;
++ case 'G': compile_flags |= PCRE2_UNGREEDY; break;
+
+ /*
+ * these are snort specific don't work with pcre or perl
+@@ -424,45 +423,37 @@ void SnortPcreParse(struct _SnortConfig
+
+ /* now compile the re */
+ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre: compiling %s\n", re););
+- pcre_data->re = pcre_compile(re, compile_flags, &error, &erroffset, NULL);
++ pcre_data->re = pcre2_compile((PCRE2_SPTR)re, PCRE2_ZERO_TERMINATED, compile_flags, &errorcode, &erroffset, NULL);
+
+ if(pcre_data->re == NULL)
+ {
++ pcre2_get_error_message(errorcode, error, 128);
+ FatalError("%s(%d) : pcre compile of \"%s\" failed at offset "
+- "%d : %s\n", file_name, file_line, re, erroffset, error);
++ "%zu : %s\n", file_name, file_line, re, erroffset, error);
+ }
+
++ /* now create match context */
++ pcre_data->match_context = pcre2_match_context_create(NULL);
++ if(pcre_data->match_context == NULL)
++ {
++ FatalError("%s(%d) : failed to allocate memory for match context\n",
++ file_name, file_line);
++ }
+
+ /* now study it... */
+- pcre_data->pe = pcre_study(pcre_data->re, 0, &error);
++ errorcode = pcre2_jit_compile(pcre_data->re, PCRE2_JIT_COMPLETE);
+
+- if (pcre_data->pe)
++ if (!errorcode)
+ {
+ if ((ScPcreMatchLimitNewConf(sc) != -1) && !(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT))
+ {
+- if (pcre_data->pe->flags & PCRE_EXTRA_MATCH_LIMIT)
+- {
+- pcre_data->pe->match_limit = ScPcreMatchLimitNewConf(sc);
+- }
+- else
+- {
+- pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT;
+- pcre_data->pe->match_limit = ScPcreMatchLimitNewConf(sc);
+- }
++ pcre2_set_match_limit(pcre_data->match_context, ScPcreMatchLimitNewConf(sc));
+ }
+
+ #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
+ if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT))
+ {
+- if (pcre_data->pe->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION)
+- {
+- pcre_data->pe->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
+- }
+- else
+- {
+- pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
+- pcre_data->pe->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
+- }
++ pcre2_set_depth_limit(pcre_data->match_context, ScPcreMatchLimitRecursionNewConf(sc));
+ }
+ #endif
+ }
+@@ -471,30 +462,28 @@ void SnortPcreParse(struct _SnortConfig
+ if (!(pcre_data->options & SNORT_OVERRIDE_MATCH_LIMIT) &&
+ ((ScPcreMatchLimitNewConf(sc) != -1) || (ScPcreMatchLimitRecursionNewConf(sc) != -1)))
+ {
+- pcre_data->pe = (pcre_extra *)SnortAlloc(sizeof(pcre_extra));
+ if (ScPcreMatchLimitNewConf(sc) != -1)
+ {
+- pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT;
+- pcre_data->pe->match_limit = ScPcreMatchLimitNewConf(sc);
++ pcre2_set_match_limit(pcre_data->match_context, ScPcreMatchLimitNewConf(sc));
+ }
+
+ #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
+ if (ScPcreMatchLimitRecursionNewConf(sc) != -1)
+ {
+- pcre_data->pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
+- pcre_data->pe->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
++ pcre2_set_depth_limit(pcre_data->match_context, ScPcreMatchLimitRecursionNewConf(sc));
+ }
+ #endif
+ }
+ }
+
+- if(error != NULL)
++ if(errorcode)
+ {
++ pcre2_get_error_message(errorcode, error, 128);
+ FatalError("%s(%d) : pcre study failed : %s\n", file_name,
+ file_line, error);
+ }
+
+- PcreCapture(sc, pcre_data->re, pcre_data->pe);
++ Pcre2Capture(sc, pcre_data->re);
+
+ PcreCheckAnchored(pcre_data);
+
+@@ -515,13 +504,13 @@ void PcreCheckAnchored(PcreData *pcre_da
+ int rc;
+ unsigned long int options = 0;
+
+- if ((pcre_data == NULL) || (pcre_data->re == NULL) || (pcre_data->pe == NULL))
++ if ((pcre_data == NULL) || (pcre_data->re == NULL) || (pcre_data->match_context == NULL))
+ return;
+
+- rc = pcre_fullinfo(pcre_data->re, pcre_data->pe, PCRE_INFO_OPTIONS, (void *)&options);
++ rc = pcre2_pattern_info(pcre_data->re, PCRE2_INFO_ARGOPTIONS, (void *)&options);
+ switch (rc)
+ {
+- /* pcre_fullinfo fails for the following:
++ /* pcre2_pattern_info fails for the following:
+ * PCRE_ERROR_NULL - the argument code was NULL
+ * the argument where was NULL
+ * PCRE_ERROR_BADMAGIC - the "magic number" was not found
+@@ -533,24 +522,24 @@ void PcreCheckAnchored(PcreData *pcre_da
+ /* This is the success code */
+ break;
+
+- case PCRE_ERROR_NULL:
+- FatalError("%s(%d) pcre_fullinfo: code and/or where were NULL.\n",
++ case PCRE2_ERROR_NULL:
++ FatalError("%s(%d) pcre2_pattern_info: code and/or where were NULL.\n",
+ __FILE__, __LINE__);
+
+- case PCRE_ERROR_BADMAGIC:
+- FatalError("%s(%d) pcre_fullinfo: compiled code didn't have "
++ case PCRE2_ERROR_BADMAGIC:
++ FatalError("%s(%d) pcre2_pattern_info: compiled code didn't have "
+ "correct magic.\n", __FILE__, __LINE__);
+
+- case PCRE_ERROR_BADOPTION:
+- FatalError("%s(%d) pcre_fullinfo: option type is invalid.\n",
++ case PCRE2_ERROR_BADOPTION:
++ FatalError("%s(%d) pcre2_pattern_info: option type is invalid.\n",
+ __FILE__, __LINE__);
+
+ default:
+- FatalError("%s(%d) pcre_fullinfo: Unknown error code.\n",
++ FatalError("%s(%d) pcre2_pattern_info: Unknown error code.\n",
+ __FILE__, __LINE__);
+ }
+
+- if ((options & PCRE_ANCHORED) && !(options & PCRE_MULTILINE))
++ if ((options & PCRE2_ANCHORED) && !(options & PCRE2_MULTILINE))
+ {
+ /* This means that this pcre rule option shouldn't be reevaluted
+ * even if any of it's relative children should fail to match.
+@@ -579,6 +568,8 @@ static int pcre_search(const PcreData *p
+ int start_offset,
+ int *found_offset)
+ {
++ pcre2_match_data *match_data;
++ PCRE2_SIZE *ovector;
+ int matched;
+ int result;
+
+@@ -596,14 +587,19 @@ static int pcre_search(const PcreData *p
+
+ *found_offset = -1;
+
+- result = pcre_exec(pcre_data->re, /* result of pcre_compile() */
+- pcre_data->pe, /* result of pcre_study() */
+- buf, /* the subject string */
+- len, /* the length of the subject string */
+- start_offset, /* start at offset 0 in the subject */
+- 0, /* options(handled at compile time */
+- snort_conf->pcre_ovector, /* vector for substring information */
+- snort_conf->pcre_ovector_size);/* number of elements in the vector */
++ match_data = pcre2_match_data_create(snort_conf->pcre_ovector_size, NULL);
++ if (!match_data) {
++ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre2_match_data_create failed to alloc mem!\n"););
++ return 0;
++ }
++
++ result = pcre2_match(pcre_data->re, /* result of pcre2_compile() */
++ (PCRE2_SPTR)buf, /* the subject string */
++ (PCRE2_SIZE)len, /* the length of the subject string */
++ (PCRE2_SIZE)start_offset, /* start at offset 0 in the subject */
++ 0, /* options(handled at compile time */
++ match_data, /* match data for results */
++ pcre_data->match_context); /* match context for JIT limits */
+
+ if(result >= 0)
+ {
+@@ -615,23 +611,25 @@ static int pcre_search(const PcreData *p
+ * second is set to the offset of the first character after the end of a substring. The first pair,
+ * ovector[0] and ovector[1], identify the portion of the subject string matched by the entire pattern.
+ * The next pair is used for the first capturing subpattern, and so on. The value returned by
+- * pcre_exec() is the number of pairs that have been set. If there are no capturing subpatterns, the
++ * pcre_match() is the number of pairs that have been set. If there are no capturing subpatterns, the
+ * return value from a successful match is 1, indicating that just the first pair of offsets has been set.
+ *
+ * In Snort's case, the ovector size only allows for the first pair and a single int for scratch space.
+ */
+- *found_offset = snort_conf->pcre_ovector[1];
++ ovector = pcre2_get_ovector_pointer(match_data);
++ *found_offset = ovector[1];
+ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
+ "Setting Doe_ptr and found_offset: %p %d\n",
+ doe_ptr, found_offset););
+ }
+- else if(result == PCRE_ERROR_NOMATCH)
++ else if(result == PCRE2_ERROR_NOMATCH)
+ {
+ matched = 0;
+ }
+ else
+ {
+- DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre_exec error : %d \n", result););
++ pcre2_match_data_free(match_data);
++ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre2_match error : %d \n", result););
+ return 0;
+ }
+
+@@ -641,6 +639,7 @@ static int pcre_search(const PcreData *p
+ matched = !matched;
+ }
+
++ pcre2_match_data_free(match_data);
+ return matched;
+ }
+
+--- a/src/detection-plugins/sp_pcre.h
++++ b/src/detection-plugins/sp_pcre.h
+@@ -49,17 +49,18 @@
+
+ void SetupPcre(void);
+
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ typedef struct _PcreData
+ {
+- pcre *re; /* compiled regex */
+- pcre_extra *pe; /* studied regex foo */
++ pcre2_code *re; /* compiled regex */
++ pcre2_match_context *match_context; /* regex match context */
+ int options; /* sp_pcre specfic options (relative & inverse) */
+ char *expression;
+ uint32_t search_offset;
+ } PcreData;
+
+-void PcreCapture(struct _SnortConfig *sc, const void *code, const void *extra);
++void Pcre2Capture(struct _SnortConfig *sc, const void *code);
+ void PcreFree(void *d);
+ uint32_t PcreHash(void *d);
+ int PcreCompare(void *l, void *r);
+--- a/src/dynamic-plugins/sf_convert_dynamic.c
++++ b/src/dynamic-plugins/sf_convert_dynamic.c
+@@ -52,9 +52,11 @@
+
+ extern void ParsePattern(char *, OptTreeNode *, int);
+ extern void ParseProtectedPattern(char *, OptTreeNode *, int);
+-extern void *pcreCompile(const char *pattern, int options, const char **errptr,
+- int *erroffset, const unsigned char *tableptr);
+-extern void *pcreStudy(struct _SnortConfig *sc, const void *code, int options, const char **errptr);
++extern void *pcre2MatchContextCreate(const void *gcontext);
++extern void *pcre2Compile(const char *pattern, int options, int *errorcode, size_t *erroffset, void *matchcontext);
++extern int pcre2JITCompile(struct _SnortConfig *sc, const void *code, const void *matchcontext, int options);
++extern void pcre2MatchContextFree(const void *match_context);
++extern void pcre2CodeFree(const void *code);
+
+ extern int SnortPcre(void *option_data, Packet *p);
+ extern int FlowBitsCheck(void *option_data, Packet *p);
+@@ -517,20 +519,20 @@ static int ConvertProtectedContentOption
+ static int ConvertPcreOption(SnortConfig *sc, Rule *rule, int index, OptTreeNode *otn)
+ {
+ PcreData *pcre_data = (PcreData *) SnortAlloc(sizeof(PcreData));
+- PCREInfo *pcre_info = rule->options[index]->option_u.pcre;
++ PCRE2Info *pcre2_info = rule->options[index]->option_u.pcre2;
+ OptFpList *fpl;
+ void *pcre_dup;
+- const char *error;
+- int erroroffset;
++ int errorcode;
++ size_t erroroffset;
+
+ /* Need to recompile the expression so double free doesn't occur
+ * during reload */
+
+ /* Compile & Study PCRE */
+- pcre_data->re = pcreCompile(
+- pcre_info->expr,
+- pcre_info->compile_flags,
+- &error,
++ pcre_data->re = pcre2Compile(
++ pcre2_info->expr,
++ pcre2_info->compile_flags,
++ &errorcode,
+ &erroroffset,
+ NULL
+ );
+@@ -541,37 +543,46 @@ static int ConvertPcreOption(SnortConfig
+ return -1;
+ }
+
+- pcre_data->pe = pcreStudy(sc,
++ pcre_data->match_context = pcre2MatchContextCreate(NULL);
++ if (pcre_data->match_context == NULL) {
++ pcre2CodeFree(pcre_data->re);
++ free(pcre_data);
++ return -1;
++ }
++
++ errorcode = pcre2JITCompile(
++ sc,
+ pcre_data->re,
+- pcre_info->compile_flags,
+- &error
++ pcre_data->match_context,
++ pcre2_info->compile_flags
+ );
+
+- if (error)
++ if (errorcode)
+ {
+- free(pcre_data->re);
++ pcre2MatchContextFree(pcre_data->match_context);
++ pcre2CodeFree(pcre_data->re);
+ free(pcre_data);
+ return -1;
+ }
+
+ /* Copy to struct used for normal PCRE rules */
+- pcre_data->expression = SnortStrdup(pcre_info->expr);
++ pcre_data->expression = SnortStrdup(pcre2_info->expr);
+
+ /* Option values differ between PCREInfo and PcreData,
+ * so a straight copy of the options variable won't work. */
+- if (pcre_info->flags & CONTENT_RELATIVE)
++ if (pcre2_info->flags & CONTENT_RELATIVE)
+ pcre_data->options |= SNORT_PCRE_RELATIVE;
+
+- if (pcre_info->flags & NOT_FLAG)
++ if (pcre2_info->flags & NOT_FLAG)
+ pcre_data->options |= SNORT_PCRE_INVERT;
+
+- if (pcre_info->flags & CONTENT_BUF_RAW)
++ if (pcre2_info->flags & CONTENT_BUF_RAW)
+ pcre_data->options |= SNORT_PCRE_RAWBYTES;
+
+- if (pcre_info->flags & CONTENT_BUF_NORMALIZED)
++ if (pcre2_info->flags & CONTENT_BUF_NORMALIZED)
+ pcre_data->options &= ~SNORT_PCRE_RAWBYTES;
+
+- pcre_data->options |= HTTP_CONTENT(pcre_info->flags);
++ pcre_data->options |= HTTP_CONTENT(pcre2_info->flags);
+
+ PcreCheckAnchored(pcre_data);
+
+@@ -584,10 +595,10 @@ static int ConvertPcreOption(SnortConfig
+ {
+ if (pcre_data->expression)
+ free(pcre_data->expression);
+- if (pcre_data->pe)
+- free(pcre_data->pe);
++ if (pcre_data->match_context)
++ pcre2MatchContextFree(pcre_data->match_context);
+ if (pcre_data->re)
+- free(pcre_data->re);
++ pcre2CodeFree(pcre_data->re);
+
+ free(pcre_data);
+ pcre_data = pcre_dup;
+--- a/src/dynamic-plugins/sf_dynamic_engine.h
++++ b/src/dynamic-plugins/sf_dynamic_engine.h
+@@ -139,11 +139,18 @@ typedef int (*DynamicDecompressFunc)(voi
+
+ #define ENGINE_DATA_VERSION 10
+
+-typedef void *(*PCRECompileFunc)(const char *, int, const char **, int *, const unsigned char *);
+-typedef void *(*PCREStudyFunc)(struct _SnortConfig *, const void *, int, const char **);
+-typedef int (*PCREExecFunc)(const void *, const void *, const char *, int, int, int, int *, int);
+-typedef void (*PCRECapture)(struct _SnortConfig *, const void *, const void *);
+-typedef void(*PCREOvectorInfo)(int **, int *);
++typedef void *(*PCRE2CompileFunc)(const char *, int, int *, size_t *, void *);
++typedef void *(*PCRE2MatchContextCreate)(const void *);
++typedef int (*PCRE2JITCompileFunc)(struct _SnortConfig *, const void *, const void *, int);
++typedef int (*PCRE2OvectorSizeFunc)(void);
++typedef void *(*PCRE2MatchDataCreateFunc)(int, const void *);
++typedef unsigned int (*PCRE2GetOvectorCountFunc)(const void *);
++typedef void *(*PCRE2GetOvectorPointerFunc)(const void *);
++typedef int (*PCRE2MatchRealFunc)(const void *, const char *, int, int, int, const void *, const void *);
++typedef void (*PCRE2MatchDataFreeFunc)(const void *);
++typedef void (*PCRE2MatchContextFreeFunc)(const void *);
++typedef void (*PCRE2CodeFreeFunc)(const void *);
++typedef void (*PCRE2Capture)(struct _SnortConfig *, const void *);
+
+ typedef struct _DynamicEngineData
+ {
+@@ -175,9 +182,15 @@ typedef struct _DynamicEngineData
+ char **debugMsgFile;
+ int *debugMsgLine;
+
+- PCRECompileFunc pcreCompile;
+- PCREStudyFunc pcreStudy;
+- PCREExecFunc pcreExec;
++ PCRE2CompileFunc pcre2Compile;
++ PCRE2MatchContextCreate pcre2MatchContextCreate;
++ PCRE2JITCompileFunc pcre2JITCompile;
++ PCRE2OvectorSizeFunc pcre2OvectorSize;
++ PCRE2MatchDataCreateFunc pcre2MatchDataCreate;
++ PCRE2GetOvectorCountFunc pcre2GetOvectorCount;
++ PCRE2GetOvectorPointerFunc pcre2GetOvectorPointer;
++ PCRE2MatchRealFunc pcre2MatchReal;
++ PCRE2MatchDataFreeFunc pcre2MatchDataFree;
+ SfUnfold sfUnfold;
+ SfBase64Decode sfbase64decode;
+ GetAltDetectFunc GetAltDetect;
+@@ -190,8 +203,7 @@ typedef struct _DynamicEngineData
+
+ UnregisterBit flowbitUnregister;
+
+- PCRECapture pcreCapture;
+- PCREOvectorInfo pcreOvectorInfo;
++ PCRE2Capture pcre2Capture;
+
+ GetHttpBufferFunc getHttpBuffer;
+ DynamicDecompressInitFunc decompressInit;
+--- a/src/dynamic-plugins/sf_dynamic_plugins.c
++++ b/src/dynamic-plugins/sf_dynamic_plugins.c
+@@ -92,7 +92,8 @@ typedef HANDLE PluginHandle;
+ #include "sf_iph.h"
+ #include "fpdetect.h"
+ #include "sfportobject.h"
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "parser.h"
+ #include "event_wrapper.h"
+ #include "util.h"
+@@ -1250,46 +1251,35 @@ void DynamicGetRuleData(void *p, const R
+ }
+ }
+
+-void *pcreCompile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr)
++void *pcre2Compile(const char *pattern, int options, int *errorcode, size_t *erroffset, void *compilecontect)
+ {
+ options &= ~SNORT_PCRE_OVERRIDE_MATCH_LIMIT;
+- return (void *)pcre_compile(pattern, options, errptr, erroffset, tableptr);
++ return (void *)pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, options, errorcode, (PCRE2_SIZE *)erroffset, (pcre2_compile_context *)compilecontect);
+ }
+
+-void *pcreStudy(struct _SnortConfig *sc, const void *code, int options, const char **errptr)
++void *pcre2MatchContextCreate(const void *generalcontext)
++{
++ return (void *)pcre2_match_context_create((pcre2_general_context *)generalcontext);
++}
++
++int pcre2JITCompile(struct _SnortConfig *sc, const void *code, const void *matchcontext, int options)
+ {
+- pcre_extra *extra_extra;
+ int snort_options = options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT;
++ int errorcode;
+
+- extra_extra = pcre_study((const pcre*)code, 0, errptr);
++ errorcode = pcre2_jit_compile((pcre2_code*)code, PCRE2_JIT_COMPLETE);
+
+- if (extra_extra)
++ if (errorcode)
+ {
+ if ((ScPcreMatchLimitNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT))
+ {
+- if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT)
+- {
+- extra_extra->match_limit = ScPcreMatchLimitNewConf(sc);
+- }
+- else
+- {
+- extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
+- extra_extra->match_limit = ScPcreMatchLimitNewConf(sc);
+- }
++ pcre2_set_match_limit((pcre2_match_context*)matchcontext, ScPcreMatchLimitNewConf(sc));
+ }
+
+ #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
+ if ((ScPcreMatchLimitRecursionNewConf(sc) != -1) && !(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT))
+ {
+- if (extra_extra->flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION)
+- {
+- extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
+- }
+- else
+- {
+- extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
+- extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
+- }
++ pcre2_set_depth_limit((pcre2_match_context*)matchcontext, ScPcreMatchLimitRecursionNewConf(sc));
+ }
+ #endif
+ }
+@@ -1298,40 +1288,62 @@ void *pcreStudy(struct _SnortConfig *sc,
+ if (!(snort_options & SNORT_PCRE_OVERRIDE_MATCH_LIMIT) &&
+ ((ScPcreMatchLimitNewConf(sc) != -1) || (ScPcreMatchLimitRecursionNewConf(sc) != -1)))
+ {
+- extra_extra = (pcre_extra *)SnortAlloc(sizeof(pcre_extra));
+ if (ScPcreMatchLimitNewConf(sc) != -1)
+ {
+- extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
+- extra_extra->match_limit = ScPcreMatchLimitNewConf(sc);
++ pcre2_set_match_limit((pcre2_match_context*)matchcontext, ScPcreMatchLimitNewConf(sc));
+ }
+
+ #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
+ if (ScPcreMatchLimitRecursionNewConf(sc) != -1)
+ {
+- extra_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
+- extra_extra->match_limit_recursion = ScPcreMatchLimitRecursionNewConf(sc);
++ pcre2_set_depth_limit((pcre2_match_context*)matchcontext, ScPcreMatchLimitRecursionNewConf(sc));
+ }
+ #endif
+ }
+ }
+
+- return extra_extra;
++ return errorcode;
++}
++
++int pcre2OvectorSize(void)
++{
++ return snort_conf->pcre_ovector_size;
++}
++
++void *pcre2MatchDataCreate(int size, const void *generalcontext)
++{
++ return pcre2_match_data_create(size, (pcre2_general_context *)generalcontext);
++}
++
++unsigned int pcre2GetOvectorCount(const void *match_data)
++{
++ return pcre2_get_ovector_count((pcre2_match_data *)match_data);
++}
++
++void *pcre2GetOvectorPointer(const void *match_data)
++{
++ return pcre2_get_ovector_pointer((pcre2_match_data *)match_data);
++}
++
++int pcre2MatchReal(const void *code, const char *subj,
++ int len, int start, int options, const void *matchdata, const void *matchcontext)
++{
++ return pcre2_match((const pcre2_code *)code, (PCRE2_SPTR)subj, len, start, options, (pcre2_match_data *)matchdata, (pcre2_match_context *)matchcontext);
++}
++
++void pcre2MatchDataFree(const void *match_data)
++{
++ pcre2_match_data_free((pcre2_match_data *)match_data);
+ }
+
+-/* pcreOvectorInfo
+- *
+- * Get the Ovector configuration for PCRE from the snort.conf
+- */
+-void pcreOvectorInfo(int **ovector, int *ovector_size)
++void pcre2MatchContextFree(const void *code)
+ {
+- *ovector = snort_conf->pcre_ovector;
+- *ovector_size = snort_conf->pcre_ovector_size;
++ pcre2_match_context_free((pcre2_match_context *)code);
+ }
+
+-int pcreExec(const void *code, const void *extra, const char *subj,
+- int len, int start, int options, int *ovec, int ovecsize)
++void pcre2CodeFree(const void *code)
+ {
+- return pcre_exec((const pcre *)code, (const pcre_extra *)extra, subj, len, start, options, ovec, ovecsize);
++ pcre2_code_free((pcre2_code *)code);
+ }
+
+ static int setFlowId(const void* p, uint32_t id)
+@@ -1415,17 +1427,22 @@ int InitDynamicEngines(char *dynamic_rul
+ engineData.debugMsgLine = &no_line;
+ #endif
+
+- engineData.pcreStudy = &pcreStudy;
+- engineData.pcreCompile = &pcreCompile;
+- engineData.pcreExec = &pcreExec;
++ engineData.pcre2JITCompile = &pcre2JITCompile;
++ engineData.pcre2MatchContextCreate = &pcre2MatchContextCreate;
++ engineData.pcre2Compile = &pcre2Compile;
++ engineData.pcre2OvectorSize = &pcre2OvectorSize;
++ engineData.pcre2MatchDataCreate = &pcre2MatchDataCreate;
++ engineData.pcre2GetOvectorCount = &pcre2GetOvectorCount;
++ engineData.pcre2GetOvectorPointer = &pcre2GetOvectorPointer;
++ engineData.pcre2MatchReal = &pcre2MatchReal;
++ engineData.pcre2MatchDataFree = &pcre2MatchDataFree;
+
+ engineData.allocRuleData = &DynamicRuleDataAlloc;
+ engineData.freeRuleData = &DynamicRuleDataFree;
+
+ engineData.flowbitUnregister = &DynamicFlowbitUnregister;
+
+- engineData.pcreCapture = &PcreCapture;
+- engineData.pcreOvectorInfo = &pcreOvectorInfo;
++ engineData.pcre2Capture = &Pcre2Capture;
+ engineData.getHttpBuffer = getHttpBuffer;
+
+ engineData.decompressInit = &DynamicDecompressInit;
+--- a/src/dynamic-plugins/sf_engine/examples/3036.c
++++ b/src/dynamic-plugins/sf_engine/examples/3036.c
+@@ -104,7 +104,7 @@ static RuleOption rule3036option3 =
+ { &rule3036byte_test3 }
+ };
+ // pcre:"^.{27}", relative;
+-static PCREInfo rule3036pcre4 =
++static PCRE2Info rule3036pcre4 =
+ {
+ "^.{27}", /* pattern */
+ NULL, /* holder for compiled pattern */
+@@ -166,7 +166,7 @@ static RuleOption rule3036option6 =
+ { &rule3036byte_jump6 }
+ };
+ // pcre:"^.{4}", relative;
+-static PCREInfo rule3036pcre7 =
++static PCRE2Info rule3036pcre7 =
+ {
+ "^.{4}", /* pattern */
+ NULL, /* holder for compiled pattern */
+@@ -325,13 +325,13 @@ int rule3036eval(void *p) {
+ // byte_test:size 1, value 128, operator &, offset 6, relative;
+ if (byteTest(p, rule3036options[3]->option_u.byte, cursor_normal) > 0) {
+ // pcre:"^.{27}", relative;
+- if (pcreMatch(p, rule3036options[4]->option_u.pcre, &cursor_normal)) {
++ if (pcre2Match(p, rule3036options[4]->option_u.pcre2, &cursor_normal)) {
+ // content:"|01 00|", offset 37, depth 2, relative;
+ if (contentMatch(p, rule3036options[5]->option_u.content, &cursor_normal) > 0) {
+ // byte_jump:size 4, offset -7, relative, endian little;
+ if (byteJump(p, rule3036options[6]->option_u.byte, &cursor_normal) > 0) {
+ // pcre:"^.{4}", relative;
+- if (pcreMatch(p, rule3036options[7]->option_u.pcre, &cursor_normal)) {
++ if (pcre2Match(p, rule3036options[7]->option_u.pcre2, &cursor_normal)) {
+ // content:"|00 00 00 00|", offset 16, depth 4, relative;
+ if (!(contentMatch(p, rule3036options[8]->option_u.content, &cursor_normal) > 0)) {
+ // byte_jump:size 4, offset 16, relative, endian little;
+--- a/src/dynamic-plugins/sf_engine/examples/3052.c
++++ b/src/dynamic-plugins/sf_engine/examples/3052.c
+@@ -93,7 +93,7 @@ static RuleOption rule3052option2 =
+ { &rule3052byte_test2 }
+ };
+ // pcre:"^.{27}", relative;
+-static PCREInfo rule3052pcre3 =
++static PCRE2Info rule3052pcre3 =
+ {
+ "^.{27}", /* pattern */
+ NULL, /* holder for compiled pattern */
+@@ -155,7 +155,7 @@ static RuleOption rule3052option5 =
+ { &rule3052byte_jump5 }
+ };
+ // pcre:"^.{4}", relative;
+-static PCREInfo rule3052pcre6 =
++static PCRE2Info rule3052pcre6 =
+ {
+ "^.{4}", /* pattern */
+ NULL, /* holder for compiled pattern */
+@@ -307,13 +307,13 @@ int rule3052eval(void *p) {
+ // byte_test:size 1, value 128, operator &, offset 6, relative;
+ if (byteTest(p, rule3052options[2]->option_u.byte, cursor_normal) > 0) {
+ // pcre:"^.{27}", relative;
+- if (pcreMatch(p, rule3052options[3]->option_u.pcre, &cursor_normal)) {
++ if (pcre2Match(p, rule3052options[3]->option_u.pcre2, &cursor_normal)) {
+ // content:"|01 00|", offset 37, depth 2, relative;
+ if (contentMatch(p, rule3052options[4]->option_u.content, &cursor_normal) > 0) {
+ // byte_jump:size 4, offset -7, relative, endian little;
+ if (byteJump(p, rule3052options[5]->option_u.byte, &cursor_normal) > 0) {
+ // pcre:"^.{4}", relative;
+- if (pcreMatch(p, rule3052options[6]->option_u.pcre, &cursor_normal)) {
++ if (pcre2Match(p, rule3052options[6]->option_u.pcre2, &cursor_normal)) {
+ // content:"|00 00 00 00|", offset 16, depth 4, relative;
+ if (!(contentMatch(p, rule3052options[7]->option_u.content, &cursor_normal) > 0)) {
+ // byte_jump:size 4, offset 16, relative, endian little;
+--- a/src/dynamic-plugins/sf_engine/examples/3099.c
++++ b/src/dynamic-plugins/sf_engine/examples/3099.c
+@@ -104,7 +104,7 @@ static RuleOption rule3099option3 =
+ { &rule3099byte_test3 }
+ };
+ // pcre:"^.{27}", relative;
+-static PCREInfo rule3099pcre4 =
++static PCRE2Info rule3099pcre4 =
+ {
+ "^.{27}", /* pattern */
+ NULL, /* holder for compiled pattern */
+@@ -191,7 +191,7 @@ static RuleOption rule3099option7 =
+ { &rule3099byte_jump7 }
+ };
+ // pcre:"^.{4}", relative;
+-static PCREInfo rule3099pcre8 =
++static PCRE2Info rule3099pcre8 =
+ {
+ "^.{4}", /* pattern */
+ NULL, /* holder for compiled pattern */
+@@ -392,7 +392,7 @@ int rule3099eval(void *p) {
+ // byte_test:size 1, value 128, operator &, offset 6, relative;
+ if (!(byteTest(p, rule3099options[3]->option_u.byte, cursor_normal) > 0)) {
+ // pcre:"^.{27}", relative;
+- if (pcreMatch(p, rule3099options[4]->option_u.pcre, &cursor_normal)) {
++ if (pcre2Match(p, rule3099options[4]->option_u.pcre2, &cursor_normal)) {
+ // content:"&|00|", offset 29, depth 2, relative;
+ if (contentMatch(p, rule3099options[5]->option_u.content, &cursor_normal) > 0) {
+ // content:"|5C|PIPE|5C 00|", offset 4, nocase, relative;
+@@ -400,7 +400,7 @@ int rule3099eval(void *p) {
+ // byte_jump:size 2, offset -17, relative, endian little;
+ if (byteJump(p, rule3099options[7]->option_u.byte, &cursor_normal) > 0) {
+ // pcre:"^.{4}", relative;
+- if (pcreMatch(p, rule3099options[8]->option_u.pcre, &cursor_normal)) {
++ if (pcre2Match(p, rule3099options[8]->option_u.pcre2, &cursor_normal)) {
+ // content:"|05|", depth 1, relative;
+ if (contentMatch(p, rule3099options[9]->option_u.content, &cursor_normal) > 0) {
+ // byte_test:size 1, value 16, operator &, offset 3, relative;
+--- a/src/dynamic-plugins/sf_engine/examples/36733.c
++++ b/src/dynamic-plugins/sf_engine/examples/36733.c
+@@ -25,7 +25,8 @@
+ #include "config.h"
+ #endif
+
+-#include "pcre.h"
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "sf_snort_plugin_api.h"
+ #include "sf_snort_packet.h"
+ #include "web-misc_base64_decode.h"
+@@ -80,12 +81,12 @@ static RuleOption ruleAPACHEAUTHLDAPopti
+ };
+
+ // pcre:"/^Authorization:\s*Basic/mi";
+-static PCREInfo ruleAPACHEAUTHLDAPpcre0 =
++static PCRE2Info ruleAPACHEAUTHLDAPpcre0 =
+ {
+ "^Authorization:\\s*Basic\\s+", /* pattern (now in snort content format) */
+ 0, /* compiled expression */
+ 0, /* compiled extra */
+- PCRE_CASELESS | PCRE_MULTILINE, /* compile flags */
++ PCRE2_CASELESS | PCRE2_MULTILINE, /* compile flags */
+ CONTENT_BUF_NORMALIZED, /* flags */ // XXX - need to add CONTENT_FAST_PATTERN support
+ 0 /* offset */
+ };
+@@ -99,7 +100,7 @@ static RuleOption ruleAPACHEAUTHLDAPopti
+ };
+
+ // pcre:"/%[0-9]*\.?[0-9]*[:formatspecifiers:]/";
+-static PCREInfo ruleAPACHEAUTHLDAPpcre1 =
++static PCRE2Info ruleAPACHEAUTHLDAPpcre1 =
+ {
+ // "%[-# +'I]*[0-9]*\\.?[0-9]*[qjzthdiouxefgcrslnp]", /* pattern (now in snort content format) */ // ZDNOTE
+ "%.+%.", /* regex. The above is technically more correct, but this is faster and good enough */
+@@ -191,7 +192,7 @@ static int ruleAPACHEAUTHLDAPeval(void *
+
+ // manual pcre stuff
+ int result;
+- int ovector[3]; // Needs to be a multiple of 3
++ void *match_data;
+
+ if(sp == NULL)
+ return RULE_NOMATCH;
+@@ -221,7 +222,7 @@ static int ruleAPACHEAUTHLDAPeval(void *
+ //DEBUG_WRAP(printf("found content:\"Authorization:\" %p\n", cursor));
+
+ // pcre:"/^Authorization:\s*Basic\s+/mi"
+- if(pcreMatch(p, ruleAPACHEAUTHLDAPoptions[2]->option_u.pcre, &cursor) <= 0)
++ if(pcre2Match(p, ruleAPACHEAUTHLDAPoptions[2]->option_u.pcre2, &cursor) <= 0)
+ return RULE_NOMATCH;
+
+ //DEBUG_WRAP(printf("found pcre:\"/^Authorization:\\s*Basic\\s+/mi\" %p\n", cursor));
+@@ -238,14 +239,35 @@ static int ruleAPACHEAUTHLDAPeval(void *
+
+ //DEBUG_WRAP(printf("Successfully base64 decoded (%s)(%d)\n", decodedbuf, decodedbytes));
+
++ match_data = pcre2MatchDataCreateWrapper();
++ if (!match_data)
++ return RULE_NOMATCH;
++
+ // Now run our regex on the base64 decoding to find an attack
+- result = pcreExecWrapper(ruleAPACHEAUTHLDAPoptions[3]->option_u.pcre,
++ result = pcre2MatchWrapper(ruleAPACHEAUTHLDAPoptions[3]->option_u.pcre2,
+ (char *)decodedbuf, // subject string
+ decodedbytes, // subject length
+ 0, // start offset
+ 0, // options (handled at compile time)
+- ovector, // ovector for storing result substrings
+- sizeof(ovector)/sizeof(int)); // size of ovector
++ match_data); // size of ovector
++
++ /* If ovector is required:
++ * 1. declare a size_t *ovector
++ * 2. after pcre2ExecWrapper...
++ * 3. ovector = pcre2GetOvectorPointer(match_data);
++ * 4. Use ovector as old implementation
++ *
++ * If required ovector_size:
++ * 1. declare a unsigned int ovector_size
++ * 2. after pcre2ExecWrapper...
++ * 3. ovector_size = pcre2GetOvectorCount(match_data);
++ * 4. User ovector_size as old implementation
++ *
++ * ALWAYS REMEMBER TO USE THE MATCH DATA CREATE AND FREE BEFORE
++ * EXEC WRAPPER
++ */
++
++ pcre2MatchDataFreeWrapper(match_data);
+
+ //DEBUG_WRAP(printf("result = %d\n", result));
+
+--- a/src/dynamic-plugins/sf_engine/examples/3682.c
++++ b/src/dynamic-plugins/sf_engine/examples/3682.c
+@@ -9,7 +9,8 @@
+ #include "config.h"
+ #endif
+
+-#include "pcre.h"
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "sf_snort_plugin_api.h"
+ #include "sf_snort_packet.h"
+ #include "detection_lib_meta.h"
+@@ -103,12 +104,12 @@ static RuleOption rule3682option3 =
+
+ /* pcre for sid 3682 */
+ //pcre:"/Content-Type\x3A\s+audio\/(x-wav|mpeg|x-midi)/i";
+-static PCREInfo rule3682pcre4 =
++static PCRE2Info rule3682pcre4 =
+ {
+ "Content-Type\\x3A\\s+audio\\/(x-wav|mpeg|x-midi)", /* expression */
+ NULL, /* Holder for compiled expr */
+ NULL, /* Holder for compiled expr extra flags */
+- PCRE_CASELESS, /* Compile Flags */
++ PCRE2_CASELESS, /* Compile Flags */
+ CONTENT_BUF_NORMALIZED, /* Flags */
+ 0 /* offset */
+ };
+@@ -148,12 +149,12 @@ static RuleOption rule3682option5 =
+
+ /* pcre for sid 3682 */
+ //pcre:"/filename=[\x22\x27]?.{1,221}\.(vbs|exe|scr|pif|bat)/i";
+-static PCREInfo rule3682pcre6 =
++static PCRE2Info rule3682pcre6 =
+ {
+ "filename=[\\x22\\x27]?.{1,221}\\.(vbs|exe|scr|pif|bat)", /* expression */
+ NULL, /* Holder for compiled expr */
+ NULL, /* Holder for compiled expr extra flags */
+- PCRE_CASELESS, /* Compile Flags */
++ PCRE2_CASELESS, /* Compile Flags */
+ CONTENT_BUF_NORMALIZED, /* Flags */
+ 0 /* offset */
+ };
+--- a/src/dynamic-plugins/sf_engine/examples/bug31842.c
++++ b/src/dynamic-plugins/sf_engine/examples/bug31842.c
+@@ -25,7 +25,8 @@
+ #include "config.h"
+ #endif
+
+-#include "pcre.h"
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "sf_snort_plugin_api.h"
+ #include "sf_snort_packet.h"
+
+@@ -89,12 +90,12 @@ static RuleOption ruleSQUID_NTLM_AUTHopt
+ }
+ };
+
+-static PCREInfo ruleSQUID_NTLM_AUTHpcre =
++static PCRE2Info ruleSQUID_NTLM_AUTHpcre =
+ {
+ "^Proxy-Authorization:\\s*NTLM\\s+", /* pattern to search for */
+ NULL, /* holder for compiled pattern */
+ NULL, /* holder for compiled pattern flags */
+- PCRE_CASELESS | PCRE_DOTALL | PCRE_MULTILINE, /* compile flags */
++ PCRE2_CASELESS | PCRE2_DOTALL | PCRE2_MULTILINE, /* compile flags */
+ CONTENT_BUF_NORMALIZED, /* content flags */
+ 0 /* offset */
+ };
+@@ -336,7 +337,7 @@ int ruleSQUID_NTLM_AUTHeval(void *p) {
+ }
+
+ /* call pcre match */
+- if (pcreMatch(p, ruleSQUID_NTLM_AUTHoptions[2]->option_u.pcre, &cursor) <= 0) {
++ if (pcre2Match(p, ruleSQUID_NTLM_AUTHoptions[2]->option_u.pcre2, &cursor) <= 0) {
+ return RULE_NOMATCH;
+ }
+
+--- a/src/dynamic-plugins/sf_engine/examples/bug35218.c
++++ b/src/dynamic-plugins/sf_engine/examples/bug35218.c
+@@ -26,7 +26,8 @@
+ #include "config.h"
+ #endif
+
+-#include "pcre.h"
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "sf_snort_plugin_api.h"
+ #include "sf_snort_packet.h"
+
+@@ -97,12 +98,12 @@ static RuleOption ruleEXCHANGE_BASE64_DE
+ }
+ };
+
+-static PCREInfo ruleEXCHANGE_BASE64_DECODEpcre0 =
++static PCRE2Info ruleEXCHANGE_BASE64_DECODEpcre0 =
+ {
+ "^Content-Transfer-Encoding:\\s*base64\\s*$", /* pattern to search for */
+ NULL, /* compiled_expr */
+ 0, /* compiled_extra */
+- PCRE_CASELESS | PCRE_MULTILINE, /* compile_flags */
++ PCRE2_CASELESS | PCRE2_MULTILINE, /* compile_flags */
+ CONTENT_BUF_RAW, /* flags: must include a CONTENT_BUF_X */
+ 0 /* offset */
+ };
+@@ -119,12 +120,12 @@ static RuleOption ruleEXCHANGE_BASE64_DE
+ /* Second PCRE just like above but with CONTENT_RELATIVE so we can find
+ additional base64 sections if they exist.
+ */
+-static PCREInfo ruleEXCHANGE_BASE64_DECODEpcre1 =
++static PCRE2Info ruleEXCHANGE_BASE64_DECODEpcre1 =
+ {
+ "^Content-Transfer-Encoding:\\s*base64\\s*$", /* pattern to search for */
+ NULL, /* compiled_expr */
+ 0, /* compiled_extra */
+- PCRE_CASELESS | PCRE_MULTILINE, /* compile_flags */
++ PCRE2_CASELESS | PCRE2_MULTILINE, /* compile_flags */
+ CONTENT_BUF_RAW | CONTENT_RELATIVE, /* flags: must include a CONTENT_BUF_X */
+ 0 /* offset */
+ };
+@@ -214,7 +215,7 @@ int ruleEXCHANGE_BASE64_DECODEeval(void
+ }
+
+ /* call pcre match */
+- if (pcreMatch(sp, ruleEXCHANGE_BASE64_DECODEoptions[2]->option_u.pcre, &cursor_normal) <= 0) {
++ if (pcre2Match(sp, ruleEXCHANGE_BASE64_DECODEoptions[2]->option_u.pcre2, &cursor_normal) <= 0) {
+ return RULE_NOMATCH;
+ }
+
+@@ -286,7 +287,7 @@ int ruleEXCHANGE_BASE64_DECODEeval(void
+
+ } else { /* !in_base64_content */
+ // Find the next base64 content the easy way
+- if(pcreMatch(sp, ruleEXCHANGE_BASE64_DECODEoptions[3]->option_u.pcre, &cursor_normal) <= 0)
++ if(pcre2Match(sp, ruleEXCHANGE_BASE64_DECODEoptions[3]->option_u.pcre2, &cursor_normal) <= 0)
+ return RULE_NOMATCH;
+
+ // Another base64 section was found, set up for another loop
+--- a/src/dynamic-plugins/sf_engine/examples/sid1902.c
++++ b/src/dynamic-plugins/sf_engine/examples/sid1902.c
+@@ -12,7 +12,8 @@
+ #include "config.h"
+ #endif
+
+-#include "pcre.h"
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "sf_snort_plugin_api.h"
+ #include "sf_snort_packet.h"
+
+@@ -59,12 +60,12 @@ static RuleOption rule1902option1 =
+ { &rule1902content1 }
+ };
+ // pcre:"\sLSUB\s[^\n]*?\s\{", dotall, multiline, nocase;
+-static PCREInfo rule1902pcre2 =
++static PCRE2Info rule1902pcre2 =
+ {
+ "\\sLSUB\\s[^\\n]*?\\s\\{", /* pattern */
+ NULL, /* holder for compiled pattern */
+ NULL, /* holder for compiled pattern flags */
+- PCRE_CASELESS|PCRE_DOTALL|PCRE_MULTILINE, /* compile flags */
++ PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_MULTILINE, /* compile flags */
+ CONTENT_BUF_NORMALIZED, /* content flags */
+ 0 /* offset */
+ };
+@@ -177,7 +178,7 @@ int rule1902eval(void *p) {
+ // content:"LSUB", nocase;
+ if (contentMatch(p, rule1902options[1]->option_u.content, &cursor_normal) > 0) {
+ // pcre:"\sLSUB\s[^\n]*?\s\{", dotall, multiline, nocase;
+- if (pcreMatch(p, rule1902options[2]->option_u.pcre, &cursor_normal)) {
++ if (pcre2Match(p, rule1902options[2]->option_u.pcre2, &cursor_normal)) {
+ // byte_test:size 5, value 256, operator >, relative, representation dec;
+ if (byteTest(p, rule1902options[3]->option_u.byte, cursor_normal) > 0) {
+ return RULE_MATCH;
+--- a/src/dynamic-plugins/sf_engine/examples/sid2389.c
++++ b/src/dynamic-plugins/sf_engine/examples/sid2389.c
+@@ -6,7 +6,8 @@
+ #include "config.h"
+ #endif
+
+-#include "pcre.h"
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "sf_snort_plugin_api.h"
+ #include "detection_lib_meta.h"
+
+@@ -113,12 +114,12 @@ static RuleOption option2 =
+ { &content1 }
+ };
+
+-static PCREInfo pcre1 =
++static PCRE2Info pcre1 =
+ { /* PCRE */
+ "^RNTO\\s[^\\n]{100}", /* expression */
+ NULL, /* Holder for compiled expr */
+ NULL, /* Holder for compiled expr extra flags */
+- PCRE_DOTALL | PCRE_MULTILINE | PCRE_CASELESS, /* Compile Flags */
++ PCRE2_DOTALL | PCRE2_MULTILINE | PCRE2_CASELESS, /* Compile Flags */
+ CONTENT_BUF_NORMALIZED, /* Flags */
+ 0 /* offset */
+ };
+@@ -178,7 +179,7 @@ int sid2389Eval(void *p)
+ if (contentMatch(p, sid2389.options[1]->option_u.content, &norm_cur)>0)
+ {
+ /* Not relative to norm cursor */
+- if (pcreMatch(p, sid2389.options[2]->option_u.pcre, NULL))
++ if (pcre2Match(p, sid2389.options[2]->option_u.pcre2, NULL))
+ {
+ return RULE_MATCH;
+ }
+--- a/src/dynamic-plugins/sf_engine/examples/sid9999.c
++++ b/src/dynamic-plugins/sf_engine/examples/sid9999.c
+@@ -159,7 +159,7 @@ static CursorInfo loopCursor =
+ /* these don't get structures... lets hope this works :) */
+ /* pcre for sid 9999 */
+ // pcre:"^[rbg]XYZ", relative;
+-static PCREInfo rule9999pcre7 =
++static PCRE2Info rule9999pcre7 =
+ {
+ "^[rbg]XYZ", /* pattern */
+ NULL, /* holder for compiled pattern */
+--- a/src/dynamic-plugins/sf_engine/examples/web-client_test.c
++++ b/src/dynamic-plugins/sf_engine/examples/web-client_test.c
+@@ -85,12 +85,12 @@ static RuleOption rule64111option1 =
+ };
+
+ // pcre:"IIS 7\x2e5 Detailed Error - 404\x2e0 - Not Found", nocase;
+-static PCREInfo rule64111pcre2 =
++static PCRE2Info rule64111pcre2 =
+ {
+ "IIS 7\\x2e5 Detailed Error - 404\\x2e0 - Not Found", /* pattern */
+ NULL, /* holder for compiled pattern */
+ NULL, /* holder for compiled pattern flags */
+- PCRE_CASELESS, /* compile flags */
++ PCRE2_CASELESS, /* compile flags */
+ CONTENT_BUF_NORMALIZED, /* content flags */
+ 0 /* offset */
+ };
+@@ -256,12 +256,12 @@ static RuleOption rule64222option2 =
+ };
+
+ // pcre:"SignUrl=[^\x26\s]*[\x22\x27\x28\x29\x3C\x3E]", payload uri, nocase;
+-static PCREInfo rule64222pcre3 =
++static PCRE2Info rule64222pcre3 =
+ {
+ "SignUrl=[^\\x26\\s]*[\\x22\\x27\\x28\\x29\\x3C\\x3E]", /* pattern */
+ NULL, /* holder for compiled pattern */
+ NULL, /* holder for compiled pattern flags */
+- PCRE_CASELESS, /* compile flags */
++ PCRE2_CASELESS, /* compile flags */
+ CONTENT_BUF_URI, /* content flags */
+ 0 /* offset */
+ };
+@@ -428,12 +428,12 @@ static RuleOption rule64333option2 =
+ };
+
+ // pcre:"SignUrl=[^\\x26\\s]*[\\x22\\x27\\x28\\x29\\x3C\\x3E]", payload uri, nocase;
+-static PCREInfo rule64333pcre3 =
++static PCRE2Info rule64333pcre3 =
+ {
+ "SignUrl=[^\\\\x26\\\\s]*[\\\\x22\\\\x27\\\\x28\\\\x29\\\\x3C\\\\x3E]", /* pattern */
+ NULL, /* holder for compiled pattern */
+ NULL, /* holder for compiled pattern flags */
+- PCRE_CASELESS, /* compile flags */
++ PCRE2_CASELESS, /* compile flags */
+ CONTENT_BUF_URI, /* content flags */
+ 0 /* offset */
+ };
+@@ -550,7 +550,7 @@ int rule64111eval(void *p) {
+ // content:"IIS 7.5 Detailed Error - 404.0 - Not Found", depth 0, nocase, fast_pattern;
+ if (contentMatch(p, rule64111options[1]->option_u.content, &cursor_normal) > 0) {
+ // pcre:"IIS 7\x2e5 Detailed Error - 404\x2e0 - Not Found", nocase;
+- if (pcreMatch(p, rule64111options[2]->option_u.pcre, &cursor_normal)) {
++ if (pcre2Match(p, rule64111options[2]->option_u.pcre2, &cursor_normal)) {
+ return RULE_MATCH;
+ }
+ }
+@@ -576,7 +576,7 @@ int rule64222eval(void *p) {
+ // content:"SignUrl=", payload http_uri, depth 0, nocase;
+ if (contentMatch(p, rule64222options[2]->option_u.content, &cursor_http_uri) > 0) {
+ // pcre:"SignUrl=[^\x26\s]*[\x22\x27\x28\x29\x3C\x3E]", payload uri, nocase;
+- if (pcreMatch(p, rule64222options[3]->option_u.pcre, &cursor_uri)) {
++ if (pcre2Match(p, rule64222options[3]->option_u.pcre2, &cursor_uri)) {
+ return RULE_MATCH;
+ }
+ }
+@@ -603,7 +603,7 @@ int rule64333eval(void *p) {
+ // content:"SignUrl=", payload http_uri, depth 0, nocase;
+ if (contentMatch(p, rule64333options[2]->option_u.content, &cursor_http_uri) > 0) {
+ // pcre:"SignUrl=[^\\x26\\s]*[\\x22\\x27\\x28\\x29\\x3C\\x3E]", payload uri, nocase;
+- if (pcreMatch(p, rule64333options[3]->option_u.pcre, &cursor_uri)) {
++ if (pcre2Match(p, rule64333options[3]->option_u.pcre2, &cursor_uri)) {
+ return RULE_MATCH;
+ }
+ }
+--- a/src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c
++++ b/src/dynamic-plugins/sf_engine/sf_snort_detection_engine.c
+@@ -899,11 +899,11 @@ int RegisterOneRule(struct _SnortConfig
+ break;
+ case OPTION_TYPE_PCRE:
+ {
+- PCREInfo *pcre = option->option_u.pcre;
++ PCRE2Info *pcre2 = option->option_u.pcre2;
+
+- if (pcre->compiled_expr == NULL)
++ if (pcre2->compiled_expr == NULL)
+ {
+- if (PCRESetup(sc, rule, pcre))
++ if (PCRE2Setup(sc, rule, pcre2))
+ {
+ rule->initialized = 0;
+ FreeOneRule(rule);
+@@ -1120,18 +1120,18 @@ static void FreeOneRule(void *data)
+
+ case OPTION_TYPE_PCRE:
+ {
+- PCREInfo *pcre = option->option_u.pcre;
++ PCRE2Info *pcre2 = option->option_u.pcre2;
+
+- if (pcre->compiled_expr != NULL)
++ if (pcre2->match_context != NULL)
+ {
+- free(pcre->compiled_expr);
+- pcre->compiled_expr = NULL;
++ pcre2_match_context_free(pcre2->match_context);
++ pcre2->match_context = NULL;
+ }
+
+- if (pcre->compiled_extra != NULL)
++ if (pcre2->compiled_expr != NULL)
+ {
+- free(pcre->compiled_extra);
+- pcre->compiled_extra = NULL;
++ pcre2_code_free(pcre2->compiled_expr);
++ pcre2->compiled_expr = NULL;
+ }
+ }
+
+--- a/src/dynamic-plugins/sf_engine/sf_snort_detection_engine.h
++++ b/src/dynamic-plugins/sf_engine/sf_snort_detection_engine.h
+@@ -30,7 +30,7 @@
+ #define SF_SNORT_DETECTION_ENGINE__H
+
+ int BoyerContentSetup(Rule *rule, ContentInfo *content);
+-int PCRESetup(struct _SnortConfig *sc, Rule *rule, PCREInfo *pcreInfo);
++int PCRE2Setup(struct _SnortConfig *sc, Rule *rule, PCRE2Info *pcre2Info);
+ int ValidateHeaderCheck(Rule *rule, HdrOptCheck *optData);
+ void ContentSetup(void);
+ int ByteExtractInitialize(Rule *rule, ByteExtract *extractData);
+--- a/src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c
++++ b/src/dynamic-plugins/sf_engine/sf_snort_plugin_api.c
+@@ -640,7 +640,7 @@ int isRelativeOption(RuleOption *option)
+ relative = option->option_u.content->flags & CONTENT_RELATIVE;
+ break;
+ case OPTION_TYPE_PCRE:
+- relative = option->option_u.pcre->flags & CONTENT_RELATIVE;
++ relative = option->option_u.pcre2->flags & CONTENT_RELATIVE;
+ break;
+ case OPTION_TYPE_FLOWBIT:
+ /* Never relative */
+@@ -716,7 +716,7 @@ int ruleMatchInternal(SFSnortPacket *p,
+ int32_t origOffset = 0;
+ uint32_t origDepth = 0;
+ int continueLoop = 1;
+- PCREInfo *thisPCREInfo = NULL;
++ PCRE2Info *thisPCREInfo = NULL;
+
+ if (cursor)
+ startCursor = thisCursor = *cursor;
+@@ -736,7 +736,7 @@ int ruleMatchInternal(SFSnortPacket *p,
+ origOffset = thisContentInfo->offset;
+ break;
+ case OPTION_TYPE_PCRE:
+- thisPCREInfo = rule->options[optIndex]->option_u.pcre;
++ thisPCREInfo = rule->options[optIndex]->option_u.pcre2;
+ origFlags = thisPCREInfo->flags;
+ origOffset = thisPCREInfo->offset;
+ break;
+@@ -760,8 +760,8 @@ int ruleMatchInternal(SFSnortPacket *p,
+ notFlag = rule->options[optIndex]->option_u.protectedContent->flags & NOT_FLAG;
+ break;
+ case OPTION_TYPE_PCRE:
+- retVal = pcreMatch(p, rule->options[optIndex]->option_u.pcre, &thisCursor);
+- notFlag = rule->options[optIndex]->option_u.pcre->flags & NOT_FLAG;
++ retVal = pcre2Match(p, rule->options[optIndex]->option_u.pcre2, &thisCursor);
++ notFlag = rule->options[optIndex]->option_u.pcre2->flags & NOT_FLAG;
+ break;
+ case OPTION_TYPE_FLOWBIT:
+ retVal = processFlowbits(p, rule->options[optIndex]->option_u.flowBit);
+--- a/src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h
++++ b/src/dynamic-plugins/sf_engine/sf_snort_plugin_api.h
+@@ -30,7 +30,8 @@
+ #ifndef SF_SNORT_PLUGIN_API_H_
+ #define SF_SNORT_PLUGIN_API_H_
+
+-#include "pcre.h"
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "stdio.h"
+
+ #ifndef WIN32
+@@ -211,26 +212,26 @@ typedef struct _CursorInfo
+ } CursorInfo;
+
+ /*
+-pcre.h provides flags:
++pcre2.h provides flags:
+
+-PCRE_CASELESS
+-PCRE_MULTILINE
+-PCRE_DOTALL
+-PCRE_EXTENDED
+-PCRE_ANCHORED
+-PCRE_DOLLAR_ENDONLY
+-PCRE_UNGREEDY
++PCRE2_CASELESS
++PCRE2_MULTILINE
++PCRE2_DOTALL
++PCRE2_EXTENDED
++PCRE2_ANCHORED
++PCRE2_DOLLAR_ENDONLY
++PCRE2_UNGREEDY
+ */
+
+-typedef struct _PCREInfo
++typedef struct _PCRE2Info
+ {
+ char *expr;
+ void *compiled_expr;
+- void *compiled_extra;
++ void *match_context;
+ uint32_t compile_flags;
+ uint32_t flags; /* must include a CONTENT_BUF_X */
+ int32_t offset;
+-} PCREInfo;
++} PCRE2Info;
+
+ #define FLOWBIT_SET 0x01
+ #define FLOWBIT_UNSET 0x02
+@@ -393,7 +394,7 @@ typedef struct _RuleOption
+ ContentInfo *content;
+ ProtectedContentInfo *protectedContent;
+ CursorInfo *cursor;
+- PCREInfo *pcre;
++ PCRE2Info *pcre2;
+ FlowBitsInfo *flowBit;
+ ByteData *byte;
+ ByteExtract *byteExtract;
+@@ -482,7 +483,7 @@ ENGINE_LINKAGE int byteTest(void *p, Byt
+ ENGINE_LINKAGE int byteMath(void *p, ByteData *byteData, const uint8_t *cursor);
+ /* Same as extractValue plus setCursor */
+ ENGINE_LINKAGE int byteJump(void *p, ByteData *byteData, const uint8_t **cursor);
+-ENGINE_LINKAGE int pcreMatch(void *p, PCREInfo* pcre, const uint8_t **cursor);
++ENGINE_LINKAGE int pcre2Match(void *p, PCRE2Info* pcre2, const uint8_t **cursor);
+ ENGINE_LINKAGE int detectAsn1(void *p, Asn1Context* asn1, const uint8_t *cursor);
+ ENGINE_LINKAGE int checkHdrOpt(void *p, HdrOptCheck *optData);
+ ENGINE_LINKAGE int loopEval(void *p, LoopInfo *loop, const uint8_t **cursor);
+@@ -506,8 +507,12 @@ ENGINE_LINKAGE void detectFlagDisable(SF
+ ENGINE_LINKAGE int getAltDetect(uint8_t **bufPtr, uint16_t *altLenPtr);
+ ENGINE_LINKAGE void setAltDetect(uint8_t *buf, uint16_t altLen);
+
+-ENGINE_LINKAGE int pcreExecWrapper(const PCREInfo *pcre_info, const char *buf, int len, int start_offset,
+- int options, int *ovector, int ovecsize);
++ENGINE_LINKAGE void *pcre2MatchDataCreateWrapper(void);
++ENGINE_LINKAGE void pcre2MatchDataFreeWrapper(void *match_data);
++ENGINE_LINKAGE int pcre2GetOvectorCountWrapper(void *match_data);
++ENGINE_LINKAGE void *pcre2GetOvectorPointerWrapper(void *match_data);
++ENGINE_LINKAGE int pcre2MatchWrapper(const PCRE2Info *pcre2_info, const char *buf, int len, int start_offset,
++ int options, const void *match_data);
+
+ static inline int invertMatchResult(int retVal)
+ {
+--- a/src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c
++++ b/src/dynamic-plugins/sf_engine/sf_snort_plugin_pcre.c
+@@ -25,13 +25,14 @@
+ * Date: 5/2005
+ *
+ *
+- * PCRE operations for dynamic rule engine
++ * PCRE2 operations for dynamic rule engine
+ */
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+ #endif
+
+-#include "pcre.h"
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "sf_types.h"
+ #include "snort_debug.h"
+ #include "sf_dynamic_define.h"
+@@ -43,32 +44,38 @@
+ /* Need access to the snort-isms that were passed to the engine */
+ extern int checkCursorSimple(const uint8_t *cursor, int flags, const uint8_t *start, const uint8_t *end, int offset);
+ extern int checkCursorInternal(void *p, int flags, int offset, const uint8_t *cursor);
+-static int pcreMatchInternal(void *, PCREInfo*, const uint8_t **);
++static int pcreMatchInternal(void *, PCRE2Info*, const uint8_t **);
+
+-int PCRESetup(struct _SnortConfig *sc, Rule *rule, PCREInfo *pcreInfo)
++int PCRE2Setup(struct _SnortConfig *sc, Rule *rule, PCRE2Info *pcre2Info)
+ {
+- const char *error;
+- int erroffset;
++ size_t erroffset;
++ int errorcode;
+
+- pcreInfo->compiled_expr = (void *)_ded.pcreCompile(pcreInfo->expr,
+- pcreInfo->compile_flags,
+- &error,
++ pcre2Info->compiled_expr = (void *)_ded.pcre2Compile(pcre2Info->expr,
++ pcre2Info->compile_flags,
++ &errorcode,
+ &erroffset,
+ NULL);
+
+- if (!pcreInfo->compiled_expr)
++ if (!pcre2Info->compiled_expr)
+ {
+ /* error doing compilation. */
+- _ded.errMsg("Failed to compile PCRE in dynamic rule [%d:%d]\n",
++ _ded.errMsg("Failed to compile PCRE2 in dynamic rule [%d:%d]\n",
+ rule->info.genID, rule->info.sigID);
+ return -1;
+ }
+- else
++
++ pcre2Info->match_context = _ded.pcre2MatchContextCreate(NULL);
++ if (!pcre2Info->match_context)
+ {
+- pcreInfo->compiled_extra = (void *)_ded.pcreStudy(sc, pcreInfo->compiled_expr, pcreInfo->compile_flags, &error);
++ /* error doing match context */
++ _ded.errMsg("Failed to allocate mem for PCRE2 match context [%d:%d]\n",
++ rule->info.genID, rule->info.sigID);
++ return -1;
+ }
+
+- if (error)
++ errorcode = _ded.pcre2JITCompile(sc, pcre2Info->compiled_expr, pcre2Info->match_context, pcre2Info->compile_flags);
++ if (errorcode)
+ {
+ /* error doing study. */
+ _ded.errMsg("Failed to study PCRE in dynamic rule [%d:%d]\n",
+@@ -76,51 +83,82 @@ int PCRESetup(struct _SnortConfig *sc, R
+ return -1;
+ }
+
+- _ded.pcreCapture(sc, pcreInfo->compiled_expr, pcreInfo->compiled_extra);
++ _ded.pcre2Capture(sc, pcre2Info->compiled_expr);
+
+
+ return 0;
+ }
+
+ /**
+- * * Wrapper for pcre_exec to expose ovector.
++ * * Wrapper for pcre2_match_data_create to run match_data.
++ * */
++ENGINE_LINKAGE void *pcre2MatchDataCreateWrapper(void)
++{
++ return _ded.pcre2MatchDataCreate(_ded.pcre2OvectorSize(), NULL);
++}
++
++/**
++ * * Wrapper for pcre2_match_data_free to run match_data.
++ * */
++ENGINE_LINKAGE void pcre2MatchDataFreeWrapper(void *match_data)
++{
++ _ded.pcre2MatchDataFree(match_data);
++}
++
++/**
++ * * Wrapper for pcre2_get_ovector_count to run match_data.
++ * */
++ENGINE_LINKAGE int pcre2GetOvectorCountWrapper(void *match_data)
++{
++ return _ded.pcre2GetOvectorCount(match_data);
++}
++
++/**
++ * * Wrapper for pcre2_get_ovector_pointer to run match_data.
+ * */
+-ENGINE_LINKAGE int pcreExecWrapper(const PCREInfo *pcre_info, const char *buf, int len, int start_offset,
+- int options, int *ovector, int ovecsize)
++ENGINE_LINKAGE void *pcre2GetOvectorPointerWrapper(void *match_data)
++{
++ return _ded.pcre2GetOvectorPointer(match_data);
++}
++
++/**
++ * * Wrapper for pcre2_match to run match_data.
++ * */
++ENGINE_LINKAGE int pcre2ExecWrapper(const PCRE2Info *pcre2_info, const char *buf, int len, int start_offset,
++ int options, const void *match_data)
+ {
+ int result;
+ int matched;
+
+- if(pcre_info == NULL
++ if(pcre2_info == NULL
+ || buf == NULL
+ || len <= 0
+ || start_offset < 0
+ || start_offset >= len
+- || ovector == NULL)
++ || match_data == NULL)
+ {
+ return 0;
+ }
+
+- result = _ded.pcreExec(pcre_info->compiled_expr, /* result of pcre_compile() */
+- pcre_info->compiled_extra, /* result of pcre_study() */
++ result = _ded.pcre2MatchReal(pcre2_info->compiled_expr, /* result of pcre_compile() */
+ buf, /* the subject string */
+ len, /* the length of the subject string */
+ start_offset, /* start at offset 0 in the subject */
+ options, /* options(handled at compile time */
+- ovector, /* vector for substring information */
+- ovecsize); /* number of elements in the vector */
++ match_data, /* match_data for results */
++ pcre2_info->match_context); /* match_context for JIT limits */
+
+ if(result >= 0)
+ {
+ matched = 1;
+ }
+- else if(result == PCRE_ERROR_NOMATCH)
++ else if(result == PCRE2_ERROR_NOMATCH)
+ {
+ matched = 0;
+ }
+ else
+ {
+- DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre_exec error : %d \n", result););
++ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre_match error : %d \n", result););
+ return 0;
+ }
+
+@@ -128,7 +166,7 @@ ENGINE_LINKAGE int pcreExecWrapper(const
+ }
+
+ /*
+- * we need to specify the vector length for our pcre_exec call. we only care
++ * we need to specify the vector length for our pcre2_match call. we only care
+ * about the first vector, which if the match is successful will include the
+ * offset to the end of the full pattern match. If we decide to store other
+ * matches, make *SURE* that this is a multiple of 3 as pcre requires it.
+@@ -136,7 +174,7 @@ ENGINE_LINKAGE int pcreExecWrapper(const
+ #define SNORT_PCRE_OVECTOR_SIZE 3
+
+ /**
+- * Perform a search of the PCRE data.
++ * Perform a search of the PCRE2 data.
+ *
+ * @param pcre_data structure that options and patterns are passed in
+ * @param buf buffer to search
+@@ -148,21 +186,18 @@ ENGINE_LINKAGE int pcreExecWrapper(const
+ *
+ * @return 1 when we find the string, 0 when we don't (unless we've been passed a flag to invert)
+ */
+-static int pcre_test(const PCREInfo *pcre_info,
++static int pcre2_test(const PCRE2Info *pcre2_info,
+ const char *buf,
+ int len,
+ int start_offset,
+ int *found_offset)
+ {
++ void *match_data;
++ size_t *ovector;
+ int matched;
+ int result;
+
+- int *ovector;
+- int ovector_size;
+-
+- _ded.pcreOvectorInfo(&ovector, &ovector_size);
+-
+- if(pcre_info == NULL
++ if(pcre2_info == NULL
+ || buf == NULL
+ || len <= 0
+ || start_offset < 0
+@@ -174,50 +209,59 @@ static int pcre_test(const PCREInfo *pcr
+ return 0;
+ }
+
++ match_data = _ded.pcre2MatchDataCreate(_ded.pcre2OvectorSize(), NULL);
++ if (!match_data) {
++ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
++ "Returning 0 because match data failed!\n"););
++ return 0;
++ }
++
+ *found_offset = -1;
+
+- result = _ded.pcreExec(pcre_info->compiled_expr,/* result of pcre_compile() */
+- pcre_info->compiled_extra, /* result of pcre_study() */
++ result = _ded.pcre2MatchReal(pcre2_info->compiled_expr,/* result of pcre_compile() */
+ buf, /* the subject string */
+ len, /* the length of the subject string */
+ start_offset, /* start at offset 0 in the subject */
+ 0, /* options(handled at compile time */
+- ovector, /* vector for substring information */
+- ovector_size); /* number of elements in the vector */
++ match_data, /* match_data vector */
++ pcre2_info->match_context); /* match context for limits */
+
+ if(result >= 0)
+ {
+ matched = 1;
+ }
+- else if(result == PCRE_ERROR_NOMATCH)
++ else if(result == PCRE2_ERROR_NOMATCH)
+ {
+ matched = 0;
+ }
+ else
+ {
+- DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre_exec error : %d \n", result););
++ _ded.pcre2MatchDataFree(match_data);
++ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "pcre_match error : %d \n", result););
+ return 0;
+ }
+
+ if (found_offset)
+ {
++ ovector = _ded.pcre2GetOvectorPointer(match_data);
+ *found_offset = ovector[1];
+ DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH,
+ "Setting buffer and found_offset: %p %d\n",
+ buf, found_offset););
+ }
+
++ _ded.pcre2MatchDataFree(match_data);
+ return matched;
+ }
+
+-ENGINE_LINKAGE int pcreMatch(void *p, PCREInfo* pcre_info, const uint8_t **cursor)
++ENGINE_LINKAGE int pcre2Match(void *p, PCRE2Info* pcre_info, const uint8_t **cursor)
+ {
+ if (pcre_info->flags & NOT_FLAG)
+ return invertMatchResult(pcreMatchInternal(p, pcre_info, cursor));
+ return pcreMatchInternal(p, pcre_info, cursor);
+ }
+
+-static int pcreMatchInternal(void *p, PCREInfo* pcre_info, const uint8_t **cursor)
++static int pcreMatchInternal(void *p, PCRE2Info* pcre_info, const uint8_t **cursor)
+ {
+ const uint8_t *buffer_start;
+ int buffer_len;
+@@ -295,7 +339,7 @@ static int pcreMatchInternal(void *p, PC
+ }
+
+
+- pcre_found = pcre_test(pcre_info, (const char *)buffer_start, buffer_len, pcre_info->offset, &pcre_offset);
++ pcre_found = pcre2_test(pcre_info, (const char *)buffer_start, buffer_len, pcre_info->offset, &pcre_offset);
+
+ if (pcre_found)
+ {
+--- a/src/dynamic-preprocessors/appid/luaDetectorApi.c
++++ b/src/dynamic-preprocessors/appid/luaDetectorApi.c
+@@ -38,7 +38,8 @@
+ #include "luaDetectorModule.h"
+ #include "luaDetectorApi.h"
+ #include "luaDetectorFlowApi.h"
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "httpCommon.h"
+ #include "sf_multi_mpse.h"
+ #include "fw_appid.h"
+@@ -54,7 +55,6 @@
+ #include "detector_cip.h"
+
+ #define DETECTOR "Detector"
+-#define OVECCOUNT 30 /* should be a multiple of 3 */
+ #define URL_LIST_STEP_SIZE 5000
+
+ typedef enum {
+@@ -1355,7 +1355,7 @@ static int Detector_getPacketDir(
+ return 1;
+ }
+
+-/**Perform a pcre match with grouping. A simple regular expression match with no grouping
++/**Perform a pcre2 match with grouping. A simple regular expression match with no grouping
+ * can also be performed.
+ *
+ * @param Lua_State* - Lua state variable.
+@@ -1371,12 +1371,15 @@ static int Detector_getPcreGroups(
+ Detector *detector;
+ char *pattern;
+ unsigned int offset;
+- pcre *re;
+- int ovector[OVECCOUNT];
+- const char *error;
+- int erroffset;
++ pcre2_code *re;
++ pcre2_match_data *match_data;
++ PCRE2_UCHAR error[128];
++ int errorcode;
++ PCRE2_SIZE erroffset;
+ int rc, i;
+ DetectorUserData *detectorUserData = checkDetectorUserData(L, 1);
++ unsigned int oveccount;
++ size_t *ovector;
+
+ pattern = (char *)lua_tostring(L, 2);
+ offset = lua_tonumber(L, 3); /*offset can be zero, no check necessary. */
+@@ -1390,49 +1393,56 @@ static int Detector_getPcreGroups(
+
+ {
+ /*compile the regular expression pattern, and handle errors */
+- re = pcre_compile(
+- pattern, /*the pattern */
+- PCRE_DOTALL, /*default options - dot matches everything including newline */
+- &error, /*for error message */
+- &erroffset, /*for error offset */
+- NULL); /*use default character tables */
++ re = pcre2_compile(
++ (PCRE2_SPTR)pattern, /*the pattern */
++ PCRE2_ZERO_TERMINATED, /*zero terminated string*/
++ PCRE2_DOTALL, /*default options - dot matches everything including newline */
++ &errorcode, /*for error message */
++ &erroffset, /*for error offset */
++ NULL); /*use default character tables */
+
+ if (re == NULL)
+ {
+- _dpd.errMsg("PCRE compilation failed at offset %d: %s\n",erroffset, error);
++ pcre2_get_error_message(errorcode, error, 128);
++ _dpd.errMsg("PCRE2 compilation failed at offset %zu: %s\n",erroffset, error);
+ return 0;
+ }
+
++ match_data = pcre2_match_data_create_from_pattern(re, NULL);
++ if (!match_data) {
++ _dpd.errMsg("PCRE2 failed to alloc data for match data\n");
++ return 0;
++ }
+
+ /*pattern match against the subject string. */
+- rc = pcre_exec(
++ rc = pcre2_match(
+ re, /*compiled pattern */
+- NULL, /*no extra data */
+- (char *)detector->validateParams.data, /*subject string */
+- detector->validateParams.size, /*length of the subject */
+- offset, /*offset 0 */
++ (PCRE2_SPTR)detector->validateParams.data, /*subject string */
++ (PCRE2_SIZE)detector->validateParams.size, /*length of the subject */
++ (PCRE2_SIZE)offset, /*offset 0 */
+ 0, /*default options */
+- ovector, /*output vector for substring information */
+- OVECCOUNT); /*number of elements in the output vector */
+-
++ match_data, /*output vector for substring information */
++ NULL); /*number of elements in the output vector */
+
+ if (rc < 0)
+ {
+ /*Matching failed: clubbing PCRE_ERROR_NOMATCH with other errors. */
+- pcre_free(re);
++ pcre2_match_data_free(match_data);
++ pcre2_code_free(re);
+ return 0;
+ }
+
+ /*Match succeded */
+
+ /*printf("\nMatch succeeded at offset %d", ovector[0]); */
+- pcre_free(re);
+
++ oveccount = pcre2_get_ovector_count(match_data);
++ ovector = pcre2_get_ovector_pointer(match_data);
+
+ if (rc == 0)
+ {
+ /*overflow of matches */
+- rc = OVECCOUNT/3;
++ rc = oveccount/3;
+ /*printf("ovector only has room for %d captured substrings", rc - 1); */
+ _dpd.errMsg("ovector only has room for %d captured substrings\n",rc - 1);
+ }
+@@ -1447,6 +1457,9 @@ static int Detector_getPcreGroups(
+ lua_pushlstring(L, (char *)detector->validateParams.data + ovector[2*i], ovector[2*i+1] - ovector[2*i]);
+ }
+
++ pcre2_match_data_free(match_data);
++ pcre2_code_free(re);
++
+ return rc;
+ }
+
+--- a/src/dynamic-preprocessors/imap/snort_imap.h
++++ b/src/dynamic-preprocessors/imap/snort_imap.h
+@@ -38,7 +38,8 @@
+
+ /* Includes ***************************************************************/
+
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+
+ #include "sf_snort_packet.h"
+ #include "imap_config.h"
+@@ -216,8 +217,7 @@ typedef struct _IMAPMimeBoundary
+
+ typedef struct _IMAPPcre
+ {
+- pcre *re;
+- pcre_extra *pe;
++ pcre2_code *re;
+
+ } IMAPPcre;
+
+--- a/src/dynamic-preprocessors/pop/snort_pop.h
++++ b/src/dynamic-preprocessors/pop/snort_pop.h
+@@ -38,7 +38,8 @@
+
+ /* Includes ***************************************************************/
+
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+
+ #include "sf_snort_packet.h"
+ #include "pop_config.h"
+--- a/src/dynamic-preprocessors/smtp/snort_smtp.h
++++ b/src/dynamic-preprocessors/smtp/snort_smtp.h
+@@ -39,7 +39,8 @@
+
+ /* Includes ***************************************************************/
+
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+
+ #include "sf_snort_packet.h"
+ #include "ssl.h"
+--- a/src/snort.c
++++ b/src/snort.c
+@@ -4449,9 +4449,6 @@ void SnortConfFree(SnortConfig *sc)
+
+ OtnxMatchDataFree(sc->omd);
+
+- if (sc->pcre_ovector != NULL)
+- free(sc->pcre_ovector);
+-
+ if ( sc->event_queue_config )
+ EventQueueConfigFree(sc->event_queue_config);
+
+--- a/src/snort.h
++++ b/src/snort.h
+@@ -826,7 +826,6 @@ typedef struct _SnortConfig
+ long int tagged_packet_limit; /* config tagged_packet_limit */
+ long int pcre_match_limit; /* config pcre_match_limit */
+ long int pcre_match_limit_recursion; /* config pcre_match_limit_recursion */
+- int *pcre_ovector;
+ int pcre_ovector_size;
+
+ #ifdef PERF_PROFILING
+--- a/src/util.c
++++ b/src/util.c
+@@ -78,7 +78,8 @@ static struct mallinfo mi;
+ #include "plugbase.h"
+ #include "sf_types.h"
+ #include "sflsq.h"
+-#include "pcre.h"
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include "pcre2.h"
+ #include "mpse.h"
+ #include "ppm.h"
+ #include "active.h"
+@@ -175,7 +176,7 @@ double CalcPct(uint64_t cnt, uint64_t to
+ int DisplayBanner(void)
+ {
+ const char * info;
+- const char * pcre_ver;
++ PCRE2_UCHAR buffer[32];
+ const char * zlib_ver;
+
+ info = getenv("HOSTTYPE");
+@@ -184,7 +185,7 @@ int DisplayBanner(void)
+ info="";
+ }
+
+- pcre_ver = pcre_version();
++ pcre2_config(PCRE2_CONFIG_VERSION, buffer);
+ zlib_ver = zlib_version;
+
+ LogMessage("\n");
+@@ -204,7 +205,7 @@ int DisplayBanner(void)
+ #ifdef HAVE_PCAP_LIB_VERSION
+ LogMessage(" Using %s\n", pcap_lib_version());
+ #endif
+- LogMessage(" Using PCRE version: %s\n", pcre_ver);
++ LogMessage(" Using PCRE2 version: %s\n", buffer);
+ LogMessage(" Using ZLIB version: %s\n", zlib_ver);
+ LogMessage("\n");
+
include $(TOPDIR)/rules.mk
PKG_NAME:=snort3
-PKG_VERSION:=3.1.71.0
+PKG_VERSION:=3.1.76.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/snort3/snort3/archive/refs/tags/
-PKG_HASH:=b5dd52b46ca2570986d7c12750bbf9db00ee3c294983ce272b3ca321aee8fb73
+PKG_HASH:=5586199be8b7a7c6a1b73e0af2e2e004db8417b8282668b10583071e35c9c7a9
-PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>, John Audia <therealgraysky@proton.me>
PKG_LICENSE:=GPL-2.0-only
PKG_LICENSE_FILES:=COPYING
PKG_CPE_ID:=cpe:/a:snort:snort
SUBMENU:=Firewall
SECTION:=net
CATEGORY:=Network
- DEPENDS:=+libstdcpp +libdaq3 +libdnet +libopenssl +libpcap +libpcre +libpthread +libuuid +zlib +libhwloc +libtirpc @HAS_LUAJIT_ARCH +luajit +libatomic
+ DEPENDS:=+libstdcpp +libdaq3 +libdnet +libopenssl +libpcap +libpcre +libpthread +libuuid +zlib +libhwloc +libtirpc @HAS_LUAJIT_ARCH +luajit +libatomic +kmod-nft-queue
TITLE:=Lightweight Network Intrusion Detection System
URL:=http://www.snort.org/
MENU:=1
$(PKG_INSTALL_DIR)/usr/bin/u2{boat,spewfoo} \
$(1)/usr/bin/
+ $(INSTALL_BIN) \
+ ./files/snort-{mgr,rules} \
+ $(1)/usr/bin/
+
$(INSTALL_DIR) $(1)/usr/lib/snort
$(CP) \
$(PKG_INSTALL_DIR)/usr/lib/snort/daq/daq_hext.so \
$(PKG_INSTALL_DIR)/usr/include/snort/lua/snort_plugin.lua \
$(1)/usr/share/lua/
+ $(INSTALL_DIR) $(1)/usr/share/snort
+ $(INSTALL_CONF) \
+ ./files/main.uc \
+ $(1)/usr/share/snort/
+
+ $(INSTALL_DIR) $(1)/usr/share/snort/templates
+ $(INSTALL_CONF) \
+ ./files/nftables.uc \
+ $(1)/usr/share/snort/templates/
+ $(INSTALL_CONF) \
+ ./files/snort.uc \
+ $(1)/usr/share/snort/templates/
+
$(INSTALL_DIR) $(1)/etc/snort/{rules,lists,builtin_rules,so_rules}
$(INSTALL_CONF) \
+-- Unused when using 'snort-mgr', do not modify without deep understanding.
-- setup HOME_NET below with your IP range/ranges to protect
-HOME_NET = [[ 192.168.1.0/24 10.1.0.1/24 ]]
-EXTERNAL_NET = "!$HOME_NET"
+--HOME_NET = [[ 192.168.1.0/24 10.1.0.0/24 ]]
+--EXTERNAL_NET = "!$HOME_NET"
+-- This file is no longer used if you are using 'snort-mgr' to create the
+-- configuration. It is left as a sample.
+--
-- use ths file to customize any functions defined in /etc/snort/snort.lua
-- switch tap to inline in ips and uncomment the below to run snort in inline mode
--- /dev/null
+{%
+//------------------------------------------------------------------------------
+// Copyright (c) 2023 Eric Fahlgren <eric.fahlgren@gmail.com>
+// SPDX-License-Identifier: GPL-2.0
+//
+// The tables defined using 'config_item' are the source of record for the
+// configuration file, '/etc/config/snort'. If you wish to add new items,
+// do that only in the tables and propagate that use into the templates.
+//
+//------------------------------------------------------------------------------
+
+import { cursor } from 'uci';
+let uci = cursor();
+
+function wrn(fmt, ...args) {
+ if (getenv("QUIET"))
+ exit(1);
+
+ let msg = "ERROR: " + sprintf(fmt, ...args);
+
+ if (getenv("TTY"))
+ warn(`\033[33m${msg}\033[m\n`);
+ else
+ warn(`[!] ${msg}\n`);
+ exit(1);
+}
+
+//------------------------------------------------------------------------------
+
+function config_item(type, values, def) {
+ // If no default value is provided explicity, then values[0] is used as default.
+ if (! type in [ "enum", "range", "path", "str" ]) {
+ wrn(`Invalid item type '${type}', must be one of "enum", "range", "path" or "str".`);
+ return;
+ }
+ if (type == "range" && (length(values) != 2 || values[0] > values[1])) {
+ wrn(`A 'range' type item must have exactly 2 values in ascending order.`);
+ return;
+ }
+ // Maybe check paths for existence???
+
+ return {
+ type: type,
+ values: values,
+ default: def ?? values[0],
+
+ contains: function(value) {
+ // Check if the value is contained in the listed values,
+ // depending on the item type.
+ switch (this.type) {
+ case "enum":
+ return value in this.values;
+ case "range":
+ return value >= this.values[0] && value <= this.values[1];
+ default:
+ return true;
+ }
+ },
+
+ allowed: function() {
+ // Show a pretty version of the possible values, for error messages.
+ switch (this.type) {
+ case "enum":
+ return "one of [" + join(", ", this.values) + "]";
+ case "range":
+ return `${this.values[0]} <= x <= ${this.values[1]}`;
+ case "path":
+ return "a path string";
+ case "str":
+ return "a string";
+ default:
+ return "???";
+ }
+ },
+ }
+};
+
+const snort_config = {
+ enabled: config_item("enum", [ 0, 1 ], 0), // Defaults to off, so that user must configure before first start.
+ manual: config_item("enum", [ 0, 1 ], 1), // Allow user to manually configure, legacy behavior when enabled.
+ oinkcode: config_item("str", [ "" ]), // User subscription oinkcode. Much more in 'snort-rules' script.
+ home_net: config_item("str", [ "" ], "192.168.1.0/24"),
+ external_net: config_item("str", [ "" ], "any"),
+
+ config_dir: config_item("path", [ "/etc/snort" ]), // Location of the base snort configuration files.
+ temp_dir: config_item("path", [ "/var/snort.d" ]), // Location of all transient snort config, including downloaded rules.
+ log_dir: config_item("path", [ "/var/log" ]), // Location of the generated logs, and oh-by-the-way the snort PID file (why?).
+ logging: config_item("enum", [ 0, 1 ], 1),
+ openappid: config_item("enum", [ 0, 1 ], 0),
+
+ mode: config_item("enum", [ "ids", "ips" ]),
+ method: config_item("enum", [ "pcap", "afpacket", "nfq" ]),
+ action: config_item("enum", [ "alert", "block", "drop", "reject" ]),
+ interface: config_item("str", [ uci.get("network", "wan", "device") ]),
+ snaplen: config_item("range", [ 1518, 65535 ]), // int daq.snaplen = 1518: set snap length (same as -s) { 0:65535 }
+};
+
+const nfq_config = {
+ queue_count: config_item("range", [ 1, 16 ], 4), // Count of queues to allocate in nft chain when method=nfq, usually 2-8.
+ queue_start: config_item("range", [ 1, 32768], 4), // Start of queue numbers in nftables.
+ queue_maxlen: config_item("range", [ 1024, 65536 ], 1024), // --daq-var queue_maxlen=int
+ fanout_type: config_item("enum", [ "hash", "lb", "cpu", "rollover", "rnd", "qm"], "hash"), // See below.
+ thread_count: config_item("range", [ 0, 32 ], 0), // 0 = use cpu count
+ chain_type: config_item("enum", [ "prerouting", "input", "forward", "output", "postrouting" ], "input"),
+ chain_priority: config_item("enum", [ "raw", "filter", "300"], "filter"),
+ include: config_item("path", [ "" ]), // User-defined rules to include inside queue chain.
+};
+
+
+let _snort_config_doc =
+"
+This is not an exhaustive list of configuration items, just those that
+require more explanation than is given in the tables that define them, below.
+
+https://openwrt.org/docs/guide-user/services/snort
+
+snort
+ manual - When set to 1, use manual configuration for legacy behavior.
+ When disabled, then use this config.
+ interface - Default should usually be 'uci get network.wan.device',
+ something like 'eth0'
+ home_net - IP range/ranges to protect. May be 'any', but more likely it's
+ your lan range, default is '192.168.1.0/24'
+ external_net - IP range external to home. Usually 'any', but if you only
+ care about true external hosts (trusting all lan devices),
+ then '!$HOMENET' or some specific range
+ mode - 'ids' or 'ips', for detection-only or prevention, respectively
+ oinkcode - https://www.snort.org/oinkcodes
+ config_dir - Location of the base snort configuration files. Default /etc/snort
+ temp_dir - Location of all transient snort config, including downloaded rules
+ Default /var/snort.d
+ logging - Enable external logging of events thus enabling 'snort-mgr report',
+ otherwise events only go to system log (i.e., 'logread -e snort:')
+ log_dir - Location of the generated logs, and oh-by-the-way the snort
+ PID file (why?). Default /var/log
+ openappid - Enabled inspection using the 'openappid' package
+ See 'opkg info openappid'
+ action - 'alert', 'block', 'reject' or 'drop'
+ method - 'pcap', 'afpacket' or 'nfq'
+ snaplen - int daq.snaplen = 1518: set snap length (same as -s) { 0:65535 }
+
+nfq - https://github.com/snort3/libdaq/blob/master/modules/nfq/README.nfq.md
+ queue_maxlen - nfq's '--daq-var queue_maxlen=int'
+ queue_count - Count of queues to use when method=nfq, usually 2-8
+ fanout_type - Sets kernel load balancing algorithm*, one of hash, lb, cpu,
+ rollover, rnd, qm.
+ thread_count - int snort.-z: <count> maximum number of packet threads
+ (same as --max-packet-threads); 0 gets the number of
+ CPU cores reported by the system; default is 1 { 0:max32 }
+ chain_type - Chain type when generating nft output
+ chain_priority - Chain priority when generating nft output
+ include - Full path to user-defined extra rules to include inside queue chain
+
+ * - for details on fanout_type, see these pages:
+ https://github.com/florincoras/daq/blob/master/README
+ https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt
+";
+
+function snort_config_doc(comment) {
+ if (comment == null) comment = "";
+ if (comment != "") comment += " ";
+ for (let line in split(_snort_config_doc, "\n")) {
+ let msg = rtrim(sprintf("%s%s", comment, line));
+ print(msg, "\n");
+ }
+}
+
+//------------------------------------------------------------------------------
+
+function load(section, config) {
+ let self = {
+ ".name": section,
+ ".config": config,
+ };
+
+ // Set the defaults from definitions in table.
+ for (let item in config) {
+ self[item] = config[item].default;
+ }
+
+ // Overwrite them with any uci config settings.
+ let cfg = uci.get_all("snort", section);
+ for (let item in cfg) {
+ // If you need to rename, delete or change the meaning of a
+ // config item, just intercept it and do the work here.
+
+ if (exists(config, item)) {
+ let val = cfg[item];
+ if (config[item].contains(val))
+ self[item] = val;
+ else {
+ wrn(`In option ${item}='${val}', must be ${config[item].allowed()}`);
+ // ??? self[item] = config[item][0]; ???
+ }
+ }
+ }
+
+ return self;
+}
+
+let snort = null;
+let nfq = null;
+function load_all() {
+ snort = load("snort", snort_config);
+ nfq = load("nfq", nfq_config);
+}
+
+function dump_config(settings) {
+ let section = settings[".name"];
+ let config = settings[".config"];
+ printf("config %s '%s'\n", section, section);
+ for (let item in config) {
+ printf("\toption %-15s %-17s# %s\n", item, `'${settings[item]}'`, config[item].allowed());
+ }
+ print("\n");
+}
+
+function render_snort() {
+ include("templates/snort.uc", { snort, nfq });
+}
+
+function render_nftables() {
+ include("templates/nftables.uc", { snort, nfq });
+}
+
+function render_config() {
+ snort_config_doc("#");
+ dump_config(snort);
+ dump_config(nfq);
+}
+
+function render_help() {
+ snort_config_doc();
+}
+
+//------------------------------------------------------------------------------
+
+load_all();
+
+switch (getenv("TYPE")) {
+ case "snort":
+ render_snort();
+ return;
+
+ case "nftables":
+ render_nftables();
+ return;
+
+ case "config":
+ render_config();
+ return;
+
+ case "help":
+ render_help();
+ return;
+
+ default:
+ print("Invalid table type.\n");
+ return;
+}
+
+//------------------------------------------------------------------------------
+-%}
--- /dev/null
+# Do not edit, automatically generated. See /usr/share/snort/templates.
+{%
+// Copyright (c) 2023 Eric Fahlgren <eric.fahlgren@gmail.com>
+// SPDX-License-Identifier: GPL-2.0
+
+let queues = `${nfq.queue_start}-${int(nfq.queue_start)+int(nfq.queue_count)-1}`;
+let chain_type = nfq.chain_type;
+-%}
+
+table inet snort {
+ chain {{ chain_type }}_{{ snort.mode }} {
+ type filter hook {{ chain_type }} priority {{ nfq.chain_priority }}
+ policy accept
+ {% if (nfq.include) { include(nfq.include, { snort, nfq }); } %}
+ # tcp flags ack ct direction original ct state established counter accept
+ counter queue flags bypass to {{ queues }}
+ }
+}
--- /dev/null
+#!/bin/sh
+# Copyright (c) 2023 Eric Fahlgren <eric.fahlgren@gmail.com>
+# SPDX-License-Identifier: GPL-2.0
+# shellcheck disable=SC2039 # "local" not defined in POSIX sh
+
+PROG="/usr/bin/snort"
+MAIN="/usr/share/snort/main.uc"
+CONF_DIR="/var/snort.d"
+CONF="${CONF_DIR}/snort_conf.lua"
+
+VERBOSE=
+TESTING=
+NLINES=0
+
+[ ! -e "$CONF_DIR" ] && mkdir "$CONF_DIR"
+[ -e /dev/stdin ] && STDIN=/dev/stdin || STDIN=/proc/self/fd/0
+[ -e /dev/stdout ] && STDOUT=/dev/stdout || STDOUT=/proc/self/fd/1
+[ -t 2 ] && export TTY=1
+
+die() {
+ [ -n "$QUIET" ] || echo "$@" >&2
+ exit 1
+}
+
+disable_offload()
+{
+ # From https://forum.openwrt.org/t/snort-3-nfq-with-ips-mode/161172
+ # https://blog.snort.org/2016/08/running-snort-on-commodity-hardware.html
+ # Not needed when running the nft daq as defragmentation is done by the kernel.
+ # What about pcap?
+
+ local filter_method=$(uci -q get snort.snort.method)
+ if [ "$filter_method" = "afpacket" ]; then
+ local wan=$(uci get snort.snort.interface)
+ if [ -n "$wan" ] && ethtool -k "$wan" | grep -q -E '(tcp-segmentation-offload|receive-offload): on' ; then
+ ethtool -K "$wan" gro off lro off tso off 2> /dev/null
+ log "Disabled gro, lro and tso on '$wan' using ethtool."
+ fi
+ fi
+}
+
+nft_rm_table() {
+ for table_type in 'inet' 'netdev'; do
+ nft list tables | grep -q "${table_type} snort" && nft delete table "${table_type}" snort
+ done
+}
+
+nft_add_table() {
+ if [ "$(uci -q get snort.snort.method)" = "nfq" ]; then
+ print nftables | nft $VERBOSE -f $STDIN
+ [ -n "$VERBOSE" ] && nft list table inet snort
+ fi
+}
+
+setup() {
+ # Generates all the configuration, then reports the config file for snort.
+ # Does NOT generate the rules file, you'll need to do 'update-rules' first.
+ nft_rm_table
+ print snort > "$CONF"
+ nft_add_table
+ echo "$CONF"
+}
+
+teardown() {
+ # Merely cleans up after.
+ nft_rm_table
+ [ -e "$CONF" ] && rm "$CONF"
+}
+
+update_rules() {
+ /usr/bin/snort-rules $TESTING
+}
+
+print() {
+ # '$1' is file type to generate, one of:
+ # config, snort or nftables
+ TYPE=$1 utpl -S "$MAIN"
+}
+
+check() {
+ local manual=$(uci get snort.snort.manual)
+ [ "$manual" = 1 ] && return 0
+
+ [ -n "$QUIET" ] && OUT=/dev/null || OUT=$STDOUT
+ local test_conf="${CONF_DIR}/test_conf.lua"
+ print snort > "${test_conf}" || die "Errors during generation of config."
+ if $PROG -T -q --warn-all -c "${test_conf}" 2> $OUT ; then
+ rm "${test_conf}"
+ return 0
+ fi
+ die "Errors in snort config tests."
+}
+
+report() {
+ # Reported IPs have source port stripped, but destination port (if any)
+ # retained.
+ #
+ # json notes
+ # from alert_fast:
+ # 08/30-11:39:57.639021 [**] [1:382:11] "PROTOCOL-ICMP PING Windows" [**] [Classification: Misc activity] [Priority: 3] {ICMP} 10.1.1.186 -> 10.1.1.20
+ #
+ # same event in alert_json (single line broken for clarity):
+ # { "timestamp" : "08/30-11:39:57.639021", "pkt_num" : 5366, "proto" : "ICMP", "pkt_gen" : "raw",
+ # "pkt_len" : 60, "dir" : "C2S", "src_ap" : "10.1.1.186:0", "dst_ap" : "10.1.1.20:0",
+ # "rule" : "1:382:11", "action" : "allow" }
+ #
+ # Second part of "rule", 382, is "sid" in ruleset, suffixing 11 is "rev".
+ # grep '\bsid:382\b' /etc/snort/rules/snort.rules (again, single line broken for clarity):
+ # alert icmp $EXTERNAL_NET any -> $HOME_NET any ( msg:"PROTOCOL-ICMP PING Windows";
+ # itype:8; content:"abcdefghijklmnop",depth 16; metadata:ruleset community;
+ # classtype:misc-activity; sid:382; rev:11; )
+ #
+ # Not sure where the prefixing 1 comes from.
+
+ local logging=$(uci get snort.snort.logging)
+ local log_dir=$(uci get snort.snort.log_dir)
+ local pattern="$1"
+
+ if [ "$logging" = 0 ]; then
+ die "Logging is not enabled in snort config."
+ fi
+
+ #if [ -z "$pattern" ]; then
+ # die "Provide a valid IP and try again."
+ #fi
+
+ [ "$NLINES" = 0 ] && output="cat" || output="head -n $NLINES"
+
+ # Fix this to use json file.
+ tmp="/tmp/snort.report.$$"
+ echo "Intrusions involving ${pattern:-all IPs}"
+ grep "\b${pattern}\b" "$log_dir/alert_fast.txt" \
+ | sed 's/.*"\([^"]*\)".* \([^ :]*\)[: ].*-> \(.*\)/\1#\2#\3/' > "$tmp"
+ n_incidents="$(wc -l < $tmp)"
+ lines=$(sort "$tmp" | uniq -c | sort -nr \
+ | awk -F'#' '{printf "%-80s %-12s -> %s\n", $1, $2, $3}')
+ echo "$lines" | $output
+ n_lines=$(echo "$lines" | wc -l)
+ [ "$NLINES" -gt 0 ] && [ "$NLINES" -lt "$n_lines" ] && echo " ... Only showing $NLINES of $n_lines most frequent incidents."
+ printf "%7d total incidents\n" "$n_incidents"
+ rm "$tmp"
+}
+
+status() {
+ echo 'tbd'
+}
+
+
+while [ -n "$1" ]; do
+ case "$1" in
+ -q)
+ export QUIET=1
+ shift
+ ;;
+ -v)
+ export VERBOSE=-e
+ shift
+ ;;
+ -t)
+ TESTING=-t
+ shift
+ ;;
+ -n)
+ NLINES="$2"
+ shift
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+case "$1" in
+ setup)
+ setup
+ ;;
+ teardown)
+ teardown
+ ;;
+ resetup)
+ QUIET=1 check || die "The generated snort lua configuration contains errors, not restarting."
+ teardown
+ setup
+ ;;
+ update-rules)
+ update_rules
+ ;;
+ check)
+ check
+ ;;
+ print)
+ print "$2"
+ ;;
+ report)
+ report "$2"
+ ;;
+ status)
+ status
+ ;;
+ *)
+ cat <<USAGE
+Usage:
+
+ -n = show only NLINES of output
+ -q = quiet
+ -v = verbose
+ -t = testing mode
+
+ $0 [-v] [-q] setup|teardown|resetup
+
+ Normally only used internally by init scripts to manage the generation
+ of configuration files and any needed firewall rules. None of these
+ modify the snort rules in any way (see 'update-rules').
+ setup = generates snort config, sets up firewall.
+ teardown = removes any firewall rules.
+ resetup = shorthand for teardown and then setup.
+
+
+ $0 [-n lines] report [pattern]
+
+ Report on incidents. Note this is somewhat experimental, so suggested
+ improvements are quite welcome.
+ pattern = IP or piece of IP or something in the message to filter.
+
+ $0 [-t] update-rules
+
+ Download and install the snort ruleset. Testing mode generates a canned
+ rule that matches IPv4 ping requests. A typical test scenario might look
+ like:
+
+ > snort-mgr -t update-rules
+ > /etc/init.d/snort start
+ > ping -c4 8.8.8.8
+ > logread -e "TEST ALERT"
+
+
+ $0 print config|snort|nftables
+
+ Print the rendered file contents.
+ config = Display contents of /etc/config/snort, but with all values and
+ descriptions. Missing values shown with defaults.
+ snort = The snort configuration file, which is a lua script.
+ nftables = The nftables script used to define the input queues when using
+ the 'nfq' DAQ.
+
+
+ $0 [-q] check
+
+ Test the rendered config using snort's check mode without
+ applying it to the running system.
+
+
+ $0 status
+
+ Print the nfq counter values and blah blah blah
+
+USAGE
+ ;;
+esac
--- /dev/null
+#!/bin/sh
+# Copyright (c) 2023 Eric Fahlgren <eric.fahlgren@gmail.com>
+# SPDX-License-Identifier: GPL-2.0
+# shellcheck disable=SC2039 # "local" not defined in POSIX sh
+
+alias log='logger -s -t "snort-rules[$$]" -p "info"'
+
+[ "$1" = "-t" ] && testing=true || testing=false
+
+download_rules() {
+ # Further information:
+ # https://www.snort.org/products#rule_subscriptions
+ # https://www.snort.org/oinkcodes
+ #
+ # Also, what to do about "subscription" vs Talos_LightSPD rules when subbed?
+ # Add a "use_rules" list or option or something?
+ oinkcode=$(uci -q get snort.snort.oinkcode)
+
+
+
+ local conf_dir=$(uci -q get snort.snort.config_dir || echo "/etc/snort")
+ local rules_file="$conf_dir/rules/snort.rules"
+ local data_dir=$(uci -q get snort.snort.temp_dir || echo "/var/snort.d")
+ local data_tar="$data_dir/rules.tar.gz"
+
+ # Make sure everything exists.
+ [ -d "$data_dir" ] || mkdir -p "$data_dir"
+
+
+ if $testing ; then
+ log "Generating testing rules..."
+ new_rules="$data_dir/testing.rules"
+ rm -f "$new_rules"
+ echo 'alert icmp any any <> any any (msg:"TEST ALERT ICMP v4"; icode:0; itype: 8; sid:10000010; rev:001;)' >> "$new_rules"
+ #echo 'alert icmp any any <> any any (msg:"TEST ALERT ICMP v6"; icode:0; itype:33; sid:10000011; rev:001;)' >> "$new_rules"
+ #echo 'alert icmp any any <> any any (msg:"TEST ALERT ICMP v6"; icode:0; itype:34; sid:10000012; rev:001;)' >> "$new_rules"
+
+ else
+ if [ -z "$oinkcode" ]; then
+ # If you do not have a subscription, then we use the community rules:
+ log "Downloading community rules..."
+ url="https://www.snort.org/downloads/community/snort3-community-rules.tar.gz"
+
+ else
+ # If you have a subscription and its corresponding oinkcode, use this:
+ #
+ # 'snortver' is the version number of the snort executable in use on your
+ # router.
+ #
+ # Ideally, the 'snort --version' output would work, but OpenWrt builds
+ # are often between (or, more likely, newer than) those listed on the
+ # snort.org downloads page.
+ #
+ # So instead, we define it manually to be the value just before the
+ # installed version. Look on https://www.snort.org/advisories/ and
+ # select the most recent date. On that page, find the closest version
+ # number preceding your installed version and modify the hard-coded
+ # value below (for example, installed is 31600 then use 31470):
+
+ #snortver=$(snort --version | awk '/Version/ {print gensub("\\.", "", "", $NF)}')
+ snortver=31470
+
+ log "Downloading subscription rules..."
+ url="https://www.snort.org/rules/snortrules-snapshot-$snortver.tar.gz?oinkcode=$oinkcode"
+ fi
+
+ wget "$url" -O "$data_tar" 2>&1 | log || exit 1
+
+ # ??? Does non-community tar contain just the one "*.rules" file, too???
+ new_rules=$(tar tzf "$data_tar" | grep '\.rules$')
+ new_rules="$data_dir/$new_rules"
+
+ old_rules="$data_dir/old.rules"
+ if [ -e "$new_rules" ]; then
+ # Before we overwrite with the new download.
+ log "Stashing old rules to $old_rules ..."
+ mv -f "$new_rules" "$old_rules"
+ fi
+
+ log "Unpacking $data_tar ..."
+ tar xzvf "$data_tar" -C "$data_dir" | log || exit 1
+ if [ -e "$old_rules" ] && ! cmp -s "$new_rules" "$old_rules" ; then
+ diff "$new_rules" "$old_rules" 2>&1 | log
+ fi
+ fi
+
+ rm -f "$rules_file"
+ ln -s "$new_rules" "$rules_file"
+
+ log "Snort rules loaded, restart snort now."
+}
+download_rules
+#
+# This is not an exhaustive list of configuration items, just those that
+# require more explanation than is given in the tables that define them, below.
+#
+# https://openwrt.org/docs/guide-user/services/snort
+#
+# snort
+# manual - When set to 1, use manual configuration for legacy behavior.
+# When disabled, then use this config.
+# interface - Default should usually be 'uci get network.wan.device',
+# something like 'eth0'
+# home_net - IP range/ranges to protect. May be 'any', but more likely it's
+# your lan range, default is '192.168.1.0/24'
+# external_net - IP range external to home. Usually 'any', but if you only
+# care about true external hosts (trusting all lan devices),
+# then '!$HOMENET' or some specific range
+# mode - 'ids' or 'ips', for detection-only or prevention, respectively
+# oinkcode - https://www.snort.org/oinkcodes
+# config_dir - Location of the base snort configuration files. Default /etc/snort
+# temp_dir - Location of all transient snort config, including downloaded rules
+# Default /var/snort.d
+# logging - Enable external logging of events thus enabling 'snort-mgr report',
+# otherwise events only go to system log (i.e., 'logread -e snort:')
+# log_dir - Location of the generated logs, and oh-by-the-way the snort
+# PID file (why?). Default /var/log
+# openappid - Enabled inspection using the 'openappid' package
+# See 'opkg info openappid'
+# action - 'alert', 'block', 'reject' or 'drop'
+# method - 'pcap', 'afpacket' or 'nfq'
+# snaplen - int daq.snaplen = 1518: set snap length (same as -s) { 0:65535 }
+#
+# nfq - https://github.com/snort3/libdaq/blob/master/modules/nfq/README.nfq.md
+# queue_maxlen - nfq's '--daq-var queue_maxlen=int'
+# queue_count - Count of queues to use when method=nfq, usually 2-8
+# fanout_type - Sets kernel load balancing algorithm*, one of hash, lb, cpu,
+# rollover, rnd, qm.
+# thread_count - int snort.-z: <count> maximum number of packet threads
+# (same as --max-packet-threads); 0 gets the number of
+# CPU cores reported by the system; default is 1 { 0:max32 }
+# chain_type - Chain type when generating nft output
+# chain_priority - Chain priority when generating nft output
+# include - Full path to user-defined extra rules to include inside queue chain
+#
+# * - for details on fanout_type, see these pages:
+# https://github.com/florincoras/daq/blob/master/README
+# https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt
+#
config snort 'snort'
- option config_dir '/etc/snort/'
- option interface 'eth0'
+ option enabled '0' # one of [0, 1]
+ option manual '1' # one of [0, 1]
+ option oinkcode '' # a string
+ option home_net '192.168.1.0/24' # a string
+ option external_net 'any' # a string
+ option config_dir '/etc/snort' # a path string
+ option temp_dir '/var/snort.d' # a path string
+ option log_dir '/var/log' # a path string
+ option logging '1' # one of [0, 1]
+ option openappid '0' # one of [0, 1]
+ option mode 'ids' # one of [ids, ips]
+ option method 'pcap' # one of [pcap, afpacket, nfq]
+ option action 'alert' # one of [alert, block, drop, reject]
+ option interface 'eth0' # a string
+ option snaplen '1518' # 1518 <= x <= 65535
+
+config nfq 'nfq'
+ option queue_count '4' # 1 <= x <= 16
+ option queue_start '4' # 1 <= x <= 32768
+ option queue_maxlen '1024' # 1024 <= x <= 65536
+ option fanout_type 'hash' # one of [hash, lb, cpu, rollover, rnd, qm]
+ option thread_count '0' # 0 <= x <= 32
+ option chain_type 'input' # one of [prerouting, input, forward, output, postrouting]
+ option chain_priority 'filter' # one of [raw, filter, 300]
+ option include '' # a path string
+
#!/bin/sh /etc/rc.common
+# shellcheck disable=SC2039 # "local" not defined in POSIX sh
START=99
STOP=10
USE_PROCD=1
PROG=/usr/bin/snort
+MGR=/usr/bin/snort-mgr
validate_snort_section() {
+ $MGR -q check || return 1
uci_validate_section snort snort "${1}" \
+ 'enabled:bool:0' \
+ 'manual:bool:1' \
'config_dir:string' \
'interface:string'
}
start_service() {
- local config_file interface
+ # If you wish to use application-managed PID file:
+ # output.logdir, in the snort lua config, determines the PID file location.
+ # Add '--create-pidfile' to the 'command', below.
- validate_snort_section snort || {
- echo "validation failed"
- return 1
- }
+ local enabled
+ local manual
+ local config_dir
+ local interface
+
+ validate_snort_section snort || {
+ echo "Validation failed, try 'snort-mgr check'."
+ return 1
+ }
+
+ [ "$enabled" = 0 ] && return
procd_open_instance
- procd_set_param command $PROG -q -i "$interface" -c "${config_dir%/}/snort.lua" --tweaks local
- procd_set_param env SNORT_LUA_PATH="$config_dir"
- procd_set_param file $CONFIGFILE
+ if [ "$manual" = 0 ]; then
+ local config_file=$($MGR setup)
+ procd_set_param command "$PROG" -q -c "${config_file}"
+ else
+ procd_set_param command $PROG -q -i "$interface" -c "${config_dir%/}/snort.lua" --tweaks local
+ procd_set_param env SNORT_LUA_PATH="$config_dir"
+ procd_set_param file $CONFIGFILE
+ fi
procd_set_param respawn
+ procd_set_param stdout 0
+ procd_set_param stderr 1
procd_close_instance
}
stop_service()
{
- service_stop ${PROG}
+ service_stop "$PROG"
+ $MGR teardown
}
service_triggers()
--- /dev/null
+{%
+// Copyright (c) 2023 Eric Fahlgren <eric.fahlgren@gmail.com>
+// SPDX-License-Identifier: GPL-2.0
+
+// Create some snort-format-specific items.
+
+let home_net = snort.home_net == 'any' ? "'any'" : snort.home_net;
+let external_net = snort.external_net;
+
+let line_mode = snort.mode == "ids" ? "tap" : "inline";
+
+let inputs = null;
+let vars = null;
+switch (snort.method) {
+case "pcap":
+case "afpacket":
+ inputs = `{ '${snort.interface}' }`;
+ vars = "{}";
+ break;
+
+case "nfq":
+ inputs = "{ ";
+ for (let i = int(nfq.queue_start); i < int(nfq.queue_start)+int(nfq.queue_count); i++) {
+ inputs += `'${i}', `
+ }
+ inputs += "}";
+
+ vars = `{ 'device=${snort.interface}', 'queue_maxlen=${nfq.queue_maxlen}', 'fanout_type=${nfq.fanout_type}', 'fail_open', }`;
+ break;
+}
+-%}
+-- Do not edit, automatically generated. See /usr/share/snort/templates.
+
+-- These must be defined before processing snort.lua
+-- The default include '/etc/snort/homenet.lua' must not redefine them.
+HOME_NET = [[ {{ home_net }} ]]
+EXTERNAL_NET = '{{ external_net }}'
+
+include('{{ snort.config_dir }}/snort.lua')
+
+snort = {
+{% if (snort.mode == 'ips'): %}
+ ['-Q'] = true,
+{% endif %}
+ ['--daq'] = {{ snort.method }},
+--['--daq-dir'] = '/usr/lib/daq/',
+{% if (snort.method == 'nfq'): %}
+ ['--max-packet-threads'] = {{ nfq.thread_count }},
+{% endif %}
+}
+
+ips = {
+ mode = {{ line_mode }},
+ variables = default_variables,
+ action_override = {{ snort.action }},
+ include = "{{ snort.config_dir }}/" .. RULE_PATH .. '/snort.rules',
+}
+
+daq = {
+ inputs = {{ inputs }},
+ snaplen = {{ snort.snaplen }},
+ module_dirs = { '/usr/lib/daq/', },
+ modules = {
+ {
+ name = '{{ snort.method }}',
+ mode = {{ line_mode }},
+ variables = {{ vars }},
+ }
+ }
+}
+
+alert_syslog = {
+ level = 'info',
+}
+
+{% if (int(snort.logging)): %}
+-- Note that this is also the location of the PID file, if you use it.
+output.logdir = "{{ snort.log_dir }}"
+
+-- Maybe add snort.log_type, 'fast', 'json' and 'full'?
+-- Json would be best for reporting, see 'snort-mgr report' code.
+-- alert_full = { file = true, }
+
+alert_fast = {
+-- bool alert_fast.file = false: output to alert_fast.txt instead of stdout
+-- bool alert_fast.packet = false: output packet dump with alert
+-- int alert_fast.limit = 0: set maximum size in MB before rollover (0 is unlimited) { 0:maxSZ }
+ file = true,
+ packet = false,
+}
+alert_json = {
+-- bool alert_json.file = false: output to alert_json.txt instead of stdout
+-- multi alert_json.fields = timestamp pkt_num proto pkt_gen pkt_len dir src_ap dst_ap rule action: selected fields will be output
+-- int alert_json.limit = 0: set maximum size in MB before rollover (0 is unlimited) { 0:maxSZ }
+-- string alert_json.separator = , : separate fields with this character sequence
+ file = true,
+}
+
+{% endif -%}
+
+normalizer = {
+ tcp = {
+ ips = true,
+ }
+}
+
+file_policy = {
+ enable_type = true,
+ enable_signature = true,
+ rules = {
+ use = {
+ verdict = 'log',
+ enable_file_type = true,
+ enable_file_signature = true,
+ }
+ }
+}
+
+-- To use openappid with snort, 'opkg install openappid' and enable in config.
+{% if (int(snort.openappid)): %}
+appid = {
+ log_stats = true,
+ app_detector_dir = '/usr/lib/openappid',
+ app_stats_period = 60,
+}
+{% endif %}
--- /dev/null
+--- a/src/network_inspectors/packet_capture/packet_capture.h
++++ b/src/network_inspectors/packet_capture/packet_capture.h
+@@ -20,9 +20,10 @@
+ #ifndef PACKET_CAPTURE_H
+ #define PACKET_CAPTURE_H
+
++#include <cstdint>
+ #include <string>
+
+-void packet_capture_enable(const std::string&, const int16_t g = -1);
++void packet_capture_enable(const std::string&, const std::int16_t g = -1);
+ void packet_capture_disable();
+
+ #endif
include $(TOPDIR)/rules.mk
PKG_NAME:=snowflake
-PKG_VERSION:=2.6.0
+PKG_VERSION:=2.8.0
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
-PKG_MIRROR_HASH:=a982f792c0184158e1842d8d191a7786f46030725bf3da1410c0d70b274cbd62
+PKG_MIRROR_HASH:=20ff3c292be6d91f535b009b95578d708daeb8b88cc2290e69feade7b844bf60
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
TITLE+= Client
endef
-define Package/snowflake-distinctcounter
-$(call Package/snowflake/Default)
- TITLE+= Distinct Counter
-endef
-
define Package/snowflake-probetest
$(call Package/snowflake/Default)
TITLE+= Probe test
This package contains the Snowflake client which provides the bridge to TOR.
endef
-define Package/snowflake-distinctcounter/description
-$(call Package/snowflake/description/Default)
-
-This package provides the Snowflake distinct counter service.
-endef
-
define Package/snowflake-probetest/description
$(call Package/snowflake/description/Default)
$(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/client $(1)/usr/bin/snowflake-client
endef
-define Package/snowflake-distinctcounter/install
- $(INSTALL_DIR) $(1)/usr/bin
- $(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/distinctcounter $(1)/usr/bin/snowflake-distinctcounter
-endef
-
define Package/snowflake-probetest/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(GO_PKG_BUILD_BIN_DIR)/probetest $(1)/usr/bin/snowflake-probetest
$(eval $(call BuildPackage,snowflake-broker))
$(eval $(call BuildPackage,snowflake-client))
-$(eval $(call BuildPackage,snowflake-distinctcounter))
$(eval $(call BuildPackage,snowflake-probetest))
$(eval $(call BuildPackage,snowflake-proxy))
$(eval $(call BuildPackage,snowflake-server))
+++ /dev/null
-From 08d1c6d6551464d526d4bbe608384b8e7dec32ee Mon Sep 17 00:00:00 2001
-From: Cecylia Bocovich <cohosh@torproject.org>
-Date: Tue, 20 Jun 2023 14:49:36 -0400
-Subject: [PATCH] Bump minimum required version of go
-
-The version of x/sys we're using requires go1.17 or later
----
- go.mod | 41 ++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 40 insertions(+), 1 deletion(-)
-
---- a/go.mod
-+++ b/go.mod
-@@ -1,6 +1,6 @@
- module gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2
-
--go 1.15
-+go 1.17
-
- require (
- github.com/clarkduvall/hyperloglog v0.0.0-20171127014514-a0107a5d8004
-@@ -23,3 +23,42 @@ require (
- golang.org/x/sys v0.5.0
- google.golang.org/protobuf v1.26.0
- )
-+
-+require (
-+ github.com/beorn7/perks v1.0.1 // indirect
-+ github.com/cespare/xxhash/v2 v2.1.1 // indirect
-+ github.com/davecgh/go-spew v1.1.1 // indirect
-+ github.com/golang/protobuf v1.5.2 // indirect
-+ github.com/google/uuid v1.3.0 // indirect
-+ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
-+ github.com/jtolds/gls v4.20.0+incompatible // indirect
-+ github.com/klauspost/cpuid v1.3.1 // indirect
-+ github.com/klauspost/reedsolomon v1.9.9 // indirect
-+ github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
-+ github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104 // indirect
-+ github.com/pion/datachannel v1.5.5 // indirect
-+ github.com/pion/dtls/v2 v2.2.6 // indirect
-+ github.com/pion/interceptor v0.1.12 // indirect
-+ github.com/pion/logging v0.2.2 // indirect
-+ github.com/pion/mdns v0.0.7 // indirect
-+ github.com/pion/randutil v0.1.0 // indirect
-+ github.com/pion/rtcp v1.2.10 // indirect
-+ github.com/pion/rtp v1.7.13 // indirect
-+ github.com/pion/sctp v1.8.6 // indirect
-+ github.com/pion/srtp/v2 v2.0.12 // indirect
-+ github.com/pion/transport/v2 v2.0.2 // indirect
-+ github.com/pion/turn/v2 v2.1.0 // indirect
-+ github.com/pion/udp/v2 v2.0.1 // indirect
-+ github.com/pkg/errors v0.9.1 // indirect
-+ github.com/pmezard/go-difflib v1.0.0 // indirect
-+ github.com/prometheus/common v0.18.0 // indirect
-+ github.com/prometheus/procfs v0.6.0 // indirect
-+ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
-+ github.com/templexxx/cpu v0.0.7 // indirect
-+ github.com/templexxx/xorsimd v0.4.1 // indirect
-+ github.com/tjfoc/gmsm v1.3.2 // indirect
-+ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
-+ golang.org/x/text v0.7.0 // indirect
-+ golang.org/x/tools v0.1.12 // indirect
-+ gopkg.in/yaml.v3 v3.0.1 // indirect
-+)
+++ /dev/null
-From aaeab3f4157d90fdc2db4ab6e0ba0547351f10c1 Mon Sep 17 00:00:00 2001
-From: meskio <meskio@torproject.org>
-Date: Mon, 3 Jul 2023 19:52:57 +0200
-Subject: [PATCH] Update dependencies
-
-So renovate doesn't create tons of merge requests.
----
- go.mod | 68 ++++----
- go.sum | 481 +++++++++++++--------------------------------------------
- 2 files changed, 143 insertions(+), 406 deletions(-)
-
---- a/go.mod
-+++ b/go.mod
-@@ -5,60 +5,60 @@ go 1.17
- require (
- github.com/clarkduvall/hyperloglog v0.0.0-20171127014514-a0107a5d8004
- github.com/gorilla/websocket v1.5.0
-- github.com/pion/ice/v2 v2.3.1
-+ github.com/pion/ice/v2 v2.3.8
- github.com/pion/sdp/v3 v3.0.6
-- github.com/pion/stun v0.4.0
-- github.com/pion/webrtc/v3 v3.1.57
-- github.com/prometheus/client_golang v1.10.0
-- github.com/prometheus/client_model v0.2.0
-- github.com/refraction-networking/utls v1.0.0
-+ github.com/pion/stun v0.6.1
-+ github.com/pion/webrtc/v3 v3.2.11
-+ github.com/prometheus/client_golang v1.16.0
-+ github.com/prometheus/client_model v0.4.0
-+ github.com/refraction-networking/utls v1.3.2
- github.com/smartystreets/goconvey v1.6.4
-- github.com/stretchr/testify v1.8.1
-- github.com/xtaci/kcp-go/v5 v5.6.1
-- github.com/xtaci/smux v1.5.15
-+ github.com/stretchr/testify v1.8.4
-+ github.com/xtaci/kcp-go/v5 v5.6.2
-+ github.com/xtaci/smux v1.5.24
- gitlab.torproject.org/tpo/anti-censorship/geoip v0.0.0-20210928150955-7ce4b3d98d01
- gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.4.0
-- golang.org/x/crypto v0.6.0
-- golang.org/x/net v0.7.0
-- golang.org/x/sys v0.5.0
-- google.golang.org/protobuf v1.26.0
-+ golang.org/x/crypto v0.10.0
-+ golang.org/x/net v0.11.0
-+ golang.org/x/sys v0.9.0
-+ google.golang.org/protobuf v1.31.0
- )
-
- require (
-+ github.com/andybalholm/brotli v1.0.5 // indirect
- github.com/beorn7/perks v1.0.1 // indirect
-- github.com/cespare/xxhash/v2 v2.1.1 // indirect
-+ github.com/cespare/xxhash/v2 v2.2.0 // indirect
- github.com/davecgh/go-spew v1.1.1 // indirect
-- github.com/golang/protobuf v1.5.2 // indirect
-+ github.com/gaukas/godicttls v0.0.4 // indirect
-+ github.com/golang/protobuf v1.5.3 // indirect
- github.com/google/uuid v1.3.0 // indirect
- github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
- github.com/jtolds/gls v4.20.0+incompatible // indirect
-- github.com/klauspost/cpuid v1.3.1 // indirect
-- github.com/klauspost/reedsolomon v1.9.9 // indirect
-- github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
-- github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104 // indirect
-+ github.com/klauspost/compress v1.16.7 // indirect
-+ github.com/klauspost/cpuid/v2 v2.2.5 // indirect
-+ github.com/klauspost/reedsolomon v1.11.8 // indirect
-+ github.com/kr/text v0.2.0 // indirect
-+ github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
- github.com/pion/datachannel v1.5.5 // indirect
-- github.com/pion/dtls/v2 v2.2.6 // indirect
-- github.com/pion/interceptor v0.1.12 // indirect
-+ github.com/pion/dtls/v2 v2.2.7 // indirect
-+ github.com/pion/interceptor v0.1.17 // indirect
- github.com/pion/logging v0.2.2 // indirect
- github.com/pion/mdns v0.0.7 // indirect
- github.com/pion/randutil v0.1.0 // indirect
- github.com/pion/rtcp v1.2.10 // indirect
- github.com/pion/rtp v1.7.13 // indirect
-- github.com/pion/sctp v1.8.6 // indirect
-- github.com/pion/srtp/v2 v2.0.12 // indirect
-- github.com/pion/transport/v2 v2.0.2 // indirect
-- github.com/pion/turn/v2 v2.1.0 // indirect
-- github.com/pion/udp/v2 v2.0.1 // indirect
-+ github.com/pion/sctp v1.8.7 // indirect
-+ github.com/pion/srtp/v2 v2.0.15 // indirect
-+ github.com/pion/transport/v2 v2.2.1 // indirect
-+ github.com/pion/turn/v2 v2.1.2 // indirect
- github.com/pkg/errors v0.9.1 // indirect
- github.com/pmezard/go-difflib v1.0.0 // indirect
-- github.com/prometheus/common v0.18.0 // indirect
-- github.com/prometheus/procfs v0.6.0 // indirect
-+ github.com/prometheus/common v0.44.0 // indirect
-+ github.com/prometheus/procfs v0.11.0 // indirect
- github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
-- github.com/templexxx/cpu v0.0.7 // indirect
-- github.com/templexxx/xorsimd v0.4.1 // indirect
-- github.com/tjfoc/gmsm v1.3.2 // indirect
-- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
-- golang.org/x/text v0.7.0 // indirect
-- golang.org/x/tools v0.1.12 // indirect
-+ github.com/templexxx/cpu v0.1.0 // indirect
-+ github.com/templexxx/xorsimd v0.4.2 // indirect
-+ github.com/tjfoc/gmsm v1.4.1 // indirect
-+ golang.org/x/text v0.10.0 // indirect
- gopkg.in/yaml.v3 v3.0.1 // indirect
- )
---- a/go.sum
-+++ b/go.sum
-@@ -1,239 +1,91 @@
- cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
--cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
- github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
--github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
--github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
--github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
--github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
--github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
--github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
--github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
--github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
--github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
--github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
--github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
--github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
--github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
--github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
--github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
--github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
--github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
--github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
--github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
--github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
--github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
-+github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
-+github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
- github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
- github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
--github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
--github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
--github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
- github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
--github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
--github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
-+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
- github.com/clarkduvall/hyperloglog v0.0.0-20171127014514-a0107a5d8004 h1:mK6JroY6bLiPS3s6QCYOSjRyErFc2iHNkhhmRfF0nHo=
- github.com/clarkduvall/hyperloglog v0.0.0-20171127014514-a0107a5d8004/go.mod h1:drodPoQNro6QBO6TJ/MpMZbz8Bn2eSDtRN6jpG4VGw8=
--github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
- github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
--github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
--github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
--github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
--github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
--github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
--github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
--github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
-+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
- github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
- github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
- github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
--github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
--github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
--github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
--github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
--github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
--github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
--github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
--github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
- github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
--github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
--github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
--github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
- github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
- github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
--github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
--github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
--github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
--github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
--github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
--github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
--github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
--github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
--github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-+github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
-+github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
- github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
--github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
--github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
--github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
--github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
- github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
--github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
--github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
- github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
- github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
--github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
- github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
- github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
- github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
- github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
- github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
- github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
- github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
--github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
- github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
--github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
- github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
--github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
--github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
--github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
-+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
- github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
- github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
- github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
- github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
--github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
--github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
- github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
--github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
--github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
--github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
- github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
- github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
- github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
- github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
--github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
--github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
--github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
--github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
- github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
- github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
--github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
--github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
--github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
--github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
--github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
--github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
--github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
--github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
--github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
--github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
--github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
--github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
--github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
--github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
--github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
--github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
--github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
--github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
--github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
--github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
--github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
--github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
--github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
- github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
--github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
--github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
--github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
--github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
--github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
--github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
--github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
--github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
--github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
--github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
- github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
- github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
--github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
--github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
--github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
--github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
--github.com/klauspost/cpuid v1.2.4/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
--github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
--github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
--github.com/klauspost/reedsolomon v1.9.9 h1:qCL7LZlv17xMixl55nq2/Oa1Y86nfO8EqDfv2GHND54=
--github.com/klauspost/reedsolomon v1.9.9/go.mod h1:O7yFFHiQwDR6b2t63KPUpccPtNdp5ADgh1gg4fd12wo=
--github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
--github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
--github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
--github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
-+github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
-+github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
-+github.com/klauspost/cpuid/v2 v2.0.14/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
-+github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
-+github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
-+github.com/klauspost/reedsolomon v1.10.0/go.mod h1:qHMIzMkuZUWqIh8mS/GruPdo3u0qwX2jk/LH440ON7Y=
-+github.com/klauspost/reedsolomon v1.11.8 h1:s8RpUW5TK4hjr+djiOpbZJB4ksx+TdYbRH7vHQpwPOY=
-+github.com/klauspost/reedsolomon v1.11.8/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A=
- github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
- github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
--github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
- github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
--github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
--github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
--github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
--github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
--github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
--github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
--github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
--github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
--github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
--github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
--github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
--github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
--github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
--github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
--github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
--github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
--github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
--github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104 h1:ULR/QWMgcgRiZLUjSSJMU+fW+RDMstRdmnDWj9Q+AsA=
--github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104/go.mod h1:wqKykBG2QzQDJEzvRkcS8x6MiSJkF52hXZsXcjaB3ls=
--github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
--github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
--github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
--github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
--github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
--github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
--github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
--github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
--github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
--github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
--github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
--github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
--github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
-+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-+github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
-+github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
- github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
- github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
--github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
--github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
--github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
- github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
--github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
- github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
- github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
- github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
--github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
- github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
- github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
- github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
--github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
--github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
--github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
--github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
--github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
--github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
--github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
--github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
--github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
--github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
--github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
--github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
--github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
--github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
--github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
- github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
- github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
--github.com/pion/dtls/v2 v2.2.6 h1:yXMxKr0Skd+Ub6A8UqXTRLSywskx93ooMRHsQUtd+Z4=
--github.com/pion/dtls/v2 v2.2.6/go.mod h1:t8fWJCIquY5rlQZwA2yWxUS1+OCrAdXrhVKXB5oD/wY=
--github.com/pion/ice/v2 v2.3.1 h1:FQCmUfZe2Jpe7LYStVBOP6z1DiSzbIateih3TztgTjc=
--github.com/pion/ice/v2 v2.3.1/go.mod h1:aq2kc6MtYNcn4XmMhobAv6hTNJiHzvD0yXRz80+bnP8=
--github.com/pion/interceptor v0.1.12 h1:CslaNriCFUItiXS5o+hh5lpL0t0ytQkFnUcbbCs2Zq8=
--github.com/pion/interceptor v0.1.12/go.mod h1:bDtgAD9dRkBZpWHGKaoKb42FhDHTG2rX8Ii9LRALLVA=
-+github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
-+github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
-+github.com/pion/ice/v2 v2.3.8 h1:/4vM7uFPJez3PhNhlqUcJhboYaDNWo+R8oAuMj2cKsA=
-+github.com/pion/ice/v2 v2.3.8/go.mod h1:DoMA9FvsfNTBVnjyRf2t4EhUkSp9tNrH77fMtPFYygQ=
-+github.com/pion/interceptor v0.1.17 h1:prJtgwFh/gB8zMqGZoOgJPHivOwVAp61i2aG61Du/1w=
-+github.com/pion/interceptor v0.1.17/go.mod h1:SY8kpmfVBvrbUzvj2bsXz7OJt5JvmVNZ+4Kjq7FcwrI=
- github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
- github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
- github.com/pion/mdns v0.0.7 h1:P0UB4Sr6xDWEox0kTVxF0LmQihtCbSAdW0H2nEgkA3U=
-@@ -245,297 +97,196 @@ github.com/pion/rtcp v1.2.10/go.mod h1:z
- github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA=
- github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
- github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0=
--github.com/pion/sctp v1.8.6 h1:CUex11Vkt9YS++VhLf8b55O3VqKrWL6W3SDwX4jAqsI=
--github.com/pion/sctp v1.8.6/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0=
-+github.com/pion/sctp v1.8.7 h1:JnABvFakZueGAn4KU/4PSKg+GWbF6QWbKTWZOSGJjXw=
-+github.com/pion/sctp v1.8.7/go.mod h1:g1Ul+ARqZq5JEmoFy87Q/4CePtKnTJ1QCL9dBBdN6AU=
- github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw=
- github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw=
--github.com/pion/srtp/v2 v2.0.12 h1:WrmiVCubGMOAObBU1vwWjG0H3VSyQHawKeer2PVA5rY=
--github.com/pion/srtp/v2 v2.0.12/go.mod h1:C3Ep44hlOo2qEYaq4ddsmK5dL63eLehXFbHaZ9F5V9Y=
--github.com/pion/stun v0.4.0 h1:vgRrbBE2htWHy7l3Zsxckk7rkjnjOsSM7PHZnBwo8rk=
-+github.com/pion/srtp/v2 v2.0.15 h1:+tqRtXGsGwHC0G0IUIAzRmdkHvriF79IHVfZGfHrQoA=
-+github.com/pion/srtp/v2 v2.0.15/go.mod h1:b/pQOlDrbB0HEH5EUAQXzSYxikFbNcNuKmF8tM0hCtw=
- github.com/pion/stun v0.4.0/go.mod h1:QPsh1/SbXASntw3zkkrIk3ZJVKz4saBY2G7S10P3wCw=
-+github.com/pion/stun v0.6.0/go.mod h1:HPqcfoeqQn9cuaet7AOmB5e5xkObu9DwBdurwLKO9oA=
-+github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
-+github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
- github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40=
- github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI=
- github.com/pion/transport/v2 v2.0.0/go.mod h1:HS2MEBJTwD+1ZI2eSXSvHJx/HnzQqRy2/LXxt6eVMHc=
--github.com/pion/transport/v2 v2.0.2 h1:St+8o+1PEzPT51O9bv+tH/KYYLMNR5Vwm5Z3Qkjsywg=
--github.com/pion/transport/v2 v2.0.2/go.mod h1:vrz6bUbFr/cjdwbnxq8OdDDzHf7JJfGsIRkxfpZoTA0=
--github.com/pion/turn/v2 v2.1.0 h1:5wGHSgGhJhP/RpabkUb/T9PdsAjkGLS6toYz5HNzoSI=
-+github.com/pion/transport/v2 v2.1.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ=
-+github.com/pion/transport/v2 v2.2.0/go.mod h1:AdSw4YBZVDkZm8fpoz+fclXyQwANWmZAlDuQdctTThQ=
-+github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c=
-+github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
- github.com/pion/turn/v2 v2.1.0/go.mod h1:yrT5XbXSGX1VFSF31A3c1kCNB5bBZgk/uu5LET162qs=
--github.com/pion/udp/v2 v2.0.1 h1:xP0z6WNux1zWEjhC7onRA3EwwSliXqu1ElUZAQhUP54=
--github.com/pion/udp/v2 v2.0.1/go.mod h1:B7uvTMP00lzWdyMr/1PVZXtV3wpPIxBRd4Wl6AksXn8=
--github.com/pion/webrtc/v3 v3.1.57 h1:dv0xnlAEwXKsoHkWcH1kVBodMTxSNCT9L/t8TAhFaQ0=
--github.com/pion/webrtc/v3 v3.1.57/go.mod h1:7VhbA6ihqJlz6R/INHjyh1b8HpiV9Ct4UQvE1OB/xoM=
--github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
--github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-+github.com/pion/turn/v2 v2.1.2 h1:wj0cAoGKltaZ790XEGW9HwoUewqjliwmhtxCuB2ApyM=
-+github.com/pion/turn/v2 v2.1.2/go.mod h1:1kjnPkBcex3dhCU2Am+AAmxDcGhLX3WnMfmkNpvSTQU=
-+github.com/pion/webrtc/v3 v3.2.11 h1:lfGKYZcG7ghCTQWn+zsD+icIIWL3qIfclEjBGk537+s=
-+github.com/pion/webrtc/v3 v3.2.11/go.mod h1:fejQio1v8tKG4ntq4u8H4uDHsCNX6eX7bT093t4H+0E=
- github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
- github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
--github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
- github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
- github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
--github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
--github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
--github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
--github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
--github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
--github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
--github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg=
--github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU=
--github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
--github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
--github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-+github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
-+github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
- github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
--github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
--github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
--github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
--github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
--github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
--github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
--github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
--github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y=
--github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
--github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
--github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
--github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
--github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
--github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
--github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
--github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
--github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
--github.com/refraction-networking/utls v1.0.0 h1:6XQHSjDmeBCF9sPq8p2zMVGq7Ud3rTD2q88Fw8Tz1tA=
--github.com/refraction-networking/utls v1.0.0/go.mod h1:tz9gX959MEFfFN5whTIocCLUG57WiILqtdVxI8c6Wj0=
--github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
--github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
--github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
--github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
--github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
-+github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
-+github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
-+github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
-+github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
-+github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk=
-+github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
-+github.com/refraction-networking/utls v1.3.2 h1:o+AkWB57mkcoW36ET7uJ002CpBWHu0KPxi6vzxvPnv8=
-+github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E=
-+github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
- github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
--github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
--github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
--github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
--github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
--github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
- github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
- github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
- github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
- github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
--github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
--github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
--github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
--github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
--github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
--github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
--github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
- github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
--github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
- github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
- github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
--github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
--github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
--github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
- github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
- github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
- github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
- github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
--github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
- github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-+github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
-+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
- github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
--github.com/templexxx/cpu v0.0.7 h1:pUEZn8JBy/w5yzdYWgx+0m0xL9uk6j4K91C5kOViAzo=
--github.com/templexxx/cpu v0.0.7/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
--github.com/templexxx/xorsimd v0.4.1 h1:iUZcywbOYDRAZUasAs2eSCUW8eobuZDy0I9FJiORkVg=
-+github.com/templexxx/cpu v0.0.9/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
-+github.com/templexxx/cpu v0.1.0 h1:wVM+WIJP2nYaxVxqgHPD4wGA2aJ9rvrQRV8CvFzNb40=
-+github.com/templexxx/cpu v0.1.0/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk=
- github.com/templexxx/xorsimd v0.4.1/go.mod h1:W+ffZz8jJMH2SXwuKu9WhygqBMbFnp14G2fqEr8qaNo=
--github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM=
--github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
--github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
--github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
--github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
--github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
--github.com/xtaci/kcp-go/v5 v5.6.1 h1:Pwn0aoeNSPF9dTS7IgiPXn0HEtaIlVb6y5UKWPsx8bI=
--github.com/xtaci/kcp-go/v5 v5.6.1/go.mod h1:W3kVPyNYwZ06p79dNwFWQOVFrdcBpDBsdyvK8moQrYo=
-+github.com/templexxx/xorsimd v0.4.2 h1:ocZZ+Nvu65LGHmCLZ7OoCtg8Fx8jnHKK37SjvngUoVI=
-+github.com/templexxx/xorsimd v0.4.2/go.mod h1:HgwaPoDREdi6OnULpSfxhzaiiSUY4Fi3JPn1wpt28NI=
-+github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
-+github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
-+github.com/xtaci/kcp-go/v5 v5.6.2 h1:pSXMa5MOsb+EIZKe4sDBqlTExu2A/2Z+DFhoX2qtt2A=
-+github.com/xtaci/kcp-go/v5 v5.6.2/go.mod h1:LsinWoru+lWWJHb+EM9HeuqYxV6bb9rNcK12v67jYzQ=
- github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
- github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
--github.com/xtaci/smux v1.5.15 h1:6hMiXswcleXj5oNfcJc+DXS8Vj36XX2LaX98udog6Kc=
--github.com/xtaci/smux v1.5.15/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
--github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
--github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-+github.com/xtaci/smux v1.5.24 h1:77emW9dtnOxxOQ5ltR+8BbsX1kzcOxQ5gB+aaV9hXOY=
-+github.com/xtaci/smux v1.5.24/go.mod h1:OMlQbT5vcgl2gb49mFkYo6SMf+zP3rcjcwQz7ZU7IGY=
- github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
- github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
- gitlab.torproject.org/tpo/anti-censorship/geoip v0.0.0-20210928150955-7ce4b3d98d01 h1:4949mHh9Vj2/okk48yG8nhP6TosFWOUfSfSr502sKGE=
- gitlab.torproject.org/tpo/anti-censorship/geoip v0.0.0-20210928150955-7ce4b3d98d01/go.mod h1:K3LOI4H8fa6j+7E10ViHeGEQV10304FG4j94ypmKLjY=
- gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.4.0 h1:Y7fHDMy11yyjM+YlHfcM3svaujdL+m5DqS444wbj8o4=
- gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.4.0/go.mod h1:70bhd4JKW/+1HLfm+TMrgHJsUHG4coelMWwiVEJ2gAg=
--go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
--go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
--go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
--go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
--go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
--go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
--go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
--go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
--go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
--go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
--go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
--go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
--golang.org/x/arch v0.0.0-20190909030613-46d78d1859ac/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
--golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
--golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
- golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
--golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
--golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
- golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
--golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
- golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
--golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-+golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
- golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
--golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
--golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
--golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
-+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-+golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
-+golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
-+golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
-+golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
- golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
- golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
- golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
--golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
- golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
--golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
--golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
--golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
--golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
- golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
--golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
- golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
- golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
- golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
--golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
--golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
--golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
--golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
--golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
--golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
- golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
- golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
- golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
--golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
--golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
- golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
--golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
--golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
- golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
--golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
--golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-+golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
- golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
- golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
- golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
-+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-+golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
- golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
- golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
- golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
- golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
--golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
--golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
-+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-+golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
-+golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
- golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
--golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
- golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
- golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
- golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
--golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
- golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
--golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
--golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
- golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
--golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
- golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
--golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
- golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
--golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
- golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
--golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
--golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
--golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
--golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
- golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
- golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
- golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
- golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
- golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
- golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
- golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
- golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
- golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
--golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
- golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
- golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
- golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-+golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
- golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
- golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
- golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
- golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
--golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
- golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-+golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
- golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
- golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
- golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
- golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
- golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
-+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
- golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
--golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
- golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
- golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
- golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
- golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
- golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
--golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
- golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
--golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
--golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
--golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
--golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-+golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-+golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
- golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
- golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
- golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
- golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
--golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
- golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
- golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
--golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
--golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
--golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
- golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
--golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
--golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
--golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
- golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
--golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
- golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
- golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
- golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
- golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
--golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
- golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
--google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
- google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
--google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
- google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
- google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
--google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
--google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
--google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
- google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
--google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
- google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
--google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
--google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
--google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
--google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
- google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
--google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
--google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
- google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
- google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
- google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-@@ -543,34 +294,20 @@ google.golang.org/protobuf v1.20.1-0.202
- google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
- google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
- google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
--google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
- google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
--gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
-+google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
-+google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
- gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
--gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
--gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
- gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
--gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
--gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
- gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
--gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
--gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
- gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
--gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
--gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
--gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
- gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
- gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
--gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
- gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
- gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
- gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
- gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
- gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
--honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
- honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
- honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
--honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
--rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
--sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
--sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
include $(TOPDIR)/rules.mk
PKG_NAME:=speedtestcpp
-PKG_VERSION:=1.20.2
+PKG_VERSION:=1.20.3
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/oskarirauta/speedtestcpp/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=7d5c85f1d9a46f7d8a3ac4261ef1f92e53c511430bae096f7ec6f12a33d38904
+PKG_HASH:=8154e2161c56c0ac1275e57c34f448aaf98fb49937ff824ce975d95984395025
PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
PKG_LICENSE:=MIT
include $(TOPDIR)/rules.mk
PKG_NAME:=sstp-client
-PKG_VERSION:=1.0.15
-PKG_RELEASE:=1
+PKG_VERSION:=1.0.19
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=@SF/sstp-client/$(PKG_VERSION)
-PKG_HASH:=8484aa51fbfbe418a0ebad58ad20a8ee1c46ed71f800be18bcd23b42e6baad64
+PKG_SOURCE_URL:=https://gitlab.com/sstp-project/sstp-client/-/archive/1.0.19/
+PKG_HASH:=e2652365f69f5037102e78f4e115ff764a390b27bb3fd513a8a50b10a61bb613
PKG_MAINTAINER:=Federico Di Marco <fededim@gmail.com>
PKG_LICENSE:=GPL-2.0-or-later
PKG_LICENSE_FILES:=COPYING
+PKG_FIXUP:=autoreconf
+
include $(INCLUDE_DIR)/package.mk
define Package/sstp-client
proto_sstp_init_config() {
proto_config_add_string "server"
+ proto_config_add_string "port"
proto_config_add_string "username"
proto_config_add_string "password"
proto_config_add_string "pppd_options"
local iface="$2"
local ifname="sstp-$config"
- local ip serv_addr server ipv6 defaultroute peerdns
+ local ip serv_addr server port ipv6 defaultroute peerdns
json_get_var server server && {
for ip in $(resolveip -t 5 "$server"); do
( proto_add_host_dependency "$config" "$ip" )
exit 1
}
- json_get_vars username password pppd_options sstp_options log_level ipv6 defaultroute peerdns
+ json_get_vars port username password pppd_options sstp_options log_level ipv6 defaultroute peerdns
if [ "$ipv6" = 1 ]; then
ipv6=1
else
--save-server-route \
--ipparam $config \
$sstp_options \
- $server \
+ $server${port:+:$port} \
ifname $ifname \
require-mschap-v2 \
${ipv6:++ipv6} \
--- a/src/sstp-client.c
+++ b/src/sstp-client.c
-@@ -542,6 +542,7 @@ static status_t sstp_init_ssl(sstp_clien
+@@ -546,6 +546,7 @@ static status_t sstp_init_ssl(sstp_clien
int retval = SSTP_FAIL;
int status = 0;
/* Initialize the OpenSSL library */
status = SSL_library_init();
if (status != 1)
-@@ -555,6 +556,9 @@ static status_t sstp_init_ssl(sstp_clien
+@@ -575,6 +576,9 @@ static status_t sstp_init_ssl(sstp_clien
/* Create a new crypto context */
client->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
include $(TOPDIR)/rules.mk
PKG_NAME:=strongswan
-PKG_VERSION:=5.9.11
+PKG_VERSION:=5.9.13
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://download.strongswan.org/ https://download2.strongswan.org/
-PKG_HASH:=ddf53f1f26ad26979d5f55e8da95bd389552f5de3682e35593f9a70b2584ed2d
+PKG_HASH:=56e30effb578fd9426d8457e3b76c8c3728cd8a5589594b55649b2719308ba55
PKG_LICENSE:=GPL-2.0-or-later
PKG_MAINTAINER:=Philip Prindeville <philipp@redfish-solutions.com>, Noel Kuntze <noel.kuntze@thermi.consulting>
PKG_CPE_ID:=cpe:/a:strongswan:strongswan
dnskey \
drbg \
duplicheck \
+ eap-dynamic \
eap-identity \
eap-md5 \
eap-mschapv2 \
+strongswan-mod-dnskey \
+strongswan-mod-drbg \
+strongswan-mod-duplicheck \
+ +strongswan-mod-eap-dynamic \
+strongswan-mod-eap-identity \
+strongswan-mod-eap-md5 \
+strongswan-mod-eap-mschapv2 \
$(eval $(call BuildPlugin,dnskey,DNS RR key decoding,))
$(eval $(call BuildPlugin,drbg,Deterministic random bit generator,,))
$(eval $(call BuildPlugin,duplicheck,advanced duplicate checking,))
+$(eval $(call BuildPlugin,eap-dynamic,EAP dynamic selector,))
$(eval $(call BuildPlugin,eap-identity,EAP identity helper,))
$(eval $(call BuildPlugin,eap-md5,EAP MD5 (CHAP) EAP auth,))
$(eval $(call BuildPlugin,eap-mschapv2,EAP MS-CHAPv2 EAP auth,+strongswan-mod-md4 +strongswan-mod-des))
local lifebytes
local rekeypackets
local lifepackets
+ local replay_window
config_get startaction "$conf" startaction "route"
config_get local_nat "$conf" local_nat ""
config_get lifebytes "$conf" lifebytes ""
config_get rekeypackets "$conf" rekeypackets ""
config_get lifepackets "$conf" lifepackets ""
+ config_get replay_window "$conf" replay_window ""
config_list_foreach "$conf" local_subnet append_var local_subnet ","
config_list_foreach "$conf" remote_subnet append_var remote_subnet ","
[ -n "$updown" ] && swanctl_xappend4 "updown = $updown"
[ -n "$dpdaction" ] && swanctl_xappend4 "dpd_action = $dpdaction"
+ [ -n "$replay_window" ] && swanctl_xappend4 "replay_window = $replay_window"
swanctl_xappend3 "}"
}
#include <linux/rtnetlink.h>
--- a/src/libstrongswan/library.h
+++ b/src/libstrongswan/library.h
-@@ -120,6 +120,7 @@
+@@ -121,6 +121,7 @@
#include "utils/leak_detective.h"
#include "plugins/plugin_loader.h"
#include "settings/settings.h"
ARG_DISBL_SET([curve25519], [disable Curve25519 Diffie-Hellman plugin.])
ARG_DISBL_SET([hmac], [disable HMAC crypto implementation plugin.])
ARG_DISBL_SET([kdf], [disable KDF (prf+) implementation plugin.])
-@@ -1565,6 +1566,7 @@ ADD_PLUGIN([pkcs8], [s ch
+@@ -1574,6 +1575,7 @@ ADD_PLUGIN([pkcs8], [s ch
ADD_PLUGIN([af-alg], [s charon pki scripts medsrv attest nm cmd aikgen])
ADD_PLUGIN([fips-prf], [s charon nm cmd])
ADD_PLUGIN([gmp], [s charon pki scripts manager medsrv attest nm cmd aikgen fuzz])
ADD_PLUGIN([curve25519], [s charon pki scripts nm cmd])
ADD_PLUGIN([agent], [s charon nm cmd])
ADD_PLUGIN([keychain], [s charon cmd])
-@@ -1706,6 +1708,7 @@ AM_CONDITIONAL(USE_SHA3, test x$sha3 = x
+@@ -1716,6 +1718,7 @@ AM_CONDITIONAL(USE_SHA3, test x$sha3 = x
AM_CONDITIONAL(USE_MGF1, test x$mgf1 = xtrue)
AM_CONDITIONAL(USE_FIPS_PRF, test x$fips_prf = xtrue)
AM_CONDITIONAL(USE_GMP, test x$gmp = xtrue)
AM_CONDITIONAL(USE_CURVE25519, test x$curve25519 = xtrue)
AM_CONDITIONAL(USE_RDRAND, test x$rdrand = xtrue)
AM_CONDITIONAL(USE_AESNI, test x$aesni = xtrue)
-@@ -1983,6 +1986,7 @@ AC_CONFIG_FILES([
+@@ -1996,6 +1999,7 @@ AC_CONFIG_FILES([
src/libstrongswan/plugins/mgf1/Makefile
src/libstrongswan/plugins/fips_prf/Makefile
src/libstrongswan/plugins/gmp/Makefile
src/libstrongswan/plugins/aesni/Makefile
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
-@@ -353,6 +353,13 @@ if MONOLITHIC
+@@ -357,6 +357,13 @@ if MONOLITHIC
endif
endif
include $(TOPDIR)/rules.mk
PKG_NAME:=tailscale
-PKG_VERSION:=1.50.1
+PKG_VERSION:=1.54.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/tailscale/tailscale/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=183a7d559590a759dd77aa9c2b65486ab6e13c26f3c07fad0b536e318ad5e233
+PKG_HASH:=c895a0f489706535ed400b0599d7d932d9eebc5f1bad2c236408a1e4b86620e7
PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com>
PKG_LICENSE:=BSD-3-Clause
include $(TOPDIR)/rules.mk
PKG_NAME:=tgt
-PKG_VERSION:=1.0.87
+PKG_VERSION:=1.0.89
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/fujita/tgt/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=975bb23b4762f2e2a8e787b79afa7fb44442c5afabaea0e469fca0169826077a
+PKG_HASH:=cd09daffacc00a6641a7b95d31c43441656ce0b01af8d512359bc91bac3c6d99
PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
PKG_LICENSE:=GPL-2.0-only
PKG_NAME:=tinc
PKG_VERSION:=1.1pre18
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://tinc-vpn.org/packages
HOST_CONF_FILE="$TMP_TINC/$n/hosts/$s"
MANDATORY_PARAM_IN_UCI=0
[ ! -f "/etc/tinc/$n/hosts/$s" ] && {
- config_get pk "$s" "PublicKey"
+ config_get pk_i "$s" "PublicKey"
+ config_get pk_f "$s" "PublicKeyFile"
+ config_get pked_i "$s" "Ed25519PublicKey"
+ config_get pked_f "$s" "Ed25519PublicKeyFile"
config_get na "$s" "Name"
- if [ -n "$pk" -a -n "$na" ] ; then
- HOST_CONF_FILE="$TMP_TINC/$n/hosts/$na"
- MANDATORY_PARAM_IN_UCI=1
+ if [ -n "$na" ] ; then
+ HOST_CONF_FILE="$TMP_TINC/$n/hosts/$na"
+ fi
+ if [ -n "$pk_i$pk_f$pked_i$pked_f" ] ; then
+ MANDATORY_PARAM_IN_UCI=1
fi
}
[ ! -f "/etc/tinc/$n/hosts/$s" ] && {
if [ "$MANDATORY_PARAM_IN_UCI" -eq 1 ] ; then
- touch "$HOST_CONF_FILE" ;
+ touch "$HOST_CONF_FILE"
else
echo -n "tinc: Warning, public key for $s for network $n "
echo -n "missing in /etc/tinc/$n/hosts/$s, "
# append flags
append_conf_bools "$s" "$HOST_CONF_FILE" \
- ClampMSS IndirectData PMTUDiscovery TCPOnly
+ ClampMSS \
+ IndirectData \
+ PMTUDiscovery \
+ TCPOnly
# append params
append_conf_params "$s" "$HOST_CONF_FILE" \
- Address Cipher Compression Digest Ed25519PublicKey MACLength Name PMTU \
- Port PublicKey PublicKeyFile Subnet
+ Address \
+ Cipher \
+ Compression \
+ Digest \
+ Ed25519PublicKey \
+ Ed25519PublicKeyFile \
+ MACLength \
+ PMTU \
+ Port \
+ PublicKey \
+ PublicKeyFile \
+ Subnet
}
check_gen_own_key() {
config_get k "$s" key_size
if [ -z "$k" ]; then
- $BIN -c "$TMP_TINC/$s" --generate-keys </dev/null
+ $BIN -c "$TMP_TINC/$s" generate-keys </dev/null
else
- $BIN -c "$TMP_TINC/$s" "--generate-keys=$k" </dev/null
+ $BIN -c "$TMP_TINC/$s" generate-keys "$k" </dev/null
fi
[ ! -d "/etc/tinc/$s/hosts" ] && mkdir -p "/etc/tinc/$s/hosts"
Device \
DeviceType \
Ed25519PrivateKeyFile \
- ECDSAPublicKey \
Forwarding \
Interface \
ListenAddress \
include $(TOPDIR)/rules.mk
PKG_NAME:=tor
-PKG_VERSION:=0.4.8.4
+PKG_VERSION:=0.4.8.7
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://dist.torproject.org/ \
https://archive.torproject.org/tor-package-archive
-PKG_HASH:=09c1ce74a25fc3b48c81ff146cbd0dd538cbbb8fe4e2964fc2fb2b192f6a1d2b
+PKG_HASH:=b20d2b9c74db28a00c07f090ee5b0241b2b684f3afdecccc6b8008931c557491
PKG_MAINTAINER:=Hauke Mehrtens <hauke@hauke-m.de> \
Peter Wagner <tripolar@gmx.at>
PKG_LICENSE_FILES:=LICENSE
}
reload_service() {
- procd_send_signal /usr/sbin/tor
+ procd_send_signal tor
}
start_service() {
include $(TOPDIR)/rules.mk
PKG_NAME:=transmission
-PKG_VERSION:=4.0.3
-PKG_RELEASE:=5
+PKG_VERSION:=4.0.4
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/transmission/transmission/releases/download/$(PKG_VERSION)/
-PKG_HASH:=b6b01fd58e42bb14f7aba0253db932ced050fcd2bba5d9f8469d77ddd8ad545a
+PKG_HASH:=15f7b4318fdfbffb19aa8d9a6b0fd89348e6ef1e86baa21a0806ffd1893bd5a6
PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
PKG_LICENSE:=GPL-2.0-or-later
#
-# Copyright (c) 2016-2022 Dirk Brenken (dev@brenken.org)
+# Copyright (c) 2016-2023 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=travelmate
-PKG_VERSION:=2.1.0
-PKG_RELEASE:=1
+PKG_VERSION:=2.1.1
+PKG_RELEASE:=3
PKG_LICENSE:=GPL-3.0-or-later
PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
SECTION:=net
CATEGORY:=Network
TITLE:=A wlan connection manager for travel router
- DEPENDS:=+iwinfo +jshn +jsonfilter +curl +ca-bundle
+ DEPENDS:=+iwinfo +jshn +jsonfilter +curl +ca-bundle +rpcd +rpcd-mod-rpcsys
PKGARCH:=all
endef
* status & debug logging to syslog
## Prerequisites
-* [OpenWrt](https://openwrt.org), only compatible with the forthcoming stable 20.x or the latest OpenWrt snapshot
+* [OpenWrt](https://openwrt.org), tested/compatible with current stable 23.x and latest OpenWrt snapshot
* 'dnsmasq' as dns backend
* 'iwinfo' for wlan scanning
* 'curl' for connection checking and all kinds of captive portal magic, e.g. cp detection and auto-logins
* happy traveling ...
## Travelmate config options
-* usually the pre-configured travelmate setup works quite well and no manual config overrides are needed, all listed options apply to the 'global' section:
+* usually the pre-configured travelmate setup works quite well and no manual config overrides are needed, all listed options apply to the 'global' section:
| Option | Default | Description/Valid Values |
| :----------------- | :--------------------------------- | :---------------------------------------------------------------------------------------------------- |
| trm_mailsender | no-reply@travelmate | e-mail sender address for travelmate notifications |
| trm_mailtopic | travelmate connection to '<sta>' | topic for travelmate notification E-Mails |
| trm_mailprofile | trm_notify | profile used by 'msmtp' for travelmate notification E-Mails |
+| trm_stdvpnservice | -, not set | standard vpn service which will be automatically added to new STA profiles |
+| trm_stdvpniface | -, not set | standard vpn interface which will be automatically added to new STA profiles |
-* per uplink exist an additional 'uplink' section in the travelmate config, with the following options:
+
+* per uplink exist an additional 'uplink' section in the travelmate config, with the following options:
| Option | Default | Description/Valid Values |
| :----------------- | :--------------------------------- | :---------------------------------------------------------------------------------------------------- |
| vpn | 0, disabled | automatically handle VPN (re-) connections |
| vpnservice | -, not set | reference the already configured 'wireguard' or 'openvpn' client instance as vpn provider |
| vpniface | -, not set | the logical vpn interface, e.g. 'wg0' or 'tun0' |
-
+
## VPN client setup
Please follow one of the following guides to get a working vpn client setup on your travel router:
* [Wireguard client setup guide](https://openwrt.org/docs/guide-user/services/vpn/wireguard/client)
* [OpenVPN client setup guide](https://openwrt.org/docs/guide-user/services/vpn/openvpn/client)
+**Please note:** Make sure to uncheck the "Bring up on boot" option during vpn interface setup, so that netifd doesn't interfere with travelmate.
Once your vpn client connection is running, you can reference to that setup in travelmate to handle VPN (re-) connections automatically.
## E-Mail setup
**receive travelmate runtime information:**
<pre><code>
-root@2go_ar750s:~# /etc/init.d/travelmate status
+root@2go:~# /etc/init.d/travelmate status
::: travelmate runtime information
- + travelmate_status : connected (net ok/100)
- + travelmate_version : 2.0.0
- + station_id : radio1/WIFIonICE/-
- + station_mac : B2:9D:F5:96:86:A4
- + station_interface : trm_wwan
+ + travelmate_status : connected (net ok/51)
+ + travelmate_version : 2.1.1
+ + station_id : radio0/403 Forbidden/00:0C:46:24:50:00
+ + station_mac : 94:83:C4:24:0E:4F
+ + station_interfaces : trm_wwan, wg0
+ wpa_flags : sae: ✔, owe: ✔, eap: ✔, suiteb192: ✔
+ run_flags : captive: ✔, proactive: ✔, netcheck: ✘, autoadd: ✘, randomize: ✔
- + ext_hooks : ntp: â\9c\94, vpn: â\9c\98, mail: ✘
- + last_run : 2020.09.10-15:21:19
- + system : GL.iNet GL-AR750S (NOR/NAND), OpenWrt SNAPSHOT r14430-2dda301d40
+ + ext_hooks : ntp: â\9c\94, vpn: â\9c\94, mail: ✘
+ + last_run : 2023.10.21-14:29:14
+ + system : GL.iNet GL-A1300, OpenWrt SNAPSHOT r24187-bb8fd41f9a
</code></pre>
To debug travelmate runtime problems, please always enable the 'trm\_debug' flag, restart travelmate and check the system log afterwards (_logread -e "trm-"_)
## Removal
* stop the travelmate daemon with _/etc/init.d/travelmate stop_
-* optional: remove the travelmate package (_opkg remove luci-app-travelmate_, _opkg remove travelmate_)
+* remove the travelmate package (_opkg remove luci-app-travelmate_, _opkg remove travelmate_)
Have fun!
Dirk
--- /dev/null
+#!/bin/sh
+# captive portal auto-login script for H-Reward Hotelss
+# This is free software, licensed under the GNU General Public License v3.
+
+# set (s)hellcheck exceptions
+# shellcheck disable=1091,2039,3040
+#
+#
+# Username and password can be passed to the script, to get fast wifi
+# If not provided, the option with the slower wifi will be selected
+
+
+. "/lib/functions.sh"
+
+
+export LC_ALL=C
+export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
+
+
+# From https://stackoverflow.com/a/17336953/819367 converted to sh
+rawurlencode() {
+ string="$1"
+ strlen=${#string}
+ encoded=""
+ pos=0
+ c=""
+ o=""
+
+ while [ $pos -lt $strlen ]; do
+ c=$(expr substr "$string" $((pos + 1)) 1)
+ case "$c" in
+ [-_.~a-zA-Z0-9] ) o="${c}" ;;
+ * ) o=$(printf '%%%02x' "'$c")
+ esac
+ encoded="${encoded}${o}"
+ pos=$((pos + 1))
+ done
+
+ echo "${encoded}"
+}
+
+user=$(rawurlencode "${1}")
+password=$(rawurlencode "${2}")
+
+successUrl="https://hrewards.com/en"
+trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
+trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
+
+set -e
+
+
+session_key="$(curl -sL --user-agent "${trm_useragent}" \
+ --connect-timeout $((trm_maxwait / 6)) \
+ "http://nossl.com/?cmd=redirect&arubalp=12345" \
+ | awk -F 'name="session_key" value="' 'NF>1{split($2,a,"\""); print a[1]; exit}')"
+
+if [ -n "$user" ] && [ -n "$password" ]; then
+ response="$(curl -sL --user-agent "${trm_useragent}" \
+ --connect-timeout $((trm_maxwait / 6)) \
+ -w %{url_effective} \
+ -o /dev/null \
+ --header "Content-Type:application/x-www-form-urlencoded" \
+ --data "session_key=${session_key}&accept_terms=1&email=${user}&password=${password}&password_reset_form_email=&password_update_form_password=&password_update_form_password_repeat=&room_number=&last_name=&voucher=" \
+ "https://cp.deutschehospitality.com/aruba/login?lang=en")"
+else
+ response="$(curl -sL --user-agent "${trm_useragent}" \
+ --connect-timeout $((trm_maxwait / 6)) \
+ -w %{url_effective} \
+ -o /dev/null \
+ --header "Content-Type:application/x-www-form-urlencoded" \
+ --data "session_key=${session_key}&email=&password=&accept_terms=1&password_reset_form_email=&password_update_form_password=&password_update_form_password_repeat=&room_number=&last_name=&voucher=" \
+ "https://cp.deutschehospitality.com/aruba/skip-registration?lang=en")"
+fi
+
+if [ "$response" != "$successUrl" ]; then
+ exit 255
+fi
#!/bin/sh /etc/rc.common
-# Copyright (c) 2016-2022 Dirk Brenken (dev@brenken.org)
+# Copyright (c) 2016-2023 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.
# set (s)hellcheck exceptions
-# shellcheck disable=2034,2086,2154,3043,3060
+# shellcheck disable=all
START=25
USE_PROCD=1
#!/bin/sh
# travelmate, a wlan connection manager for travel router
-# Copyright (c) 2016-2022 Dirk Brenken (dev@brenken.org)
+# Copyright (c) 2016-2023 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.
# set (s)hellcheck exceptions
-# shellcheck disable=1091,2086,3040,3043,3057,3060
+# shellcheck disable=all
export LC_ALL=C
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
-trm_ver="2.1.0"
trm_enabled="0"
trm_debug="0"
trm_iface=""
trm_ovpninfolist=""
trm_vpnifacelist=""
trm_vpninfolist=""
+trm_stdvpnservice=""
+trm_stdvpniface=""
trm_rtfile="/tmp/trm_runtime.json"
+trm_ubuscmd="$(command -v ubus)"
+trm_jsoncmd="$(command -v jsonfilter)"
trm_wifi="$(command -v wifi)"
trm_fetch="$(command -v curl)"
trm_iwinfo="$(command -v iwinfo)"
trm_logger="$(command -v logger)"
trm_wpa="$(command -v wpa_supplicant)"
trm_captiveurl="http://detectportal.firefox.com"
-trm_useragent="Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0"
+trm_useragent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0"
trm_ntpfile="/var/state/travelmate.ntp"
trm_vpnfile="/var/state/travelmate.vpn"
trm_mailfile="/var/state/travelmate.mail"
return
fi
- unset trm_stalist trm_radiolist trm_uplinklist trm_uplinkcfg trm_activesta trm_opensta
+ unset trm_stalist trm_radiolist trm_uplinklist trm_vpnifacelist trm_uplinkcfg trm_activesta trm_opensta
- trm_sysver="$(ubus -S call system board 2>/dev/null | jsonfilter -q -e '@.model' -e '@.release.description' |
+ trm_sysver="$("${trm_ubuscmd}" -S call system board 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.model' -e '@.release.description' |
awk 'BEGIN{RS="";FS="\n"}{printf "%s, %s",$1,$2}')"
config_cb() {
}
list_cb() {
local option="${1}" value="${2}"
- if [ "${option}" = "trm_vpnifacelist" ]; then
+ if [ "${option}" = "trm_vpnifacelist" ] && ! printf "%s" "${trm_vpnifacelist}" | grep -q "${value}"; then
eval "trm_vpnifacelist=\"$(printf "%s" "${trm_vpnifacelist}") ${value}\""
fi
}
elif [ -z "${trm_iface}" ]; then
f_log "info" "travelmate is currently not configured, please use the 'Interface Setup' in LuCI or the 'setup' option in CLI"
/etc/init.d/travelmate stop
- elif ! ubus -t "${trm_maxwait}" wait_for network.wireless network.interface."${trm_iface}" >/dev/null 2>&1; then
+ elif ! "${trm_ubuscmd}" -t "${trm_maxwait}" wait_for network.wireless network.interface."${trm_iface}" >/dev/null 2>&1; then
f_log "info" "travelmate interface '${trm_iface}' does not appear on ubus, please check your network setup"
/etc/init.d/travelmate stop
fi
break 2
fi
status="$("${trm_wifi}" status 2>/dev/null)"
- if [ "$(printf "%s" "${status}" | jsonfilter -q -l1 -e "@.${radio}.up")" != "true" ] ||
- [ "$(printf "%s" "${status}" | jsonfilter -q -l1 -e "@.${radio}.pending")" != "false" ]; then
+ if [ "$(printf "%s" "${status}" | "${trm_jsoncmd}" -ql1 -e "@.${radio}.up")" != "true" ] ||
+ [ "$(printf "%s" "${status}" | "${trm_jsoncmd}" -ql1 -e "@.${radio}.pending")" != "false" ]; then
if [ "${radio}" != "${radio_up}" ]; then
"${trm_wifi}" up "${radio}"
radio_up="${radio}"
for info in ${trm_vpninfolist}; do
iface="${info%%&&*}"
[ "${iface}" = "${info}" ] && vpn_instance="" || vpn_instance="${info##*&&}"
- vpn_status="$(ifstatus "${iface}" | jsonfilter -q -l1 -e '@.up')"
+ vpn_status="$(ifstatus "${iface}" | "${trm_jsoncmd}" -ql1 -e '@.up')"
if [ "${vpn_status}" = "true" ]; then
- ifdown "${iface}"
+ /sbin/ifdown "${iface}"
+ "${trm_ubuscmd}" -S call network.interface."${iface}" remove >/dev/null 2>&1
if [ -x "/etc/init.d/openvpn" ] && [ -n "${vpn_instance}" ] && /etc/init.d/openvpn running "${vpn_instance}"; then
/etc/init.d/openvpn stop "${vpn_instance}"
fi
f_log "info" "take down vpn interface '${iface}/${vpn_instance:-"-"}' (initial)"
fi
done
- if [ -f "/etc/init.d/sysntpd" ]; then
- /etc/init.d/sysntpd restart >/dev/null 2>&1
- fi
rm -f "${trm_vpnfile}"
elif [ "${vpn}" = "1" ] && [ -n "${vpn_iface}" ] && [ "${vpn_action}" = "enable_keep" ]; then
for info in ${trm_vpninfolist}; do
iface="${info%%&&*}"
[ "${iface}" = "${info}" ] && vpn_instance="" || vpn_instance="${info##*&&}"
- vpn_status="$(ifstatus "${iface}" | jsonfilter -q -l1 -e '@.up')"
+ vpn_status="$(ifstatus "${iface}" | "${trm_jsoncmd}" -ql1 -e '@.up')"
if [ "${vpn_status}" = "true" ] && [ "${iface}" != "${vpn_iface}" ]; then
ifdown "${iface}"
if [ -x "/etc/init.d/openvpn" ] && [ -n "${vpn_instance}" ] && /etc/init.d/openvpn running "${vpn_instance}"; then
fi
if [ -x "${trm_vpnpgm}" ] && [ -n "${vpn_service}" ] && [ -n "${vpn_iface}" ]; then
if { [ "${vpn_action}" = "disable" ] && [ -f "${trm_vpnfile}" ]; } ||
- { [ -f "${trm_ntpfile}" ] && { [ "${vpn}" = "1" ] && [ "${vpn_action%_*}" = "enable" ] && [ ! -f "${trm_vpnfile}" ]; } ||
+ { [ -s "${trm_ntpfile}" ] && { [ "${vpn}" = "1" ] && [ "${vpn_action%_*}" = "enable" ] && [ ! -f "${trm_vpnfile}" ]; } ||
{ [ "${vpn}" != "1" ] && [ "${vpn_action%_*}" = "enable" ] && [ -f "${trm_vpnfile}" ]; }; }; then
result="$(f_net)"
if [ "${result}" = "net ok" ] || [ "${vpn_action}" = "disable" ]; then
[ -n "${rc}" ] && f_jsnup
fi
fi
- f_log "debug" "f_vpn ::: vpn: ${trm_vpn:-"-"}, enabled: ${vpn:-"-"}, action: ${vpn_action}, service: ${vpn_service:-"-"}, iface: ${vpn_iface:-"-"}, instance: ${vpn_instance:-"-"}, infolist: ${trm_vpninfolist:-"-"}, result: ${result}, rc: ${rc:-"-"}"
+ f_log "debug" "f_vpn ::: vpn: ${trm_vpn:-"-"}, enabled: ${vpn:-"-"}, action: ${vpn_action}, vpn_service: ${vpn_service:-"-"}, vpn_iface: ${vpn_iface:-"-"}, vpn_instance: ${vpn_instance:-"-"}, vpn_infolist: ${trm_vpninfolist:-"-"}, result: ${result}, rc: ${rc:-"-"}"
}
# mac helper function
uci_set "wireless" "${section}" "macaddr" "${result}"
else
uci_remove "wireless" "${section}" "macaddr" 2>/dev/null
- ifname="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -q -l1 -e '@.*.interfaces[@.config.mode="sta"].ifname')"
+ ifname="$("${trm_ubuscmd}" -S call network.wireless status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.*.interfaces[@.config.mode="sta"].ifname')"
result="$(${trm_iwinfo} "${ifname}" info 2>/dev/null | awk '/Access Point:/{printf "%s",$3}')"
fi
elif [ "${action}" = "get" ]; then
result="$(uci_get "wireless" "${section}" "macaddr")"
if [ -z "${result}" ]; then
- ifname="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -q -l1 -e '@.*.interfaces[@.config.mode="sta"].ifname')"
+ ifname="$("${trm_ubuscmd}" -S call network.wireless status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.*.interfaces[@.config.mode="sta"].ifname')"
result="$(${trm_iwinfo} "${ifname}" info 2>/dev/null | awk '/Access Point:/{printf "%s",$3}')"
fi
fi
"start")
uci_remove "travelmate" "${trm_uplinkcfg}" "con_start" 2>/dev/null
uci_remove "travelmate" "${trm_uplinkcfg}" "con_end" 2>/dev/null
- if [ -f "${trm_ntpfile}" ]; then
+ if [ -s "${trm_ntpfile}" ]; then
uci_set "travelmate" "${trm_uplinkcfg}" "con_start" "$(date "+%Y.%m.%d-%H:%M:%S")"
fi
;;
"refresh")
- if [ -f "${trm_ntpfile}" ] && [ -z "$(uci_get "travelmate" "${trm_uplinkcfg}" "con_start")" ]; then
+ if [ -s "${trm_ntpfile}" ] && [ -z "$(uci_get "travelmate" "${trm_uplinkcfg}" "con_start")" ]; then
uci_set "travelmate" "${trm_uplinkcfg}" "con_start" "$(date "+%Y.%m.%d-%H:%M:%S")"
fi
;;
"end")
- if [ -f "${trm_ntpfile}" ]; then
+ if [ -s "${trm_ntpfile}" ]; then
uci_set "travelmate" "${trm_uplinkcfg}" "con_end" "$(date "+%Y.%m.%d-%H:%M:%S")"
fi
;;
"start_expiry")
- if [ -f "${trm_ntpfile}" ]; then
+ if [ -s "${trm_ntpfile}" ]; then
expiry="$(uci_get "travelmate" "${trm_uplinkcfg}" "con_start_expiry")"
uci_set "travelmate" "${trm_uplinkcfg}" "enabled" "0"
uci_set "travelmate" "${trm_uplinkcfg}" "con_end" "$(date "+%Y.%m.%d-%H:%M:%S")"
fi
;;
"end_expiry")
- if [ -f "${trm_ntpfile}" ]; then
+ if [ -s "${trm_ntpfile}" ]; then
expiry="$(uci_get "travelmate" "${trm_uplinkcfg}" "con_end_expiry")"
uci_set "travelmate" "${trm_uplinkcfg}" "enabled" "1"
uci_remove "travelmate" "${trm_uplinkcfg}" "con_start" 2>/dev/null
;;
"disabled")
uci_set "travelmate" "${trm_uplinkcfg}" "enabled" "0"
- if [ -f "${trm_ntpfile}" ]; then
+ if [ -s "${trm_ntpfile}" ]; then
uci_set "travelmate" "${trm_uplinkcfg}" "con_end" "$(date "+%Y.%m.%d-%H:%M:%S")"
fi
;;
config_load openvpn
config_foreach uci_config "openvpn"
fi
- f_log "debug" "f_getovpn ::: ovpninfolist: ${trm_ovpninfolist:-"-"}"
+ f_log "debug" "f_getovpn ::: ovpn_infolist: ${trm_ovpninfolist:-"-"}"
}
# get logical vpn network interfaces
proto="$(uci_get "network" "${iface}" "proto")"
device="$(uci_get "network" "${iface}" "device")"
if [ "${proto}" = "wireguard" ]; then
- if { [ -z "${trm_vpnifacelist}" ] || printf "%s" "${trm_vpnifacelist}" | grep -q "${iface}"; }; then
+ if [ -z "${trm_vpnifacelist}" ] || printf "%s" "${trm_vpnifacelist}" | grep -q "${iface}"; then
if ! printf "%s" "${trm_vpninfolist}" | grep -q "${iface}"; then
trm_vpninfolist="$(f_trim "${trm_vpninfolist} ${iface}")"
fi
if [ -z "${trm_ovpninfolist}" ]; then
f_getovpn
fi
- if { [ -z "${trm_vpnifacelist}" ] || printf "%s" "${trm_vpnifacelist}" | grep -q "${iface}"; }; then
+ if [ -z "${trm_vpnifacelist}" ] || printf "%s" "${trm_vpnifacelist}" | grep -q "${iface}"; then
for info in ${trm_ovpninfolist}; do
if [ "${info%%&&*}" = "${device}" ]; then
if ! printf "%s" "${trm_vpninfolist}" | grep -q "${iface}"; then
done
fi
fi
- f_log "debug" "f_getvpn ::: iface: ${iface:-"-"}, proto: ${proto:-"-"}, device: ${device:-"-"}, ifacelist: ${trm_vpnifacelist:-"-"}, infolist: ${trm_vpninfolist:-"-"}"
+ f_log "debug" "f_getvpn ::: iface: ${iface:-"-"}, proto: ${proto:-"-"}, device: ${device:-"-"}, vpn_ifacelist: ${trm_vpnifacelist:-"-"}, vpn_infolist: ${trm_vpninfolist:-"-"}"
}
# get wan gateway addresses
# add open uplinks
#
f_addsta() {
- local uci_cfg new_uplink="1" offset="1" radio="${1}" essid="${2}"
+ local wifi_cfg trm_cfg new_uplink="1" offset="1" radio="${1}" essid="${2}"
if [ "${trm_maxautoadd}" = "0" ] || [ "${trm_opensta:-0}" -lt "${trm_maxautoadd}" ]; then
config_cb() {
fi
if [ "${new_uplink}" = "1" ]; then
- uci_cfg="trm_uplink$((offset + 1))"
- while [ -n "$(uci_get "wireless.${uci_cfg}")" ]; do
+ wifi_cfg="trm_uplink$((offset + 1))"
+ while [ -n "$(uci_get "wireless.${wifi_cfg}")" ]; do
offset="$((offset + 1))"
- uci_cfg="trm_uplink${offset}"
+ wifi_cfg="trm_uplink${offset}"
done
uci -q batch <<-EOC
- set wireless."${uci_cfg}"="wifi-iface"
- set wireless."${uci_cfg}".mode="sta"
- set wireless."${uci_cfg}".network="${trm_iface}"
- set wireless."${uci_cfg}".device="${radio}"
- set wireless."${uci_cfg}".ssid="${essid}"
- set wireless."${uci_cfg}".encryption="none"
- set wireless."${uci_cfg}".disabled="1"
+ set wireless."${wifi_cfg}"="wifi-iface"
+ set wireless."${wifi_cfg}".mode="sta"
+ set wireless."${wifi_cfg}".network="${trm_iface}"
+ set wireless."${wifi_cfg}".device="${radio}"
+ set wireless."${wifi_cfg}".ssid="${essid}"
+ set wireless."${wifi_cfg}".encryption="none"
+ set wireless."${wifi_cfg}".disabled="1"
EOC
- uci_cfg="$(uci -q add travelmate uplink)"
+ trm_cfg="$(uci -q add travelmate uplink)"
uci -q batch <<-EOC
- set travelmate."${uci_cfg}".device="${radio}"
- set travelmate."${uci_cfg}".ssid="${essid}"
- set travelmate."${uci_cfg}".opensta="1"
- set travelmate."${uci_cfg}".con_start_expiry="0"
- set travelmate."${uci_cfg}".con_end_expiry="0"
- set travelmate."${uci_cfg}".enabled="1"
+ set travelmate."${trm_cfg}".device="${radio}"
+ set travelmate."${trm_cfg}".ssid="${essid}"
+ set travelmate."${trm_cfg}".opensta="1"
+ set travelmate."${trm_cfg}".con_start_expiry="0"
+ set travelmate."${trm_cfg}".con_end_expiry="0"
+ set travelmate."${trm_cfg}".enabled="1"
EOC
- if [ -n "$(uci -q changes "travelmate")" ] || [ -n "$(uci -q changes "wireless")" ]; then
- trm_opensta="$((trm_opensta + 1))"
- uci_commit "travelmate"
- uci_commit "wireless"
- f_wifi
- if [ ! -f "${trm_refreshfile}" ]; then
- printf "%s" "ui_reload" >"${trm_refreshfile}"
- fi
- f_log "info" "open uplink '${radio}/${essid}' added to wireless config"
+ if [ -n "${trm_stdvpnservice}" ] && [ -n "${trm_stdvpniface}" ]; then
+ uci -q batch <<-EOC
+ set travelmate."${trm_cfg}".vpnservice="${trm_stdvpnservice}"
+ set travelmate."${trm_cfg}".vpniface="${trm_stdvpniface}"
+ set travelmate."${trm_cfg}".vpn="1"
+ EOC
fi
+ trm_opensta="$((trm_opensta + 1))"
+ uci_commit "travelmate"
+ uci_commit "wireless"
+ f_wifi
+ if [ ! -f "${trm_refreshfile}" ]; then
+ printf "%s" "ui_reload" >"${trm_refreshfile}"
+ fi
+ f_log "info" "open uplink '${radio}/${essid}' added to wireless config"
+ printf "%s" "${wifi_cfg}-${radio}"
fi
f_log "debug" "f_addsta ::: radio: ${radio:-"-"}, essid: ${essid}, opensta/maxautoadd: ${trm_opensta:-"-"}/${trm_maxautoadd:-"-"}, new_uplink: ${new_uplink}, offset: ${offset}"
}
json_raw="${raw#*\{}"
html_raw="${raw%%\{*}"
if [ -n "${json_raw}" ]; then
- json_ec="$(printf "%s" "{${json_raw}" | jsonfilter -q -l1 -e '@.exitcode')"
- json_rc="$(printf "%s" "{${json_raw}" | jsonfilter -q -l1 -e '@.response_code')"
- json_cp="$(printf "%s" "{${json_raw}" | jsonfilter -q -l1 -e '@.redirect_url' | awk 'BEGIN{FS="/"}{printf "%s",tolower($3)}')"
+ json_ec="$(printf "%s" "{${json_raw}" | "${trm_jsoncmd}" -ql1 -e '@.exitcode')"
+ json_rc="$(printf "%s" "{${json_raw}" | "${trm_jsoncmd}" -ql1 -e '@.response_code')"
+ json_cp="$(printf "%s" "{${json_raw}" | "${trm_jsoncmd}" -ql1 -e '@.redirect_url' | awk 'BEGIN{FS="/"}{printf "%s",tolower($3)}')"
if [ "${json_ec}" = "0" ]; then
if [ -n "${json_cp}" ]; then
result="net cp '${json_cp}'"
fi
fi
else
- err_msg="$(printf "%s" "{${json_raw}" | jsonfilter -q -l1 -e '@.errormsg')"
+ err_msg="$(printf "%s" "{${json_raw}" | "${trm_jsoncmd}" -ql1 -e '@.errormsg')"
json_ed="$(printf "%s" "{${err_msg}" | awk '/([[:alnum:]_-]{1,63}\.)+[[:alpha:]]+$/{printf "%s",tolower($NF)}')"
if [ "${json_ec}" = "6" ]; then
if [ -n "${json_ed}" ] && [ "${json_ed}" != "${trm_captiveurl#http*://*}" ]; then
# check interface status
#
f_check() {
- local ifname radio dev_status result login_script login_script_args cp_domain wait_time="1" enabled="1" mode="${1}" status="${2}" sta_radio="${3}" sta_essid="${4}" sta_bssid="${5}"
+ local ifname radio dev_status result login_script login_script_args cp_domain wait_time="0" enabled="1" mode="${1}" status="${2}" sta_radio="${3}" sta_essid="${4}" sta_bssid="${5}"
if [ "${mode}" = "initial" ] || [ "${mode}" = "dev" ]; then
json_get_var station_id "station_id"
f_wifi
fi
while [ "${wait_time}" -le "${trm_maxwait}" ]; do
- dev_status="$(ubus -S call network.wireless status 2>/dev/null)"
+ [ "${wait_time}" -gt "0" ] && sleep 1
+ wait_time="$((wait_time + 1))"
+ dev_status="$("${trm_ubuscmd}" -S call network.wireless status 2>/dev/null)"
if [ -n "${dev_status}" ]; then
if [ "${mode}" = "dev" ]; then
if [ "${trm_ifstatus}" != "${status}" ]; then
trm_ifstatus="${status}"
break
else
- ifname="$(printf "%s" "${dev_status}" | jsonfilter -q -l1 -e '@.*.interfaces[@.config.mode="sta"].ifname')"
+ ifname="$(printf "%s" "${dev_status}" | "${trm_jsoncmd}" -ql1 -e '@.*.interfaces[@.config.mode="sta"].ifname')"
if [ -n "${ifname}" ] && [ "${enabled}" = "1" ]; then
- trm_ifquality="$(${trm_iwinfo} "${ifname}" info 2>/dev/null | awk -F '[ ]' '/Link Quality:/{split($NF,var0,"/");printf "%i\n",(var0[1]*100/var0[2])}')"
- if [ "${trm_ifquality}" -ge "${trm_minquality}" ]; then
- trm_ifstatus="$(ubus -S call network.interface dump 2>/dev/null | jsonfilter -q -l1 -e "@.interface[@.device=\"${ifname}\"].up")"
+ trm_ifquality="$(${trm_iwinfo} "${ifname}" info 2>/dev/null | awk -F '[ ]' '/Link Quality: [0-9]+\/[0-9]+/{split($NF,var0,"/");printf "%i\n",(var0[1]*100/var0[2])}')"
+ if [ -z "${trm_ifquality}" ]; then
+ continue
+ elif [ "${trm_ifquality}" -ge "${trm_minquality}" ]; then
+ trm_ifstatus="$("${trm_ubuscmd}" -S call network.interface dump 2>/dev/null | "${trm_jsoncmd}" -ql1 -e "@.interface[@.device=\"${ifname}\"].up")"
if [ "${trm_ifstatus}" = "true" ]; then
result="$(f_net)"
if [ "${trm_captive}" = "1" ]; then
f_jsnup
break
fi
- wait_time="$((wait_time + 1))"
- sleep 1
done
f_log "debug" "f_check ::: mode: ${mode}, name: ${ifname:-"-"}, status: ${trm_ifstatus}, enabled: ${enabled}, connection: ${trm_connection:-"-"}, wait: ${wait_time}, max_wait: ${trm_maxwait}, min_quality: ${trm_minquality}, captive: ${trm_captive}, netcheck: ${trm_netcheck}"
}
# update runtime information
#
f_jsnup() {
- local vpn vpn_iface section last_date last_station sta_iface sta_radio sta_essid sta_bssid sta_mac dev_status last_status status="${trm_ifstatus}" ntp_done="0" vpn_done="0" mail_done="0"
+ local vpn vpn_iface section last_date sta_iface sta_radio sta_essid sta_bssid sta_mac dev_status status="${trm_ifstatus}" ntp_done="0" vpn_done="0" mail_done="0"
if [ "${status}" = "true" ]; then
status="connected (${trm_connection:-"-"})"
- dev_status="$(ubus -S call network.wireless status 2>/dev/null)"
- section="$(printf "%s" "${dev_status}" | jsonfilter -q -l1 -e '@.*.interfaces[@.config.mode="sta"].section')"
+ dev_status="$("${trm_ubuscmd}" -S call network.wireless status 2>/dev/null)"
+ section="$(printf "%s" "${dev_status}" | "${trm_jsoncmd}" -ql1 -e '@.*.interfaces[@.config.mode="sta"].section')"
if [ -n "${section}" ]; then
sta_iface="$(uci_get "wireless" "${section}" "network")"
sta_radio="$(uci_get "wireless" "${section}" "device")"
f_getcfg "${sta_radio}" "${sta_essid}" "${sta_bssid}"
fi
json_get_var last_date "last_run"
- json_get_var last_station "station_id"
- json_get_var last_status "travelmate_status"
-
- if { [ -f "${trm_ntpfile}" ] && [ ! -s "${trm_ntpfile}" ]; } || [ "${last_status}" = "running (not connected)" ] ||
- { [ -n "${last_station}" ] && [ "${last_station}" != "${sta_radio:-"-"}/${sta_essid:-"-"}/${sta_bssid:-"-"}" ]; }; then
- last_date="$(date "+%Y.%m.%d-%H:%M:%S")"
- if [ -f "${trm_ntpfile}" ] && [ ! -s "${trm_ntpfile}" ]; then
- printf "%s" "${last_date}" >"${trm_ntpfile}"
- fi
- fi
+
vpn="$(f_getval "vpn")"
if [ "${trm_vpn}" = "1" ] && [ -n "${trm_vpninfolist}" ] && [ "${vpn}" = "1" ] && [ -f "${trm_vpnfile}" ]; then
vpn_iface="$(f_getval "vpniface")"
# main function for connection handling
#
f_main() {
- local radio cnt retrycnt scan_dev scan_list scan_essid scan_bssid scan_open scan_quality
- local station_id section sta sta_essid sta_bssid sta_radio sta_mac config_essid config_bssid config_radio
+ local radio cnt retrycnt scan_dev scan_list scan_essid scan_bssid scan_open scan_quality station_id section
+ local sta sta_essid sta_bssid sta_radio sta_mac open_sta open_essid config_radio config_essid config_bssid
f_check "initial" "false"
f_log "debug" "f_main-1 ::: status: ${trm_ifstatus}, proactive: ${trm_proactive}"
f_log "debug" "f_main-5 ::: sta_radio: ${sta_radio}, sta_essid: \"${sta_essid}\", sta_bssid: ${sta_bssid:-"-"}"
fi
if [ -z "${scan_list}" ]; then
- scan_dev="$(ubus -S call network.wireless status 2>/dev/null | jsonfilter -q -l1 -e "@.${radio}.interfaces[0].ifname")"
+ scan_dev="$("${trm_ubuscmd}" -S call network.wireless status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e "@.${radio}.interfaces[0].ifname")"
scan_list="$("${trm_iwinfo}" "${scan_dev:-${radio}}" scan 2>/dev/null |
awk 'BEGIN{FS="[[:space:]]"}/Address:/{var1=$NF}/ESSID:/{var2="";for(i=12;i<=NF;i++)if(var2==""){var2=$i}else{var2=var2" "$i}}
/Quality:/{split($NF,var0,"/")}/Encryption:/{if($NF=="none"){var3="+"}else{var3="-"};
if [ -n "${scan_quality}" ] && [ -n "${scan_open}" ] && [ -n "${scan_bssid}" ] && [ -n "${scan_essid}" ]; then
f_log "debug" "f_main-7 ::: radio(sta/scan): ${sta_radio}/${radio}, essid(sta/scan): \"${sta_essid}\"/${scan_essid}, bssid(sta/scan): ${sta_bssid}/${scan_bssid}, quality(min/scan): ${trm_minquality}/${scan_quality}, open: ${scan_open}"
if [ "${scan_quality}" -ge "${trm_minquality}" ]; then
+ if [ "${trm_autoadd}" = "1" ] && [ "${scan_open}" = "+" ] && [ "${scan_essid}" != "unknown" ]; then
+ open_essid="${scan_essid%?}"
+ open_essid="${open_essid:1}"
+ open_sta="$(f_addsta "${radio}" "${open_essid}")"
+ if [ -n "${open_sta}" ]; then
+ section="${open_sta%%-*}"
+ sta_radio="$(uci_get "wireless" "${section}" "device")"
+ sta_essid="$(uci_get "wireless" "${section}" "ssid")"
+ sta_bssid=""
+ sta_mac=""
+ fi
+ fi
if { { [ "${scan_essid}" = "\"${sta_essid}\"" ] && { [ -z "${sta_bssid}" ] || [ "${scan_bssid}" = "${sta_bssid}" ]; }; } ||
{ [ "${scan_bssid}" = "${sta_bssid}" ] && [ "${scan_essid}" = "unknown" ]; }; } && [ "${radio}" = "${sta_radio}" ]; then
if [ -n "${config_radio}" ]; then
retrycnt="$((retrycnt + 1))"
sleep "$((trm_maxwait / 6))"
done
- elif [ "${trm_autoadd}" = "1" ] && [ "${scan_open}" = "+" ] && [ "${scan_essid}" != "unknown" ]; then
- scan_essid="${scan_essid%?}"
- scan_essid="${scan_essid:1}"
- f_addsta "${radio}" "${scan_essid}"
fi
fi
fi
fi
}
+# get travelmate version
+#
+trm_ver="$("${trm_ubuscmd}" -S call rpc-sys packagelist '{ "all": true }' 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.packages.travelmate')"
+
# source required system libraries
#
if [ -r "/lib/functions.sh" ] && [ -r "/lib/functions/network.sh" ] && [ -r "/usr/share/libubox/jshn.sh" ]; then
f_log "err" "system libraries not found"
fi
+# force ntp restart/sync
+#
+if [ -f "/etc/init.d/sysntpd" ] && [ ! -s "${trm_ntpfile}" ]; then
+ /etc/init.d/sysntpd restart >/dev/null 2>&1
+ f_log "debug" "ntp time sync requested"
+fi
+
# control travelmate actions
#
while true; do
#!/bin/sh
# vpn handler called by travelmate
-# Copyright (c) 2020-2022 Dirk Brenken (dev@brenken.org)
+# Copyright (c) 2020-2023 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.
# set (s)hellcheck exceptions
-# shellcheck disable=1091,3040,3043
+# shellcheck disable=all
# Please note: you have to setup the package 'wireguard' or 'openvpn' before using this script
vpn_instance="${5}"
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")"
-trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
+trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/118.0")"
+trm_ubuscmd="$(command -v ubus)"
+trm_jsoncmd="$(command -v jsonfilter)"
trm_logger="$(command -v logger)"
trm_fetch="$(command -v curl)"
trm_vpnfile="/var/state/travelmate.vpn"
f_net() {
- local json_rc result="net nok"
+ local json_rc
json_rc="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --header "Cache-Control: no-cache, no-store, must-revalidate, max-age=0" --write-out "%{response_code}" --silent --output /dev/null --max-time $((trm_maxwait / 6)) "${trm_captiveurl}")"
if [ "${json_rc}" = "200" ] || [ "${json_rc}" = "204" ]; then
- result="net ok"
+ json_rc="net ok"
fi
- printf "%s" "${result}"
+ printf "%s" "${json_rc}"
}
if [ "${vpn}" = "1" ] && [ "${vpn_action%_*}" = "enable" ]; then
if [ "${vpn_action}" = "enable_keep" ]; then
- vpn_status="$(ubus -S call network.interface."${vpn_iface}" status 2>/dev/null | jsonfilter -q -l1 -e '@.up')"
+ vpn_status="$("${trm_ubuscmd}" -S call network.interface."${vpn_iface}" status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.up')"
fi
if [ "${vpn_action}" = "enable" ] || [ "${vpn_status}" != "true" ]; then
+ if [ "${vpn_status}" != "true" ]; then
+ /sbin/ifdown "${vpn_iface}"
+ "${trm_ubuscmd}" -S call network.interface."${vpn_iface}" remove >/dev/null 2>&1
+ if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && /etc/init.d/openvpn running "${vpn_instance}"; then
+ /etc/init.d/openvpn stop "${vpn_instance}"
+ fi
+ sleep 1
+ fi
if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && ! /etc/init.d/openvpn running "${vpn_instance}"; then
/etc/init.d/openvpn start "${vpn_instance}"
fi
- ifup "${vpn_iface}"
+ /sbin/ifup "${vpn_iface}"
cnt=0
while true; do
- vpn_status="$(ubus -S call network.interface."${vpn_iface}" status 2>/dev/null | jsonfilter -q -l1 -e '@.up')"
+ vpn_status="$("${trm_ubuscmd}" -S call network.interface."${vpn_iface}" status 2>/dev/null | "${trm_jsoncmd}" -ql1 -e '@.up')"
if [ "${vpn_status}" = "true" ]; then
net_status="$(f_net)"
if [ "${net_status}" = "net ok" ]; then
fi
fi
if [ "${cnt}" -ge "$((trm_maxwait / 3))" ]; then
- ifdown "${vpn_iface}"
+ /sbin/ifdown "${vpn_iface}"
+ "${trm_ubuscmd}" -S call network.interface."${vpn_iface}" remove >/dev/null 2>&1
if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && /etc/init.d/openvpn running "${vpn_instance}"; then
/etc/init.d/openvpn stop "${vpn_instance}"
fi
rm -f "${trm_vpnfile}"
- "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${vpn_service} client connection can't be established '${vpn_iface}/${vpn_instance:-"-"}'" 2>/dev/null
+ "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${vpn_service} client connection can't be established '${vpn_iface}/${vpn_instance:-"-", rc: ${net_status:-"-"}}'" 2>/dev/null
return 1
fi
sleep 1
done
fi
elif { [ "${vpn}" != "1" ] && [ "${vpn_action%_*}" = "enable" ]; } || [ "${vpn_action}" = "disable" ]; then
- ifdown "${vpn_iface}"
+ /sbin/ifdown "${vpn_iface}"
+ "${trm_ubuscmd}" -S call network.interface."${vpn_iface}" remove >/dev/null 2>&1
if [ "${vpn_service}" = "openvpn" ] && [ -n "${vpn_instance}" ] && [ -x "/etc/init.d/openvpn" ] && /etc/init.d/openvpn running "${vpn_instance}"; then
/etc/init.d/openvpn stop "${vpn_instance}"
fi
#!/bin/sh
# ntp hotplug script for travelmate
-# Copyright (c) 2020-2022 Dirk Brenken (dev@brenken.org)
+# Copyright (c) 2020-2023 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.
# set (s)hellcheck exceptions
-# shellcheck disable=3023
+# shellcheck disable=all
trm_init="/etc/init.d/travelmate"
trm_ntpfile="/var/state/travelmate.ntp"
trm_logger="$(command -v logger)"
-if [ "${ACTION}" = "stratum" ] && [ ! -f "${trm_ntpfile}" ] && "${trm_init}" enabled; then
- {
- if flock -xn 1001; then
- "${trm_logger}" -p "info" -t "trm-ntp [${$}]" "get ntp time sync" 2>/dev/null
- "${trm_init}" restart
- fi
- } 1001>"${trm_ntpfile}"
+if [ "${ACTION}" = "stratum" ] && [ ! -s "${trm_ntpfile}" ] && "${trm_init}" enabled; then
+ printf "%s" "$(date "+%Y.%m.%d-%H:%M:%S")" > "${trm_ntpfile}"
+ "${trm_logger}" -p "info" -t "trm-ntp [${$}]" "get ntp time sync"
fi
include $(TOPDIR)/rules.mk
PKG_NAME:=udp-broadcast-relay-redux
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_LICENSE:=GPL-2.0
PKG_SOURCE_PROTO:=git
'port:port' \
'network:list(string)' \
'src_override:ip4addr' \
- 'dest_override:ip4addr'
+ 'dest_override:ip4addr' \
+ 'multicast:ip4addr'
[ -z "$id" ] && return 1
}
udp_broadcast_relay_redux_instance() {
- local net network ifname id port src_override dest_override
+ local net network ifname id port src_override dest_override multicast
validate_section_udp_broadcast_relay_redux "${1}" || {
echo "Validation failed"
procd_append_param command "-t" "$dest_override"
fi
+ if [ -n "$multicast" ] ; then
+ procd_append_param command "--multicast" "$multicast"
+ fi
+
procd_add_jail ubr-${PIDCOUNT} cgroupsns
procd_close_instance
}
# list network lan
# list network vpnsrv
# option dest_override 10.66.2.13
+# option multicast 239.255.255.250
include $(TOPDIR)/rules.mk
PKG_NAME:=unbound
-PKG_VERSION:=1.18.0
-PKG_RELEASE:=1
+PKG_VERSION:=1.19.0
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://nlnetlabs.nl/downloads/unbound
-PKG_HASH:=3da95490a85cff6420f26fae0b84a49f5112df1bf1b7fc34f8724f02082cb712
+PKG_HASH:=a97532468854c61c2de48ca4170de854fd3bc95c8043bb0cfb0fe26605966624
PKG_MAINTAINER:=Eric Luehrsen <ericluehrsen@gmail.com>
PKG_LICENSE:=BSD-3-Clause
##############################################################################
-create_host_record() {
+create_host_record_from_domain() {
local cfg="$1"
local ip name debug_ip
##############################################################################
+create_host_record_from_host() {
+ local cfg="$1"
+ local dns ip name
+
+ # basefiles dhcp "host" clause which means host A and PTR records
+ config_get dns "$cfg" dns 0
+ config_get ip "$cfg" ip
+ config_get name "$cfg" name
+
+
+ if [ -n "$name" ] && [ -n "$ip" ] && [ $dns -eq 1 ] ; then
+ case $name in
+ *.*)
+ # domain present, do nothing
+ ;;
+ *)
+ name="$name.$UB_TXT_DOMAIN"
+ ;;
+ esac
+
+
+ create_local_zone "$name"
+ DM_LIST_LOCAL_DATA="$DM_LIST_LOCAL_DATA $name.@@300@@IN@@A@@$ip"
+ DM_LIST_LOCAL_PTR="$DM_LIST_LOCAL_PTR $ip@@300@@$name"
+ fi
+}
+
+##############################################################################
+
create_mx_record() {
local cfg="$1"
local domain relay pref record
# Parasite from the uci.dhcp.domain clauses
DM_LIST_KNOWN_ZONES="$DM_LIST_KNOWN_ZONES $UB_TXT_DOMAIN"
config_load dhcp
- config_foreach create_host_record domain
+ config_foreach create_host_record_from_domain domain
+ config_foreach create_host_record_from_host host
if [ $UB_D_EXTRA_DNS -gt 1 ] ; then
target. Use "uname" on host only if "UNAME" variable is empty.
--- a/configure.ac
+++ b/configure.ac
-@@ -840,7 +840,7 @@ if test x_$ub_test_python != x_no; then
+@@ -842,7 +842,7 @@ if test x_$ub_test_python != x_no; then
fi
fi
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=uspot
+PKG_RELEASE:=1
+
+PKG_LICENSE:=GPL-2.0
+PKG_MAINTAINER:=Thibaut VARÈNE <hacks@slashdirt.org>
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/f00b4r0/uspot.git
+PKG_SOURCE_DATE:=2023-11-30
+PKG_SOURCE_VERSION:=7e1e21b0f8425205d719b99a392fa893b3e512e6
+PKG_MIRROR_HASH:=494c616159b16d978fe00348ebe50c77a48f1db98d624ed613f3cca2d39e3a6e
+
+CMAKE_SOURCE_SUBDIR:=src
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/uspot
+ SUBMENU:=Captive Portals
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=uspot hotspot daemon
+ DEPENDS:=+conntrack \
+ +libblobmsg-json +liblucihttp-ucode +libradcli +libubox +libubus +libuci \
+ +spotfilter \
+ +ucode +ucode-mod-math +ucode-mod-nl80211 +ucode-mod-rtnl +uhttpd-mod-ucode +ucode-mod-uloop
+
+endef
+
+define Package/uspot/description
+ This package implements a captive portal supporting click-to-continue,
+ simple credential-based as well as RADIUS authentication.
+ It is UAM capable, and has limited support for RFC5176
+ RADIUS Dynamic Authorization Extensions.
+ It is meant to be a drop-in replacement for CoovaChilli,
+ leveraging the performance and flexibility of the nftables firewall
+ without the need for extra kernel modules.
+endef
+
+define Package/uspot/conffiles
+/etc/config/uspot
+endef
+
+define Package/uspot-www
+ SUBMENU:=Captive Portals
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=uspot default user interface files
+ DEPENDS:=+uspot
+endef
+
+define Package/uspot-www/description
+ This package provides CSS and HTML templates for uspot UI.
+ This package must be installed with uspot unless a local alternative is provided.
+endef
+
+define Package/uspotfilter
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=uspot implementation of spotfilter
+ PROVIDES:=spotfilter
+ CONFLICTS:=spotfilter
+ DEPENDS:=+conntrack +nftables-json +ucode +ucode-mod-rtnl +ucode-mod-uloop
+endef
+
+define Package/uspotfilter/description
+ This package provides the nftables firewall interface to spotfilter.
+ It is compatible with firewall4.
+endef
+
+define Package/uspot/install
+ $(INSTALL_DIR) $(1)/usr/bin $(1)/usr/share $(1)/usr/lib/ucode $(1)/etc/init.d $(1)/etc/config
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/radius-client $(1)/usr/bin/radius-client
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/uspot-das $(1)/usr/bin/uspot-das
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/libuam.so $(1)/usr/lib/ucode/uam.so
+ $(INSTALL_CONF) $(PKG_BUILD_DIR)/files/etc/config/uspot $(1)/etc/config/uspot
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/etc/init.d/uspot $(1)/etc/init.d/uspot
+ $(CP) $(PKG_BUILD_DIR)/files/usr/bin $(1)/usr/
+ $(CP) $(PKG_BUILD_DIR)/files/usr/share/uspot $(1)/usr/share/
+endef
+
+define Package/uspot-www/install
+ $(CP) $(PKG_BUILD_DIR)/files/www-uspot $(1)/
+endef
+
+define Package/uspotfilter/install
+ $(INSTALL_DIR) $(1)/usr/share $(1)/etc/init.d
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/files/etc/init.d/spotfilter $(1)/etc/init.d/spotfilter
+ $(CP) $(PKG_BUILD_DIR)/files/usr/share/uspotfilter $(1)/usr/share/
+endef
+
+$(eval $(call BuildPackage,uspot))
+$(eval $(call BuildPackage,uspot-www))
+$(eval $(call BuildPackage,uspotfilter))
include $(TOPDIR)/rules.mk
PKG_NAME:=v2ray-core
-PKG_VERSION:=5.8.0
+PKG_VERSION:=5.13.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/v2fly/v2ray-core/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=340798554d2c7f0e5fb719f9d9dd6a667dfe93ccdd3b1d653c3a3bdb04ed2d00
+PKG_HASH:=6b2eb6286c99da010db5c5f629f950e753fc4addeed189d3d898c1ef56d5a785
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
-GEOIP_VER:=202308310037
+GEOIP_VER:=202312071808
GEOIP_FILE:=geoip.dat.$(GEOIP_VER)
define Download/geoip
URL:=https://github.com/v2fly/geoip/releases/download/$(GEOIP_VER)/
URL_FILE:=geoip.dat
FILE:=$(GEOIP_FILE)
- HASH:=536d7aa9f54af747153d4f982adaa3181025dd72faaba8f532b3f514b467eff8
+ HASH:=1c8d8bd5e8966a115d2ba16739660ef8ea1ebbb812fec4f87c699df479721652
endef
-GEOSITE_VER:=20230905081311
+GEOSITE_VER:=20231212122459
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
define Download/geosite
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
URL_FILE:=dlc.dat
FILE:=$(GEOSITE_FILE)
- HASH:=d393deda756a446ec5247730ef09fed80ba9fb8d9204d1263c45a3604435fe57
+ HASH:=954adf9b4e999839073715566ab5df3f2177ad97741ce78dcea9b0795ef30614
endef
-GEOSITE_IRAN_VER:=202309250024
+GEOSITE_IRAN_VER:=202312110026
GEOSITE_IRAN_FILE:=iran.dat.$(GEOSITE_IRAN_VER)
define Download/geosite-ir
URL:=https://github.com/bootmortis/iran-hosted-domains/releases/download/$(GEOSITE_IRAN_VER)/
URL_FILE:=iran.dat
FILE:=$(GEOSITE_IRAN_FILE)
- HASH:=1eccf6e1514ceb338a91da0c938d62a0e0c1e1aee12f8d479fafcdadace5625a
+ HASH:=0f5a1c31c0b905d6619d5b917a1031defb17f5a556e604327d9bc49ee3de962f
endef
define Package/v2ray-geodata/template
include $(TOPDIR)/rules.mk
PKG_NAME:=v2rayA
-PKG_VERSION:=2.2.4
+PKG_VERSION:=2.2.4.3
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=844da2a4c1ac1f7eae02519a0833255a63938f08a554cbea043606b28ee6ebed
+PKG_HASH:=8ebb1790ac57b795a03a13f830d316206040627486bd204158b04917a8c817b7
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/service
PKG_LICENSE:=AGPL-3.0-only
/etc/config/v2raya
endef
-WEB_FILE:=$(PKG_NAME)-web-$(PKG_VERSION).zip
+WEB_FILE:=$(PKG_NAME)-web-$(PKG_VERSION).tar.gz
define Download/v2raya-web
URL:=https://github.com/v2rayA/v2rayA/releases/download/v$(PKG_VERSION)/
- URL_FILE:=web.zip
+ URL_FILE:=web.tar.gz
FILE:=$(WEB_FILE)
- HASH:=2699dacdf39137af408a9ffcb91734e5af487bef4dccaa51f1bb3de6c4d3e8fe
+ HASH:=187b498b8b5fdac765309c9ae23efb1ccd74e01d713682c44b4aa7689c99017c
endef
define Build/Prepare
( \
mkdir -p $(PKG_BUILD_DIR)/server/router/web ; \
- unzip -q -d $(PKG_BUILD_DIR)/server/router/web $(DL_DIR)/$(WEB_FILE) ; \
+ gzip -dc $(DL_DIR)/$(WEB_FILE) | $(HOST_TAR) -C $(PKG_BUILD_DIR)/server/router/web $(TAR_OPTIONS) ; \
)
endef
include $(TOPDIR)/rules.mk
PKG_NAME:=wavemon
-PKG_VERSION:=0.9.3
+PKG_VERSION:=0.9.5
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/uoaerg/wavemon/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=ddbeb6ec8ed7d94fa895e5d57ecfe338495df3991f6facc7cf40aa121bf7ff60
+PKG_HASH:=f84c55a40b470f2b98908d20cd0b38ffef6f587daed23b50281c9592df3331c6
PKG_MAINTAINER:=Jonathan McCrohan <jmccrohan@gmail.com>
PKG_LICENSE:=GPL-2.0-or-later
SECTION:=net
CATEGORY:=Network
TITLE:=N-curses based wireless network devices monitor
- DEPENDS:=+libncurses +libpthread +libnl-genl
+ DEPENDS:=+libncurses +libpthread +libnl-genl +libnl-cli
SUBMENU:=Wireless
URL:=https://github.com/uoaerg/wavemon/releases
endef
include $(TOPDIR)/rules.mk
PKG_NAME:=wifischedule
-PKG_VERSION:=1
-PKG_RELEASE:=3
+PKG_VERSION:=1.0.5
+PKG_RELEASE:=1
PKG_LICENSE:=PRPL
PKG_MAINTAINER:=Nils Koenig <openwrt@newk.it>
$(INSTALL_BIN) ./net/usr/bin/wifi_schedule.sh $(1)/usr/bin/wifi_schedule.sh
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./net/etc/config/wifi_schedule $(1)/etc/config/wifi_schedule
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_DATA) ./net/etc/init.d/wifi_schedule $(1)/etc/init.d/wifi_schedule
+endef
+
+define Package/wifischedule/postinst
+#!/bin/sh
+# check if we are on real system
+if [ -z "$${IPKG_INSTROOT}" ]; then
+ echo "Enabling rc.d symlink for wifischedule"
+ /etc/init.d/wifi_schedule enable
+fi
+exit 0
endef
$(eval $(call BuildPackage,wifischedule))
All commands:
```
-wifi_schedule.sh cron|start|stop|forcestop|recheck|getmodules|savemodules|help
+wifi_schedule.sh cron|start|startup|stop|forcestop|recheck|getmodules|savemodules|help
cron: Create cronjob entries.
start: Start wifi.
+ startup: Checks current timewindow and enables/disables WIFI accordingly.
stop: Stop wifi gracefully, i.e. check if there are stations associated and if so keep retrying.
forcestop: Stop wifi immediately.
recheck: Recheck if wifi can be disabled now.
savemodules: Saves a list of automatic determined modules to UCI
help: This description.
```
+
+## Startup Script: `/etc/init.d/wifi_schedule`
+Makes sure time window is checked and WIFI is enabled or disabled accordingly when powering on the router.
--- /dev/null
+#!/bin/sh /etc/rc.common
+# Startup Script for wifi_schedule
+
+START=100
+
+start() {
+ /usr/bin/wifi_schedule.sh startup
+}
#
# Author: Nils Koenig <openwrt@newk.it>
+set -o pipefail
+
SCRIPT=$0
LOCKFILE=/tmp/wifi_schedule.lock
LOGFILE=/tmp/log/wifi_schedule.log
return 0
}
+_is_earlier()
+{
+ local hhmm=$1
+ local ret=1
+ if [[ $(date +%H) -lt ${hhmm:0:2} ]]
+ then
+ ret=0
+ fi
+ if [[ $(date +%H) -eq ${hhmm:0:2} && $(date +%M) -lt ${hhmm:3:4} ]]
+ then
+ ret=0
+ fi
+ echo $ret
+}
+
+# returns 0 if now() is in $entry
+_check_startup_timewindow()
+{
+ local entry=$1
+ local starttime
+ local stoptime
+ local dow
+ starttime=$(_get_uci_value ${PACKAGE}.${entry}.starttime) || _exit 1
+ stoptime=$(_get_uci_value ${PACKAGE}.${entry}.stoptime) || _exit 1
+ dow=$(_get_uci_value_raw ${PACKAGE}.${entry}.daysofweek) || _exit 1
+
+ echo $dow | grep $(date +%A) > /dev/null 2>&1
+ rc=$?
+
+ if [[ $rc -eq 0 && $(date +%H) -ge ${starttime:0:2} && $(date +%M) -ge ${starttime:3:4} && $(_is_earlier $stoptime) -eq 0 ]]
+ then
+ echo 0
+ else
+ echo 1
+ fi
+}
+
_get_wireless_interfaces()
{
- local n=$(cat /proc/net/wireless | wc -l)
- cat /proc/net/wireless | tail -n $(($n - 2))|awk -F':' '{print $1}'| sed 's/ //'
+ iwinfo | grep ESSID | cut -f 1 -s -d" "
}
done
}
+_should_wifi_enabled()
+{
+
+ local enable_wifi=0
+ local entries=$(uci show ${PACKAGE} 2> /dev/null | awk -F'.' '{print $2}' | grep -v '=' | grep -v '@global\[0\]' | uniq | sort)
+ local _entry
+ for _entry in ${entries}
+ do
+ local status
+ status=$(_get_uci_value ${PACKAGE}.${_entry}.enabled) || _exit 1
+ if [ ${status} -eq 1 ]
+ then
+ enable_wifi=$(_check_startup_timewindow $_entry)
+ fi
+ done
+ echo ${enable_wifi}
+}
+
+startup()
+{
+ _log "startup"
+ local _enable_wifi=$(_should_wifi_enabled)
+ if [[ ${_enable_wifi} -eq 0 ]]
+ then
+ _log "enable wifi"
+ enable_wifi
+ else
+ _log "disable wifi"
+ disable_wifi
+ fi
+}
+
check_cron_status()
{
local global_enabled
disable_wifi()
{
_rm_cron_script "${SCRIPT} recheck"
- /sbin/wifi down
+ _set_status_wifi_uci 1
local unload_modules
unload_modules=$(_get_uci_value_raw ${GLOBAL}.unload_modules) || _exit 1
if [[ "${unload_modules}" == "1" ]]; then
soft_disable_wifi()
{
- local _disable_wifi=1
+ local _disable_wifi=0 #0: disable wifi, 1: do not disable wifi
local iwinfo=/usr/bin/iwinfo
if [ ! -e ${iwinfo} ]; then
_log "${iwinfo} not available, skipping"
fi
if [ -n "${stations}" ]; then
- _disable_wifi=0
+ _disable_wifi=1
_log "Station(s) $(echo ${stations}) associated on ${_if}"
fi
done
- if [ ${_disable_wifi} -eq 1 ]; then
+ local _wifi_enabled=$(_should_wifi_enabled)
+ if [[ ${_disable_wifi} -eq 0 && ${_wifi_enabled} -eq 1 ]]; then
_log "No stations associated, disable wifi."
disable_wifi
+ elif [[ ${_disable_wifi} -eq 0 && ${_wifi_enabled} -eq 0 ]]; then
+ _log "Do not disable wifi since there is an allow timeframe, skip rechecking."
+ _rm_cron_script "${SCRIPT} recheck"
else
_log "Could not disable wifi due to associated stations, retrying..."
local recheck_interval=$(_get_uci_value ${GLOBAL}.recheck_interval)
fi
}
+_set_status_wifi_uci()
+{
+ local status=$1
+ local radios=$(uci show wireless | grep radio | awk -F'.' '{print $2}' | grep -v '[=|@]' | sort | uniq)
+ for radio in ${radios}
+ do
+ uci set wireless.${radio}.disabled=${status}
+ done
+ uci commit
+}
+
enable_wifi()
{
_rm_cron_script "${SCRIPT} recheck"
if [[ "${unload_modules}" == "1" ]]; then
_load_modules
fi
+ _set_status_wifi_uci 0
/sbin/wifi
}
usage()
{
echo ""
- echo "$0 cron|start|stop|forcestop|recheck|getmodules|savemodules|help"
+ echo "$0 cron|start|startup|stop|forcestop|recheck|getmodules|savemodules|help"
echo ""
echo " UCI Config File: /etc/config/${PACKAGE}"
echo ""
echo " cron: Create cronjob entries."
echo " start: Start wifi."
+ echo " startup: Checks current timewindow and enables/disables WIFI accordingly."
echo " stop: Stop wifi gracefully, i.e. check if there are stations associated and if so keep retrying."
echo " forcestop: Stop wifi immediately."
echo " recheck: Recheck if wifi can be disabled now."
echo ""
}
+_cleanup()
+{
+ lock -u ${LOCKFILE}
+ rm ${LOCKFILE}
+}
+
###############################################################################
# MAIN
###############################################################################
+trap _cleanup EXIT
+
LOGGING=$(_get_uci_value ${GLOBAL}.logging) || _exit 1
_log ${SCRIPT} $1 $2
lock ${LOCKFILE}
case "$1" in
- cron) check_cron_status ;;
+ cron)
+ check_cron_status
+ startup
+ ;;
start) enable_wifi ;;
+ startup) startup ;;
forcestop) disable_wifi ;;
stop) soft_disable_wifi ;;
recheck) soft_disable_wifi ;;
include $(TOPDIR)/rules.mk
PKG_NAME:=xray-core
-PKG_VERSION:=1.8.4
+PKG_VERSION:=1.8.6
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/XTLS/Xray-core/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=89f73107abba9bd438111edfe921603ddb3c2b631b2716fbdc6be78552f0d322
+PKG_HASH:=d828296c9f29f9e59a61ab73d44f072ab2a30fe979679e39aea43b33ddb7d6bf
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
PKG_LICENSE:=MPL-2.0
include $(TOPDIR)/rules.mk
PKG_NAME:=yggdrasil
-PKG_VERSION:=0.4.7
+PKG_VERSION:=0.5.4
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/yggdrasil-network/yggdrasil-go/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=47429f75b87d9b2450108471991e84c90d748606642e8778e9f578485b05a56f
+PKG_HASH:=c1cceb9a7a4a8959536b1d930ca081bcfbc76ab655e4bcb55d5d0ab6520d9241
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-go-$(PKG_VERSION)
PKG_MAINTAINER:=William Fleurant <meshnet@protonmail.com>
SUBMENU:=Routing and Redirection
TITLE:=Yggdrasil supports end-to-end encrypted IPv6 networks
URL:=https://yggdrasil-network.github.io/
- DEPENDS:=$(GO_ARCH_DEPENDS) @IPV6 +kmod-tun +dkjson +libuci-lua
+ DEPENDS:=$(GO_ARCH_DEPENDS) @IPV6 +kmod-tun
endef
define Package/yggdrasil/description
interfaces simultaneously with much greater throughput.
endef
-define Package/yggdrasil/conffiles
-/etc/config/yggdrasil
-endef
-
define Package/yggdrasil/install
$(INSTALL_DIR) \
- $(1)/etc/init.d \
- $(1)/etc/uci-defaults \
+ $(1)/lib/netifd/proto \
$(1)/usr/sbin
$(INSTALL_BIN) \
$(1)/usr/sbin
$(INSTALL_BIN) \
- ./files/ygguci \
- $(1)/usr/sbin
-
- $(INSTALL_BIN) \
- ./files/yggdrasil.defaults \
- $(1)/etc/uci-defaults/yggdrasil
-
- $(INSTALL_BIN) \
- ./files/yggdrasil.init \
- $(1)/etc/init.d/yggdrasil
+ ./files/yggdrasil.sh \
+ $(1)/lib/netifd/proto
endef
$(eval $(call GoBinPackage,yggdrasil))
+++ /dev/null
-#!/bin/sh
-
-yggConfig="/etc/config/yggdrasil"
-
-first_boot_genConfig()
-{
- . /usr/share/libubox/jshn.sh
- boardcfg=$(ubus call system board)
- touch ${yggConfig}
- yggdrasil -genconf -json | ygguci set
-
- json_load "$boardcfg"
- json_get_var kernel kernel
- json_get_var system system
- json_get_var model model
- json_get_var board_name board_name
- nodeinfo='{"kernel": "'$kernel'", "hostname":"'OpenWrt'", "system": "'$system'", "model": "'$model'", "board_name": "'$board_name'"}'
-
- uci set yggdrasil.yggdrasil.IfName="ygg0"
- uci set yggdrasil.yggdrasil.NodeInfo="$nodeinfo"
- uci commit yggdrasil
-}
-
-if [ -e /etc/yggdrasil.conf ]; then
- echo "config: import config from /etc/yggdrasil.conf to /etc/config/yggdrasil" | logger -t yggdrasil
- touch ${yggConfig}
- cat /etc/yggdrasil.conf | ygguci set
- mv /etc/yggdrasil.conf /etc/yggdrasil.conf.bak
-elif [ ! -e ${yggConfig} ]; then
- echo "first_boot: adding system board details to NodeInfo[] in NEW config: ${yggConfig}" | logger -t yggdrasil
-
- first_boot_genConfig
-
- # create the network interface
- uci -q batch <<-EOF >/dev/null
- set network.yggdrasil=interface
- set network.yggdrasil.device=ygg0
- set network.yggdrasil.proto=none
-EOF
-
- # create the firewall zone
- uci -q batch <<-EOF >/dev/null
- set firewall.yggdrasil=zone
- set firewall.yggdrasil.name=yggdrasil
- add_list firewall.yggdrasil.network=yggdrasil
- set firewall.yggdrasil.input=REJECT
- set firewall.yggdrasil.output=ACCEPT
- set firewall.yggdrasil.forward=REJECT
- set firewall.yggdrasil.conntrack=1
-EOF
-
- # allow ICMP from yggdrasil zone, e.g. ping6
- uci -q batch <<-EOF >/dev/null
- add firewall rule
- set firewall.@rule[-1].name='Allow-ICMPv6-yggdrasil'
- set firewall.@rule[-1].src=yggdrasil
- set firewall.@rule[-1].proto=icmp
- add_list firewall.@rule[-1].icmp_type=echo-request
- add_list firewall.@rule[-1].icmp_type=echo-reply
- add_list firewall.@rule[-1].icmp_type=destination-unreachable
- add_list firewall.@rule[-1].icmp_type=packet-too-big
- add_list firewall.@rule[-1].icmp_type=time-exceeded
- add_list firewall.@rule[-1].icmp_type=bad-header
- add_list firewall.@rule[-1].icmp_type=unknown-header-type
- set firewall.@rule[-1].limit='1000/sec'
- set firewall.@rule[-1].family=ipv6
- set firewall.@rule[-1].target=ACCEPT
-EOF
-
- # allow SSH from yggdrasil zone, needs to be explicitly enabled
- uci -q batch <<-EOF >/dev/null
- add firewall rule
- set firewall.@rule[-1].enabled=0
- set firewall.@rule[-1].name='Allow-SSH-yggdrasil'
- set firewall.@rule[-1].src=yggdrasil
- set firewall.@rule[-1].proto=tcp
- set firewall.@rule[-1].dest_port=22
- set firewall.@rule[-1].target=ACCEPT
-EOF
-
- # allow LuCI access from yggdrasil zone, needs to be explicitly enabled
- uci -q batch <<-EOF >/dev/null
- add firewall rule
- set firewall.@rule[-1].enabled=0
- set firewall.@rule[-1].name='Allow-HTTP-yggdrasil'
- set firewall.@rule[-1].src=yggdrasil
- set firewall.@rule[-1].proto=tcp
- set firewall.@rule[-1].dest_port=80
- set firewall.@rule[-1].target=ACCEPT
-EOF
-
- # allow LuCI access with SSL from yggdrasil zone, needs to be explicitly enabled
- uci -q batch <<-EOF >/dev/null
- add firewall rule
- set firewall.@rule[-1].enabled=0
- set firewall.@rule[-1].name='Allow-HTTPS-yggdrasil'
- set firewall.@rule[-1].src=yggdrasil
- set firewall.@rule[-1].proto=tcp
- set firewall.@rule[-1].dest_port=443
- set firewall.@rule[-1].target=ACCEPT
-EOF
-
- uci commit firewall
- uci commit network
-
-else
- :
-fi
-
-exit 0
+++ /dev/null
-#!/bin/sh /etc/rc.common
-
-START=90
-STOP=85
-
-USE_PROCD=1
-BIN_FILE="/usr/sbin/yggdrasil"
-CONFIG_FILE="/tmp/yggdrasil.conf"
-DAEMON_OPTS="-useconffile $CONFIG_FILE"
-
-start_service()
-{
- [ -f /etc/uci-defaults/yggdrasil ] && ( . /etc/uci-defaults/yggdrasil )
-
- /usr/sbin/ygguci get | $BIN_FILE -useconf -normaliseconf -json > $CONFIG_FILE
-
- procd_open_instance
- procd_set_param respawn
- procd_set_param command $BIN_FILE $DAEMON_OPTS
- procd_set_param stdout 1
- procd_set_param stderr 1
- procd_close_instance
-}
-
-reload_service()
-{
- restart
-}
-
-service_triggers()
-{
- procd_add_reload_trigger yggdrasil
-}
--- /dev/null
+#!/bin/sh
+
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_yggdrasil_init_config() {
+ proto_config_add_string "private_key"
+ available=1
+}
+
+proto_yggdrasil_setup_peer_if_non_interface() {
+ local peer_config="$1"
+ local peer_address
+ local peer_interface
+ config_get peer_address "${peer_config}" "address"
+ config_get peer_interface "${peer_config}" "interface"
+ if [ -z ${peer_interface} ]; then
+ json_add_string "" ${peer_address}
+ fi;
+}
+
+proto_yggdrasil_dump_peer_interface() {
+ local peer_config="$1"
+ local peer_interface
+
+ config_get peer_interface "${peer_config}" "interface"
+
+ if [ ! -z ${peer_interface} ]; then
+ peer_interfaces="${peer_interfaces}\n${peer_interface}"
+ fi;
+}
+
+proto_yggdrasil_setup_peer_if_interface() {
+ local peer_config="$1"
+ local peer_address
+ local peer_interface
+ config_get peer_interface "${peer_config}" "interface"
+ if [ "${peer_interface}" = "${peer_interface_filter}" ]; then
+ config_get peer_address "${peer_config}" "address"
+ json_add_string "" ${peer_address}
+ fi;
+}
+
+proto_yggdrasil_append_to_interface_regex() {
+ if [ -z "${regex}" ]; then
+ regex="$1"
+ else
+ regex="${regex}|$1";
+ fi;
+}
+
+proto_yggdrasil_setup_multicast_interface() {
+ local interface_config="$1"
+ local beacon
+ local listen
+ local port=0
+ local password
+ local regex=""
+
+ config_get beacon "${interface_config}" "beacon"
+ config_get listen "${interface_config}" "listen"
+ config_get port "${interface_config}" "port"
+ config_get password "${interface_config}" "password"
+
+ json_add_object ""
+ json_add_boolean "Beacon" $beacon
+ json_add_boolean "Listen" $listen
+ if [ ! -z ${port} ]; then
+ json_add_int "Port" $port
+ else
+ json_add_int "Port" 0
+ fi;
+ if [ ! -z ${password} ]; then
+ json_add_string "Password" $password
+ fi;
+
+ config_list_foreach "${interface_config}" interface proto_yggdrasil_append_to_interface_regex
+
+ json_add_string "Regex" "^(${regex})\$"
+
+ json_close_object
+}
+
+proto_yggdrasil_add_string() {
+ json_add_string "" $1
+}
+
+proto_yggdrasil_generate_keypair() {
+ json_load "$(yggdrasil -genconf -json)"
+ json_get_vars PrivateKey
+ json_cleanup
+ private_key=$PrivateKey
+ public_key=${PrivateKey:64}
+}
+
+proto_yggdrasil_setup() {
+ local config="$1"
+ local device="$2"
+ local ygg_dir="/tmp/yggdrasil"
+ local ygg_cfg="${ygg_dir}/${config}.conf"
+ local ygg_sock="unix://${ygg_dir}/${config}.sock"
+
+
+ local private_key
+ local public_key
+ local mtu
+ local listen_addresses
+ local whitelisted_keys
+ local node_info
+ local node_info_privacy
+
+ config_load network
+ config_get private_key "${config}" "private_key"
+ config_get public_key "${config}" "public_key"
+ config_get mtu "${config}" "mtu"
+ config_get node_info "${config}" "node_info"
+ config_get node_info_privacy "${config}" "node_info_privacy"
+
+ if [ -z $private_key ]; then
+ proto_yggdrasil_generate_keypair
+ fi;
+
+ umask 077
+ mkdir -p "${ygg_dir}"
+
+ if [ $private_key = "auto" ]; then
+ proto_yggdrasil_generate_keypair
+ uci -t ${ygg_dir}/.uci.${config} batch <<EOF
+ set network.${config}.private_key='${private_key}'
+ set network.${config}.public_key='${public_key}'
+EOF
+ uci -t ${ygg_dir}/.uci.${config} commit;
+ fi;
+
+ # Generate config file
+ json_init
+ json_add_string "IfName" ${config}
+ json_add_string "AdminListen" ${ygg_sock}
+
+ json_add_string "PrivateKey" ${private_key}
+ json_add_string "PublicKey" ${public_key}
+
+ if [ ! -z $mtu ]; then
+ json_add_int "IfMTU" ${mtu}
+ fi;
+
+ if [ ! -z $node_info ]; then
+ json_add_string "NodeInfo" "%%_YGGDRASIL_NODEINFO_TEMPLATE_%%"
+ fi;
+
+ json_add_boolean "NodeInfoPrivacy" ${node_info_privacy}
+
+ # Peers
+ json_add_array "Peers"
+ config_foreach proto_yggdrasil_setup_peer_if_non_interface "yggdrasil_${config}_peer"
+ json_close_array
+
+ local peer_interfaces
+ peer_interfaces=""
+ config_foreach proto_yggdrasil_dump_peer_interface "yggdrasil_${config}_peer"
+ peer_interfaces=$(echo -e ${peer_interfaces} | sort | uniq)
+
+ json_add_object "InterfacePeers"
+ for peer_interface_filter in ${peer_interfaces}; do
+ json_add_array "${peer_interface_filter}"
+ config_foreach proto_yggdrasil_setup_peer_if_interface "yggdrasil_${config}_peer"
+ json_close_array
+ done
+ json_close_object
+
+ json_add_array "AllowedPublicKeys"
+ config_list_foreach "$config" allowed_public_key proto_yggdrasil_add_string
+ json_close_array
+
+ json_add_array "Listen"
+ config_list_foreach "$config" listen_address proto_yggdrasil_add_string
+ json_close_array
+
+ json_add_array "MulticastInterfaces"
+ config_foreach proto_yggdrasil_setup_multicast_interface "yggdrasil_${config}_interface"
+ json_close_array
+
+ json_dump > "${ygg_cfg}.1"
+ awk -v s='"%%_YGGDRASIL_NODEINFO_TEMPLATE_%%"' -v r="${node_info}" '{gsub(s, r)} 1' "${ygg_cfg}.1" > ${ygg_cfg}
+ rm "${ygg_cfg}.1"
+
+ proto_run_command "$config" /usr/sbin/yggdrasil -useconffile "${ygg_cfg}"
+ proto_init_update "$config" 1
+ proto_add_ipv6_address "$(yggdrasil -useconffile "${ygg_cfg}" -address)" "7"
+ proto_add_ipv6_prefix "$(yggdrasil -useconffile "${ygg_cfg}" -subnet)"
+ proto_send_update "$config"
+}
+
+proto_yggdrasil_teardown() {
+ local interface="$1"
+ proto_kill_command "$interface"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol yggdrasil
+}
+++ /dev/null
-#!/usr/bin/env lua
-
-dkjson = require("dkjson")
-uci = require("uci")
-
-UCI = {}
-
---- Return the configuration defaults as a table suitable for JSON output
---
--- Mostly taken from yggdrasil -genconf -json
--- @return table with configuration defaults
-function UCI.defaults()
- return {
- AdminListen = "unix:///var/run/yggdrasil.sock", IfName = "ygg0",
- NodeInfoPrivacy = false,
- IfMTU = 65535,
-
- Peers = { }, Listen = { }, MulticastInterfaces = { }, AllowedPublicKeys = { },
- InterfacePeers = setmetatable({ }, {__jsontype = "object"}),
- NodeInfo = setmetatable({ }, {__jsontype = "object"})
- }
-end
-
---- Return the yggdrasil configuration as a table suitable for JSON output
---
--- @return table with yggdrasil configuration
-function UCI.get()
- local obj = UCI.defaults()
-
- local cursor = uci.cursor()
- local config = cursor:get_all("yggdrasil", "yggdrasil")
- if not config then return obj end
-
- obj.PublicKey = config.PublicKey
- obj.PrivateKey = config.PrivateKey
- obj.AdminListen = config.AdminListen or obj.AdminListen
- obj.IfName = config.IfName or obj.IfName
- obj.NodeInfo = dkjson.decode(config.NodeInfo) or obj.NodeInfo
- for _, v in pairs({ "NodeInfoPrivacy" }) do
- if config[v] ~= nil then obj[v] = to_bool(config[v]) end
- end
- if config["IfMTU"] ~= nil then obj["IfMTU"] = tonumber(config["IfMTU"]) end
-
- cursor:foreach("yggdrasil", "peer", function (s)
- table.insert(obj.Peers, s.uri)
- end)
- cursor:foreach("yggdrasil", "listen_address", function (s)
- table.insert(obj.Listen, s.uri)
- end)
- cursor:foreach("yggdrasil", "multicast_interface", function (s)
- table.insert(obj.MulticastInterfaces, {
- Beacon = to_bool(s.beacon), Listen = to_bool(s.listen),
- Port = tonumber(s.port), Regex = s.regex
- })
- end)
- cursor:foreach("yggdrasil", "allowed_public_key", function (s)
- table.insert(obj.AllowedPublicKeys, s.key)
- end)
-
- cursor:foreach("yggdrasil", "interface_peer", function (s)
- if obj.InterfacePeers[s.interface] == nil then
- obj.InterfacePeers[s.interface] = {}
- end
- table.insert(obj.InterfacePeers[s["interface"]], s.uri)
- end)
-
- return obj
-end
-
---- Parse and save updated configuration from JSON input
---
--- Transforms general settings into UCI sections, and replaces the UCI config's
--- contents with them.
--- @param table JSON input
--- @return Boolean whether saving succeeded
-function UCI.set(obj)
- local cursor = uci.cursor()
-
- for i, section in pairs(cursor:get_all("yggdrasil")) do
- cursor:delete("yggdrasil", section[".name"])
- end
-
-
- cursor:set("yggdrasil", "yggdrasil", "yggdrasil")
- cursor:set("yggdrasil", "yggdrasil", "PublicKey", obj.PublicKey)
- cursor:set("yggdrasil", "yggdrasil", "PrivateKey", obj.PrivateKey)
- cursor:set("yggdrasil", "yggdrasil", "AdminListen", obj.AdminListen)
- cursor:set("yggdrasil", "yggdrasil", "IfName", obj.IfName)
- cursor:set("yggdrasil", "yggdrasil", "NodeInfoPrivacy", to_int(obj.NodeInfoPrivacy))
- cursor:set("yggdrasil", "yggdrasil", "NodeInfo", dkjson.encode(obj.NodeInfo))
- cursor:set("yggdrasil", "yggdrasil", "IfMTU", obj.IfMTU)
-
- set_values(cursor, "peer", "uri", obj.Peers)
- set_values(cursor, "listen_address", "uri", obj.Listen)
-
- for _, interface in pairs(obj.MulticastInterfaces) do
- local name = cursor:add("yggdrasil", "multicast_interface")
- cursor:set("yggdrasil", name, "beacon", to_int(interface.Beacon))
- cursor:set("yggdrasil", name, "listen", to_int(interface.Listen))
- cursor:set("yggdrasil", name, "port", interface.Port)
- cursor:set("yggdrasil", name, "regex", interface.Regex)
- end
-
- set_values(cursor, "allowed_public_key", "key", obj.AllowedPublicKeys)
-
- for interface, peers in pairs(obj.InterfacePeers) do
- for _, v in pairs(peers) do
- local name = cursor:add("yggdrasil", "interface_peer")
- cursor:set("yggdrasil", name, "interface", interface)
- cursor:set("yggdrasil", name, "uri", v)
- end
- end
-
- return cursor:commit("yggdrasil")
-end
-
-function set_values(cursor, section_name, parameter, values)
- if values == nil then return false end
-
- for k, v in pairs(values) do
- local name = cursor:add("yggdrasil", section_name)
- cursor:set("yggdrasil", name, parameter, v)
- end
-end
-
-function to_int(bool) return bool and '1' or '0' end
-
-function to_bool(int) return int ~= '0' end
-
-function help()
- print("JSON interface to /etc/config/yggdrasil\n\nExamples: \
- ygguci get > /tmp/etc/yggdrasil.conf \
- cat /tmp/etc/yggdrasil.conf | ygguci set \
- uci changes \
- ygguci get | yggdrasil -useconf")
-end
-
--- main
-
-if arg[1] == "get" then
- local json = dkjson.encode(UCI.get(), { indent = true })
- print(json)
-elseif arg[1] == "set" then
- local json = io.stdin:read("*a")
- local obj, pos, err = dkjson.decode(json, 1, nil)
-
- if obj then
- UCI.set(obj)
- else
- print("dkjson: " .. err)
- os.exit(1)
- end
-else
- help()
-end
PKG_NAME:=zerotier
PKG_VERSION:=1.12.2
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/zerotier/ZeroTierOne/tar.gz/$(PKG_VERSION)?
local args=""
if ! section_enabled "$cfg"; then
- echo "disabled in /ect/config/zerotier"
+ echo "disabled in /etc/config/zerotier"
return 1
fi
include $(TOPDIR)/rules.mk
PKG_NAME:=owntone
-PKG_VERSION:=28.5
+PKG_VERSION:=28.8
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/owntone/owntone-server/releases/download/$(PKG_VERSION)/
-PKG_HASH:=c9ee0152dc488f782a25a68e72d24c109882bef3dd2914315fe499c8415fd898
+PKG_HASH:=ebaee52ae617f08c41859522ba0a839d1865dcac7d6c0eb9e3fee81caf8fd47c
PKG_FIXUP:=autoreconf
PKG_BUILD_FLAGS:=no-mips16
TITLE:=iTunes (DAAP) server for Apple Remote and AirPlay
URL:=https://github.com/owntone/owntone-server
DEPENDS:=+libgpg-error +libgcrypt +libgdbm +zlib +libexpat +libunistring \
- +libevent2 +libdaemon +confuse +alsa-lib +libffmpeg-full \
+ +libevent2 +libevent2-pthreads +libdaemon +confuse +alsa-lib +libffmpeg-full \
+mxml +libavahi-client +sqlite3-cli +libplist +libcurl +libjson-c \
+libprotobuf-c +libgnutls +libsodium +libwebsockets +libuuid $(ICONV_DEPENDS)
endef
--disable-install_conf_file \
--disable-install_user \
--with-alsa \
- --without-pulseaudio \
- --without-libevent_pthreads
+ --without-pulseaudio
TARGET_CFLAGS += $(FPIC)
include $(TOPDIR)/rules.mk
PKG_NAME:=pulseaudio
-PKG_VERSION:=14.2
-PKG_RELEASE:=10
+PKG_VERSION:=16.1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://freedesktop.org/software/pulseaudio/releases
-PKG_HASH:=75d3f7742c1ae449049a4c88900e454b8b350ecaa8c544f3488a2562a9ff66f1
+PKG_HASH:=8eef32ce91d47979f95fd9a935e738cd7eb7463430dabc72863251751e504ae4
PKG_MAINTAINER:=Peter Wagner <tripolar@gmx.at>
PKG_LICENSE:=LGPL-2.1-or-later
define Package/pulseaudio-daemon/Default
SECTION:=sound
CATEGORY:=Sound
- DEPENDS:=+libsndfile +libltdl +libpthread +librt +alsa-lib \
+ DEPENDS:=+libsndfile +libltdl +alsa-lib \
+libopenssl +libcap $(ICONV_DEPENDS) $(INTL_DEPENDS)
TITLE:=Network sound server
URL:=https://www.freedesktop.org/wiki/Software/PulseAudio/
define Package/pulseaudio-daemon-avahi
$(call Package/pulseaudio-daemon/Default)
- DEPENDS+=+dbus +libavahi-client +sbc
+ DEPENDS+=+dbus +libavahi-client +sbc +bluez-daemon
TITLE+= (avahi/bluez)
VARIANT:=avahi
endef
-Dudev=disabled \
-Dx11=disabled \
-Dadrian-aec=true \
- -Dwebrtc-aec=disabled
+ -Dwebrtc-aec=disabled \
+ -Ddoxygen=false \
+ -Dtcpwrap=disabled \
+ -Dbluez5-gstreamer=disabled
ifeq ($(BUILD_VARIANT),avahi)
MESON_ARGS += \
-Davahi=enabled \
- -Dbluez5=true \
+ -Dbluez5=enabled \
-Ddbus=enabled
endif
ifeq ($(BUILD_VARIANT),noavahi)
MESON_ARGS += \
-Davahi=disabled \
- -Dbluez5=false \
+ -Dbluez5=disabled \
-Ddbus=disabled
endif
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pulseaudio/* $(1)/usr/lib/pulseaudio/
$(INSTALL_DIR) $(1)/usr/lib/pulse-$(PKG_VERSION)/modules
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/pulse-$(PKG_VERSION)/modules/lib*.so $(1)/usr/lib/
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/pulse-$(PKG_VERSION)/modules/module*.so $(1)/usr/lib/pulse-$(PKG_VERSION)/modules/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pulseaudio/modules/lib*.so $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pulseaudio/modules/module*.so $(1)/usr/lib/pulseaudio/modules/
endef
define Package/pulseaudio-daemon-avahi/install
+++ /dev/null
---- a/meson.build
-+++ b/meson.build
-@@ -390,12 +390,11 @@ if dl_dep.found()
- endif
-
- have_iconv = false
--if cc.has_function('iconv_open')
-+iconv_dep = cc.find_library('iconv', required : false)
-+have_iconv = iconv_dep.found()
-+if not have_iconv and cc.has_function('iconv_open')
- iconv_dep = dependency('', required : false)
- have_iconv = true
--else
-- iconv_dep = cc.find_library('iconv', required : false)
-- have_iconv = iconv_dep.found()
- endif
- if have_iconv
- cdata.set('HAVE_ICONV', 1)
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -681,7 +681,7 @@ if get_option('daemon')
+ cdata.set('HAVE_ALSA_UCM', 1)
+ endif
+
+- gio_dep = dependency('gio-2.0', version : '>= 2.26.0')
++ gio_dep = dependency('gio-2.0', version : '>= 2.26.0', required : false)
+ if get_option('gsettings').enabled()
+ assert(gio_dep.found(), 'GSettings support needs glib I/O library (GIO)')
+ cdata.set('HAVE_GSETTINGS', 1)
+++ /dev/null
---- a/meson.build
-+++ b/meson.build
-@@ -698,7 +698,6 @@ check_dep = dependency('check', version
-
- # Subdirs
-
--subdir('doxygen')
- subdir('po')
- if get_option('man')
- subdir('man')
+++ /dev/null
-#
-# Copyright (C) 2014-2016 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=shairplay
-PKG_SOURCE_DATE:=2018-08-24
-PKG_SOURCE_VERSION:=096b61ad14c90169f438e690d096e3fcf87e504e
-PKG_RELEASE:=2
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/juhovh/shairplay/tar.gz/$(PKG_SOURCE_VERSION)?
-PKG_HASH:=7e2b013ffe75ea2f13fb12b1aa38b8e2e8b1899ac292d57f05d7b352a3a181cf
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION)
-
-PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
-PKG_LICENSE:=MIT
-PKG_LICENSE_FILES:=LICENSE
-
-PKG_FIXUP:=autoreconf
-PKG_BUILD_PARALLEL:=1
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/shairplay
- SECTION:=sound
- CATEGORY:=Sound
- DEPENDS:=+libao +libavahi-compat-libdnssd +libltdl +libpthread
- TITLE:=Shairplay
-endef
-
-define Package/shairplay/description
- Free portable AirPlay server implementation similar to ShairPort.
-endef
-
-define Package/shairplay/conffiles
-/etc/config/shairplay
-endef
-
-define Package/shairplay/install
- $(INSTALL_DIR) $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/shairplay $(1)/usr/bin/
- $(INSTALL_DIR) $(1)/usr/share/shairplay
- $(INSTALL_DATA) $(PKG_BUILD_DIR)/airport.key $(1)/usr/share/shairplay/
- $(INSTALL_DIR) $(1)/etc/init.d
- $(INSTALL_BIN) files/shairplay.init $(1)/etc/init.d/shairplay
- $(INSTALL_DIR) $(1)/etc/config
- $(INSTALL_CONF) files/shairplay.config $(1)/etc/config/shairplay
-endef
-
-$(eval $(call BuildPackage,shairplay))
+++ /dev/null
-config shairplay main
- option disabled '1'
- option respawn '1'
- option apname 'AirPlay'
- option port '5000'
- option password ''
- option hwaddr ''
- option ao_driver 'oss'
- option ao_devicename ''
- option ao_deviceid ''
+++ /dev/null
-#!/bin/sh /etc/rc.common
-# Copyright (C) 2014 OpenWrt.org
-
-START=90
-USE_PROCD=1
-
-append_arg() {
- local cfg="$1"
- local var="$2"
- local opt="$3"
- local def="$4"
- local val
-
- config_get val "$cfg" "$var"
- [ -n "$val" -o -n "$def" ] && procd_append_param command $opt="${val:-$def}"
-}
-
-start_instance() {
- local cfg="$1"
- local aux
-
- config_get_bool aux "$cfg" 'disabled' '0'
- [ "$aux" = 1 ] && return 1
-
- procd_open_instance
-
- procd_set_param command /usr/bin/shairplay
-
- append_arg "$cfg" apname "--apname" "AirPlay"
- append_arg "$cfg" port "--server_port"
- append_arg "$cfg" password "--password"
- append_arg "$cfg" hwaddr "--hwaddr"
-
- append_arg "$cfg" ao_driver "--ao_driver"
- append_arg "$cfg" ao_devicename "--ao_devicename"
- append_arg "$cfg" ao_deviceid "--ao_deviceid"
-
- config_get_bool aux "$cfg" 'respawn' '0'
- [ "$aux" = 1 ] && procd_set_param respawn
-
- procd_close_instance
-}
-
-service_triggers() {
- procd_add_reload_trigger "shairplay"
-}
-
-start_service() {
- config_load shairplay
- config_foreach start_instance shairplay
-}
+++ /dev/null
---- a/src/shairplay.c
-+++ b/src/shairplay.c
-@@ -350,7 +350,7 @@ main(int argc, char *argv[])
- raop_cbs.audio_destroy = audio_destroy;
- raop_cbs.audio_set_volume = audio_set_volume;
-
-- raop = raop_init_from_keyfile(10, &raop_cbs, "airport.key", NULL);
-+ raop = raop_init_from_keyfile(10, &raop_cbs, "/usr/share/shairplay/airport.key", NULL);
- if (raop == NULL) {
- fprintf(stderr, "Could not initialize the RAOP service\n");
- fprintf(stderr, "Please make sure the airport.key file is in the current directory.\n");
+++ /dev/null
---- a/src/lib/alac/alac.c
-+++ b/src/lib/alac/alac.c
-@@ -29,7 +29,7 @@
- *
- */
-
--static const int host_bigendian = 0;
-+#define host_bigendian (htonl(42) == 42)
-
- #include <stdio.h>
- #include <stdlib.h>
+++ /dev/null
-From 031c3d802e51bbc233b1044f812402a66bfcf237 Mon Sep 17 00:00:00 2001
-From: Memphiz <memphis@machzwo.de>
-Date: Fri, 21 Dec 2018 20:39:11 +0100
-Subject: [PATCH] [configure] - only check for dns_sd.h in case libdl was not
- found
-
----
- configure.ac | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/configure.ac
-+++ b/configure.ac
-@@ -19,7 +19,7 @@ LT_LIB_DLLOAD
-
- # Checks for header files.
- AC_HEADER_STDC
--if test yes = "$libltdl_cv_func_dlopen" || test yes = "$libltdl_cv_lib_dl_dlopen"
-+if test no = "$libltdl_cv_func_dlopen" && test no = "$libltdl_cv_lib_dl_dlopen"
- then
- AC_CHECK_HEADERS([dns_sd.h], [],
- [AC_MSG_ERROR([Could not find dns_sd.h header, please install libavahi-compat-libdnssd-dev or equivalent.])])
include $(TOPDIR)/rules.mk
PKG_NAME:=upmpdcli
-PKG_VERSION:=1.5.19
+PKG_VERSION:=1.8.6
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.lesbonscomptes.com/upmpdcli/downloads
-PKG_HASH:=67fa1f5c06fecd404f3414b25a070c9deabe917241ed6881b7a8e41e8379ed09
+PKG_HASH:=55e3d27bea5bef4560f319137f1a5c7d08abbba5a9aae90ee3240903fdb8c3e4
PKG_MAINTAINER:=
PKG_LICENSE:=LGPL-2.1-or-later
PKG_FORTIFY_SOURCE:=0
PKG_BUILD_PARALLEL:=1
+include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/package.mk
define Package/acpica-unix
define Build/Configure
endef
+define Host/Install
+ $(INSTALL_DIR) $(STAGING_DIR_HOST)/usr/bin
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/generate/unix/bin/{acpibin,acpidump} \
+ $(STAGING_DIR_HOST)/usr/bin/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/generate/unix/bin/{acpiexamples,acpiexec} \
+ $(STAGING_DIR_HOST)/usr/bin/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/generate/unix/bin/{acpihelp,acpisrc} \
+ $(STAGING_DIR_HOST)/usr/bin/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/generate/unix/bin/{acpixtract,iasl} \
+ $(STAGING_DIR_HOST)/usr/bin/
+endef
+
+define Host/Clean
+ $(RM) $(STAGING_DIR_HOST)/usr/bin/{acpibin,acpidump}
+ $(RM) $(STAGING_DIR_HOST)/usr/bin/{acpiexamples,acpiexec}
+ $(RM) $(STAGING_DIR_HOST)/usr/bin/{acpihelp,acpisrc}
+ $(RM) $(STAGING_DIR_HOST)/usr/bin/{acpixtract,iasl}
+endef
+
MAKE_VARS += HOST=_LINUX
MAKE_PATH:=generate/unix
endef
$(eval $(call BuildPackage,acpica-unix))
+$(eval $(call HostBuild))
PKG_LICENSE_FILES:=LICENCE
PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
include ../../lang/rust/rust-package.mk
include $(TOPDIR)/rules.mk
PKG_NAME:=catatonit
-PKG_VERSION:=0.1.7
+PKG_VERSION:=0.2.0
PKG_RELEASE:=1
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL:=https://github.com/openSUSE/catatonit.git
-PKG_SOURCE_DATE:=2022-03-07
-PKG_SOURCE_VERSION:=d8d72fea155c144ed3bf298a35a1aba5625a5656
-PKG_MIRROR_HASH:=5dfec105de2b1e674db55e12007aa66cf67769d38e3f294fbca54fc3e9b78674
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/openSUSE/catatonit/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=d0cf1feffdc89c9fb52af20fc10127887a408bbd99e0424558d182b310a3dc92
PKG_BUILD_PARALLEL:=1
PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
-PKG_LICENSE:=GPL-3.0-or-later
+PKG_LICENSE:=GPL-2.0-or-later
PKG_LICENSE_FILES:=COPYING
include $(INCLUDE_DIR)/package.mk
--- /dev/null
+#
+# Copyright (C) 2020-2023 Olof Hagsand and Rubicon Communications, LLC(Netgate)
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=cligen
+PKG_VERSION:=6.5.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/clicon/$(PKG_NAME)/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=8b3943430f7aa9eea6a5f7cf1ace5b68eb382380cf68f41ae3ef5e032e08816f
+
+PKG_MAINTAINER:=Olof Hagsand <olof@hagsand.se>, Philip Prindeville <philipp@redfish-solutions.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE.md
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/cligen
+ SECTION:=utils
+ CATEGORY:=Utilities
+ URL:=https://www.cligen.se
+ TITLE:=CLIgen is a Command-Line Interface generator
+ DEPENDS:=libxml2
+endef
+
+define Package/cligen/description
+ CLIgen provides dynamic CLI interpretation from grammar files
+ handled at run-time.
+endef
+
+CONFIGURE_ARGS+= \
+ --exec-prefix=/usr
+
+CONFIGURE_ARGS:=$(filter-out --disable-dependency-tracking,$(CONFIGURE_ARGS))
+
+INSTALLFLAGS:=-s --strip-program=$(TARGET_CROSS)strip
+
+CONFIGURE_VARS+= \
+ INSTALLFLAGS="$(INSTALLFLAGS)"
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/cligen $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libcligen.so* $(1)/usr/lib/
+endef
+
+define Package/cligen/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libcligen.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,cligen))
--- /dev/null
+#
+# Copyright (C) 2020-2023 Olof Hagsand and Rubicon Communications, LLC(Netgate)
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=clixon
+PKG_VERSION:=6.5.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/clicon/$(PKG_NAME)/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=c85bf3112ddd9dcc00965780c21bf1589095c8b67f741ef7059c805feccf3bfc
+PKG_MAINTAINER:=Olof Hagsand <olof@hagsand.se>, Philip Prindeville <philipp@redfish-solutions.com>
+
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILE:=LICENSE.md
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/clixon
+ SECTION:=utils
+ CATEGORY:=Utilities
+ URL:=https://www.clicon.org
+ TITLE:=YANG-based toolchain
+ DEPENDS:=+cligen +libopenssl +libnghttp2 +libcurl \
+ @(PACKAGE_openssh-server||PACKAGE_openssh-server-pam)
+ USERID:=clicon=61:clicon=61
+endef
+
+define Package/clixon/description
+ YANG-based toolchain including NETCONF and RESTCONF interfaces and an interactive CLI.
+endef
+
+define Package/clixon/conffiles
+/etc/clixon/restconf.xml
+/etc/ssh/sshd_config.d/90-netconf-subsystem.conf
+endef
+
+CONFIGURE_ARGS += \
+ --exec-prefix=/usr \
+ --with-restconf=native \
+ --with-configfile=/etc/clixon/clixon.xml \
+ --with-cligen=$(STAGING_DIR)/usr
+
+CONFIGURE_ARGS:=$(filter-out --disable-dependency-tracking,$(CONFIGURE_ARGS))
+
+INSTALLFLAGS:=-s --strip-program=$(TARGET_CROSS)strip
+
+CONFIGURE_VARS+= \
+ INSTALLFLAGS="$(INSTALLFLAGS)" \
+ SSH_BIN=/usr/bin/ssh
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/clixon $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libclixon.so* \
+ $(PKG_INSTALL_DIR)/usr/lib/libclixon_backend.so* \
+ $(PKG_INSTALL_DIR)/usr/lib/libclixon_restconf.so* \
+ $(PKG_INSTALL_DIR)/usr/lib/libclixon_cli.so* \
+ $(1)/usr/lib/
+endef
+
+define Package/clixon/install
+ $(INSTALL_DIR) $(1)/etc/clixon
+ $(INSTALL_DATA) ./files/restconf.xml $(1)/etc/clixon/
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/clixon_* $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/clixon_* $(1)/usr/bin/
+ $(INSTALL_DIR) $(1)/usr/share/clixon
+ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/clixon/*.yang $(1)/usr/share/clixon/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libclixon.so* \
+ $(PKG_INSTALL_DIR)/usr/lib/libclixon_backend.so* \
+ $(PKG_INSTALL_DIR)/usr/lib/libclixon_restconf.so* \
+ $(PKG_INSTALL_DIR)/usr/lib/libclixon_cli.so* \
+ $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/clixon.init $(1)/etc/init.d/clixon
+ $(INSTALL_DIR) $(1)/etc/ssh/sshd_config.d
+ $(INSTALL_CONF) ./files/netconf-subsystem.conf $(1)/etc/ssh/sshd_config.d/90-netconf-subsystem.conf
+endef
+
+$(eval $(call BuildPackage,clixon))
+
--- /dev/null
+#!/bin/sh /etc/rc.common
+
+START=95
+STOP=05
+
+USE_PROCD=1
+PROG=/usr/sbin/clixon_backend
+CONFIGFILE=/etc/clixon/clixon.xml
+
+get_xmldb_dir() {
+ $PROG -F -f "$CONFIGFILE" -1 -l s -C text -s none \
+ | awk '/^ CLICON_XMLDB_DIR / { print substr($2, 0, length($2) - 1); }'
+}
+
+start_service() {
+ local state="init"
+
+ [ -f "$(get_xmldb_dir)/running_db" ] && state="running"
+
+ procd_open_instance
+ procd_set_param command "$PROG"
+
+ procd_set_param file $CONFIGFILE
+
+ procd_append_param command -F
+ procd_append_param command -f $CONFIGFILE
+ procd_append_param command -l s
+ procd_append_param command -s $state
+
+ procd_close_instance
+}
+
+stop_service() {
+ service_stop "$PROG"
+}
--- /dev/null
+Subsystem netconf /usr/bin/clixon_netconf
--- /dev/null
+<restconf>
+ <enable>true</enable>
+ <auth-type>none</auth-type>
+ <pretty>false</pretty>
+ <debug>0</debug>
+ <log-destination>syslog</log-destination>
+ <socket>
+ <namespace>default</namespace>
+ <address>0.0.0.0</address>
+ <port>80</port>
+ <ssl>false</ssl>
+ </socket>
+</restconf>
include $(TOPDIR)/rules.mk
PKG_NAME:=crun
-PKG_VERSION:=1.9.2
+PKG_VERSION:=1.12
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/containers/crun/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=a5ed2984a9ebb3e0e5cba0781832f03931423097a56f48a948ab034b46726aef
+PKG_HASH:=e4afa9dc5b3b851435b990331a013c6cb6064f3206609782f01486dff2446522
PKG_BUILD_DEPENDS:=argp-standalone
PKG_BUILD_PARALLEL:=1
--- /dev/null
+#
+# Copyright (C) 2023 David Bauer <mail@david-bauer.net>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=cudy-bdinfo
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/blocktrron/cudy-bdinfo-decrypt.git
+PKG_SOURCE_DATE:=2023-06-01
+PKG_SOURCE_VERSION:=5a60308c0fff610c4698207387d7153aba5fd62b
+PKG_MIRROR_HASH:=aefcd37e4b059d92226d2bc97b1b199f6a360c4935a6e92c930998b510275838
+
+PKG_MAINTAINER:=David Bauer <mail@david-bauer.net>
+PKG_LICENSE:=GPL-2.0-or-later
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/cudy-bdinfo
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=@(TARGET_ramips||TARGET_mediatek) +libopenssl
+ TITLE:=Tool for reading the bdinfo partition of Cudy routers
+endef
+
+define Package/cudy-bdinfo/description
+This program can be used to obtain information stored on the
+bdinfo parition found on routers from Shenzhen Cudy Technology.
+endef
+
+define Package/cudy-bdinfo/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/cudy-bdinfo $(1)/usr/bin/cudy-bdinfo
+endef
+
+
+$(eval $(call BuildPackage,cudy-bdinfo))
PKG_NAME:=dmidecode
PKG_VERSION:=3.2
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@SAVANNAH/$(PKG_NAME)
define Package/dmidecode
SECTION:=utils
CATEGORY:=Utilities
- DEPENDS:=@(TARGET_x86||TARGET_x86_64)
+ DEPENDS:=@(TARGET_x86||TARGET_x86_64||TARGET_armsr_armv8)
TITLE:=Displays BIOS informations.
URL:=https://www.nongnu.org/dmidecode/
endef
include $(TOPDIR)/rules.mk
PKG_NAME:=compose
-PKG_VERSION:=2.22.0
+PKG_VERSION:=2.23.3
PKG_RELEASE:=1
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
PKG_SOURCE:=v$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/docker/compose/tar.gz/v${PKG_VERSION}?
-PKG_HASH:=82bd4622729cff061b3489bad96b54849a7f4b462345aade1bd374c879db9019
+PKG_HASH:=29ba96c8d398fbc6f7c791c65e70b97e7df116223f2996062441093258d914fe
PKG_MAINTAINER:=Javier Marcet <javier@marcet.info>
include $(TOPDIR)/rules.mk
PKG_NAME:=domoticz
-PKG_VERSION:=2022.1
-PKG_RELEASE:=5
+PKG_VERSION:=2023.2
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/domoticz/domoticz/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=8282cb71c924b6ef92503976d50f966f2c785eab8f8cffa1136ac133f0241157
+PKG_HASH:=32bcf49df8c80c470352e63004a82d9601b90ccf406096099656250a4515ac28
PKG_MAINTAINER:=David Woodhouse <dwmw2@infradead.org>
PKG_LICENSE:=GPL-3.0
+++ /dev/null
-From 2975b1113d9540f39b6bade3b6d459b61c2e5007 Mon Sep 17 00:00:00 2001
-From: Arjen de Korte <build+github@de-korte.org>
-Date: Sun, 15 May 2022 19:00:02 +0200
-Subject: [PATCH] Fix compilation with GCC12
-
-Building domoticz fails under GCC12 with the following error:
-
-In file included from /usr/include/c++/12/utility:68,
- from /home/abuild/rpmbuild/BUILD/domoticz-2022.1/main/LuaTable.cpp:10:
-/usr/include/c++/12/bits/stl_relops.h:86:5: error: template with C linkage
- 86 | template <class _Tp>
- | ^~~~~~~~
----
- main/LuaTable.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/main/LuaTable.cpp
-+++ b/main/LuaTable.cpp
-@@ -6,9 +6,9 @@ extern "C" {
- #include <lua.h>
- #include <lualib.h>
- #include <lauxlib.h>
-+}
-
- #include <utility>
--}
-
- CLuaTable::CLuaTable(lua_State *lua_state, const std::string &Name)
- {
+++ /dev/null
-From 3c23a7863c0b01273d4c36423769443ea7e4a7bb Mon Sep 17 00:00:00 2001
-From: David Woodhouse <dwmw2@infradead.org>
-Date: Fri, 5 Jun 2020 15:02:41 +0100
-Subject: [PATCH 1/2] unzip: reduce file name size to 65535 to work with
- external minizip
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The external minizip project has changed the unzGetCurrentFileInfo()
-function to take a uint16_t as the filename size, instead of a uLong
-as in the original version in zlib.
-
-(Reported as https://github.com/nmoinvaz/minizip/issues/490 but it
-was 3½ years ago and might be too late to fix it now, although changing
-it back to a *larger* type is a lot safer than reducing the size, and
-perhaps they should.)
-
-This means that our 65536-byte buffer gets truncated to zero, as the
-compiler tells us when we build agaisnt the external minizip:
-
-domoticz/main/unzip_stream.h:140:50: warning: conversion from ‘long unsigned int’ to ‘uint16_t’ {aka ‘short unsigned int’} changes value from ‘65536’ to ‘0’ [-Woverflow]
- 140 | unzGetCurrentFileInfo(handler_, &info, path, sizeof(path), NULL, 0, NULL, 0);
- | ^~~~~~~~~~~~
-
-Reduce the buffer size to 65535 bytes instead.
----
- main/unzip_stream.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/main/unzip_stream.h
-+++ b/main/unzip_stream.h
-@@ -143,7 +143,7 @@ namespace clx {
- basic_unzip_stream& open(handler_type h) {
- handler_ = h;
- if (handler_) {
-- char path[65536];
-+ char path[65535];
- unz_file_info info;
- unzGetCurrentFileInfo(handler_, &info, path, sizeof(path), NULL, 0, NULL, 0);
- path_ = path;
+++ /dev/null
-From 8f01ed77d5831090f34ad59d22ef1f7cd4d740f2 Mon Sep 17 00:00:00 2001
-From: dnpwwo <kendel.boul@gmail.com>
-Date: Mon, 21 Feb 2022 10:27:06 +1100
-Subject: [PATCH] Convert Python implementation to use Python's stable ABI
-
----
- hardware/plugins/DelayedLink.h | 199 +++---
- hardware/plugins/PluginManager.cpp | 17 +-
- hardware/plugins/PluginMessages.h | 1 -
- hardware/plugins/PluginProtocols.cpp | 356 ++++++-----
- hardware/plugins/PluginTransports.cpp | 64 +-
- hardware/plugins/Plugins.cpp | 883 +++++++++-----------------
- hardware/plugins/Plugins.h | 37 +-
- hardware/plugins/PythonObjectEx.cpp | 60 +-
- hardware/plugins/PythonObjectEx.h | 83 +--
- hardware/plugins/PythonObjects.cpp | 147 +++--
- hardware/plugins/PythonObjects.h | 119 ----
- main/EventSystem.cpp | 3 +-
- main/EventsPythonDevice.cpp | 12 +-
- main/EventsPythonDevice.h | 42 +-
- main/EventsPythonModule.cpp | 321 ++++++----
- main/SQLHelper.cpp | 2 +-
- 16 files changed, 980 insertions(+), 1366 deletions(-)
-
---- a/hardware/plugins/DelayedLink.h
-+++ b/hardware/plugins/DelayedLink.h
-@@ -9,10 +9,19 @@
- #ifdef WITH_THREAD
- # undefine WITH_THREAD
- #endif
-+
-+#pragma push_macro("_DEBUG")
-+#ifdef _DEBUG
-+# undef _DEBUG // Not compatible with Py_LIMITED_API
-+#endif
-+#define Py_LIMITED_API 0x03040000
- #include <Python.h>
- #include <structmember.h>
--#include <frameobject.h>
--#include "../../main/Helper.h"
-+#include "../../main/Logger.h"
-+
-+#ifndef WIN32
-+# include "../../main/Helper.h"
-+#endif
-
- namespace Plugins {
-
-@@ -29,6 +38,8 @@ namespace Plugins {
- #define DECLARE_PYTHON_SYMBOL(type, symbol, params) typedef type (PYTHON_CALL symbol##_t)(params); symbol##_t symbol
- #define RESOLVE_PYTHON_SYMBOL(symbol) symbol = (symbol##_t)RESOLVE_SYMBOL(shared_lib_, #symbol)
-
-+#undef Py_None
-+
- struct SharedLibraryProxy
- {
- #ifdef WIN32
-@@ -36,6 +47,8 @@ namespace Plugins {
- #else
- void* shared_lib_;
- #endif
-+ PyObject* Py_None;
-+
- // Shared library interface begin.
- DECLARE_PYTHON_SYMBOL(const char*, Py_GetVersion, );
- DECLARE_PYTHON_SYMBOL(int, Py_IsInitialized, );
-@@ -50,6 +63,9 @@ namespace Plugins {
- DECLARE_PYTHON_SYMBOL(wchar_t*, Py_GetProgramFullPath, );
- DECLARE_PYTHON_SYMBOL(int, PyImport_AppendInittab, const char *COMMA PyObject *(*initfunc)());
- DECLARE_PYTHON_SYMBOL(int, PyType_Ready, PyTypeObject*);
-+ DECLARE_PYTHON_SYMBOL(PyObject*, PyObject_Type, PyObject*);
-+ DECLARE_PYTHON_SYMBOL(PyObject*, PyType_FromSpec, PyType_Spec*);
-+ DECLARE_PYTHON_SYMBOL(void*, PyType_GetSlot, PyTypeObject* COMMA int);
- DECLARE_PYTHON_SYMBOL(int, PyCallable_Check, PyObject*);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyObject_GetAttrString, PyObject* pObj COMMA const char*);
- DECLARE_PYTHON_SYMBOL(int, PyObject_HasAttrString, PyObject* COMMA const char *);
-@@ -60,7 +76,6 @@ namespace Plugins {
- DECLARE_PYTHON_SYMBOL(wchar_t*, PyUnicode_AsWideCharString, PyObject* COMMA Py_ssize_t*);
- DECLARE_PYTHON_SYMBOL(const char*, PyUnicode_AsUTF8, PyObject*);
- DECLARE_PYTHON_SYMBOL(char*, PyByteArray_AsString, PyObject*);
-- DECLARE_PYTHON_SYMBOL(PyObject*, PyUnicode_FromKindAndData, int COMMA const void* COMMA Py_ssize_t);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyLong_FromLong, long);
- DECLARE_PYTHON_SYMBOL(PY_LONG_LONG, PyLong_AsLongLong, PyObject*);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyModule_GetDict, PyObject*);
-@@ -91,8 +106,6 @@ namespace Plugins {
- DECLARE_PYTHON_SYMBOL(PyObject *, PyImport_ImportModule, const char *);
- DECLARE_PYTHON_SYMBOL(int, PyObject_RichCompareBool, PyObject* COMMA PyObject* COMMA int);
- DECLARE_PYTHON_SYMBOL(PyObject *, PyObject_CallObject, PyObject *COMMA PyObject *);
-- DECLARE_PYTHON_SYMBOL(PyObject *, PyObject_CallNoArgs, PyObject *); // Python 3.9 !!!!
-- DECLARE_PYTHON_SYMBOL(int, PyFrame_GetLineNumber, PyFrameObject*);
- DECLARE_PYTHON_SYMBOL(void, PyEval_InitThreads, );
- DECLARE_PYTHON_SYMBOL(int, PyEval_ThreadsInitialized, );
- DECLARE_PYTHON_SYMBOL(PyThreadState*, PyThreadState_Get, );
-@@ -102,17 +115,12 @@ namespace Plugins {
- DECLARE_PYTHON_SYMBOL(void, PyEval_RestoreThread, PyThreadState *);
- DECLARE_PYTHON_SYMBOL(void, PyEval_ReleaseLock, );
- DECLARE_PYTHON_SYMBOL(PyThreadState*, PyThreadState_Swap, PyThreadState*);
-- DECLARE_PYTHON_SYMBOL(int, PyGILState_Check, );
- DECLARE_PYTHON_SYMBOL(void, _Py_NegativeRefcount, const char* COMMA int COMMA PyObject*);
- DECLARE_PYTHON_SYMBOL(PyObject *, _PyObject_New, PyTypeObject *);
- DECLARE_PYTHON_SYMBOL(int, PyObject_IsInstance, PyObject* COMMA PyObject*);
- DECLARE_PYTHON_SYMBOL(int, PyObject_IsSubclass, PyObject *COMMA PyObject *);
- DECLARE_PYTHON_SYMBOL(PyObject *, PyObject_Dir, PyObject *);
--#ifdef _DEBUG
-- DECLARE_PYTHON_SYMBOL(PyObject*, PyModule_Create2TraceRefs, struct PyModuleDef* COMMA int);
--#else
- DECLARE_PYTHON_SYMBOL(PyObject*, PyModule_Create2, struct PyModuleDef* COMMA int);
--#endif
- DECLARE_PYTHON_SYMBOL(int, PyModule_AddObject, PyObject* COMMA const char* COMMA PyObject*);
- DECLARE_PYTHON_SYMBOL(int, PyArg_ParseTuple, PyObject* COMMA const char* COMMA ...);
- DECLARE_PYTHON_SYMBOL(int, PyArg_ParseTupleAndKeywords, PyObject* COMMA PyObject* COMMA const char* COMMA char*[] COMMA ...);
-@@ -120,8 +128,6 @@ namespace Plugins {
- DECLARE_PYTHON_SYMBOL(PyObject*, Py_BuildValue, const char* COMMA ...);
- DECLARE_PYTHON_SYMBOL(void, PyMem_Free, void*);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyBool_FromLong, long);
-- DECLARE_PYTHON_SYMBOL(int, PyRun_SimpleStringFlags, const char* COMMA PyCompilerFlags*);
-- DECLARE_PYTHON_SYMBOL(int, PyRun_SimpleFileExFlags, FILE* COMMA const char* COMMA int COMMA PyCompilerFlags*);
- DECLARE_PYTHON_SYMBOL(void*, PyCapsule_Import, const char *name COMMA int);
- DECLARE_PYTHON_SYMBOL(void*, PyType_GenericAlloc, const PyTypeObject * COMMA Py_ssize_t);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyUnicode_DecodeUTF8, const char * COMMA Py_ssize_t COMMA const char *);
-@@ -132,44 +138,32 @@ namespace Plugins {
- DECLARE_PYTHON_SYMBOL(long, PyLong_AsLong, PyObject*);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyUnicode_AsUTF8String, PyObject*);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyImport_AddModule, const char*);
-- DECLARE_PYTHON_SYMBOL(void, PyEval_SetProfile, Py_tracefunc COMMA PyObject*);
-- DECLARE_PYTHON_SYMBOL(void, PyEval_SetTrace, Py_tracefunc COMMA PyObject*);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyObject_Str, PyObject*);
- DECLARE_PYTHON_SYMBOL(int, PyObject_IsTrue, PyObject*);
- DECLARE_PYTHON_SYMBOL(double, PyFloat_AsDouble, PyObject*);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyObject_GetIter, PyObject*);
- DECLARE_PYTHON_SYMBOL(PyObject*, PyIter_Next, PyObject*);
- DECLARE_PYTHON_SYMBOL(void, PyErr_SetString, PyObject* COMMA const char*);
--
--#ifdef _DEBUG
-- // In a debug build dealloc is a function but for release builds its a macro
-+ DECLARE_PYTHON_SYMBOL(PyObject*, PyObject_CallFunctionObjArgs, PyObject* COMMA ...);
-+ DECLARE_PYTHON_SYMBOL(PyObject*, Py_CompileString, const char* COMMA const char* COMMA int);
-+ DECLARE_PYTHON_SYMBOL(PyObject*, PyEval_EvalCode, PyObject* COMMA PyObject* COMMA PyObject*);
-+ DECLARE_PYTHON_SYMBOL(long, PyType_GetFlags, PyTypeObject*);
- DECLARE_PYTHON_SYMBOL(void, _Py_Dealloc, PyObject*);
--#endif
-- Py_ssize_t _Py_RefTotal;
-- PyObject _Py_NoneStruct;
-- PyObject * dzPy_None;
-
- SharedLibraryProxy() {
-+ Py_None = nullptr;
- shared_lib_ = nullptr;
-- _Py_RefTotal = 0;
- if (!shared_lib_) {
- #ifdef WIN32
--# ifdef _DEBUG
-- if (!shared_lib_) shared_lib_ = LoadLibrary("python39_d.dll");
-- if (!shared_lib_) shared_lib_ = LoadLibrary("python38_d.dll");
-- if (!shared_lib_) shared_lib_ = LoadLibrary("python37_d.dll");
-- if (!shared_lib_) shared_lib_ = LoadLibrary("python36_d.dll");
-- if (!shared_lib_) shared_lib_ = LoadLibrary("python35_d.dll");
-- if (!shared_lib_) shared_lib_ = LoadLibrary("python34_d.dll");
--# else
-+ if (!shared_lib_) shared_lib_ = LoadLibrary("python310.dll");
- if (!shared_lib_) shared_lib_ = LoadLibrary("python39.dll");
- if (!shared_lib_) shared_lib_ = LoadLibrary("python38.dll");
- if (!shared_lib_) shared_lib_ = LoadLibrary("python37.dll");
- if (!shared_lib_) shared_lib_ = LoadLibrary("python36.dll");
- if (!shared_lib_) shared_lib_ = LoadLibrary("python35.dll");
- if (!shared_lib_) shared_lib_ = LoadLibrary("python34.dll");
--# endif
- #else
-+ if (!shared_lib_) FindLibrary("python3.10", true);
- if (!shared_lib_) FindLibrary("python3.9", true);
- if (!shared_lib_) FindLibrary("python3.8", true);
- if (!shared_lib_) FindLibrary("python3.7", true);
-@@ -198,6 +192,9 @@ namespace Plugins {
- RESOLVE_PYTHON_SYMBOL(Py_GetProgramFullPath);
- RESOLVE_PYTHON_SYMBOL(PyImport_AppendInittab);
- RESOLVE_PYTHON_SYMBOL(PyType_Ready);
-+ RESOLVE_PYTHON_SYMBOL(PyObject_Type);
-+ RESOLVE_PYTHON_SYMBOL(PyType_FromSpec);
-+ RESOLVE_PYTHON_SYMBOL(PyType_GetSlot);
- RESOLVE_PYTHON_SYMBOL(PyCallable_Check);
- RESOLVE_PYTHON_SYMBOL(PyObject_GetAttrString);
- RESOLVE_PYTHON_SYMBOL(PyObject_HasAttrString);
-@@ -208,7 +205,6 @@ namespace Plugins {
- RESOLVE_PYTHON_SYMBOL(PyUnicode_AsWideCharString);
- RESOLVE_PYTHON_SYMBOL(PyUnicode_AsUTF8);
- RESOLVE_PYTHON_SYMBOL(PyByteArray_AsString);
-- RESOLVE_PYTHON_SYMBOL(PyUnicode_FromKindAndData);
- RESOLVE_PYTHON_SYMBOL(PyLong_FromLong);
- RESOLVE_PYTHON_SYMBOL(PyLong_AsLongLong);
- RESOLVE_PYTHON_SYMBOL(PyModule_GetDict);
-@@ -239,8 +235,6 @@ namespace Plugins {
- RESOLVE_PYTHON_SYMBOL(PyImport_ImportModule);
- RESOLVE_PYTHON_SYMBOL(PyObject_RichCompareBool);
- RESOLVE_PYTHON_SYMBOL(PyObject_CallObject);
-- RESOLVE_PYTHON_SYMBOL(PyObject_CallNoArgs);
-- RESOLVE_PYTHON_SYMBOL(PyFrame_GetLineNumber);
- RESOLVE_PYTHON_SYMBOL(PyEval_InitThreads);
- RESOLVE_PYTHON_SYMBOL(PyEval_ThreadsInitialized);
- RESOLVE_PYTHON_SYMBOL(PyThreadState_Get);
-@@ -250,28 +244,18 @@ namespace Plugins {
- RESOLVE_PYTHON_SYMBOL(PyEval_RestoreThread);
- RESOLVE_PYTHON_SYMBOL(PyEval_ReleaseLock);
- RESOLVE_PYTHON_SYMBOL(PyThreadState_Swap);
-- RESOLVE_PYTHON_SYMBOL(PyGILState_Check);
- RESOLVE_PYTHON_SYMBOL(_Py_NegativeRefcount);
- RESOLVE_PYTHON_SYMBOL(_PyObject_New);
- RESOLVE_PYTHON_SYMBOL(PyObject_IsInstance);
- RESOLVE_PYTHON_SYMBOL(PyObject_IsSubclass);
- RESOLVE_PYTHON_SYMBOL(PyObject_Dir);
--#ifdef _DEBUG
-- RESOLVE_PYTHON_SYMBOL(PyModule_Create2TraceRefs);
--#else
- RESOLVE_PYTHON_SYMBOL(PyModule_Create2);
--#endif
- RESOLVE_PYTHON_SYMBOL(PyModule_AddObject);
- RESOLVE_PYTHON_SYMBOL(PyArg_ParseTuple);
- RESOLVE_PYTHON_SYMBOL(PyArg_ParseTupleAndKeywords);
- RESOLVE_PYTHON_SYMBOL(PyUnicode_FromFormat);
- RESOLVE_PYTHON_SYMBOL(Py_BuildValue);
- RESOLVE_PYTHON_SYMBOL(PyMem_Free);
--#ifdef _DEBUG
-- RESOLVE_PYTHON_SYMBOL(_Py_Dealloc);
--#endif
-- RESOLVE_PYTHON_SYMBOL(PyRun_SimpleFileExFlags);
-- RESOLVE_PYTHON_SYMBOL(PyRun_SimpleStringFlags);
- RESOLVE_PYTHON_SYMBOL(PyBool_FromLong);
- RESOLVE_PYTHON_SYMBOL(PyCapsule_Import);
- RESOLVE_PYTHON_SYMBOL(PyType_GenericAlloc);
-@@ -283,17 +267,19 @@ namespace Plugins {
- RESOLVE_PYTHON_SYMBOL(PyLong_AsLong);
- RESOLVE_PYTHON_SYMBOL(PyUnicode_AsUTF8String);
- RESOLVE_PYTHON_SYMBOL(PyImport_AddModule);
-- RESOLVE_PYTHON_SYMBOL(PyEval_SetProfile);
-- RESOLVE_PYTHON_SYMBOL(PyEval_SetTrace);
- RESOLVE_PYTHON_SYMBOL(PyObject_Str);
- RESOLVE_PYTHON_SYMBOL(PyObject_IsTrue);
- RESOLVE_PYTHON_SYMBOL(PyFloat_AsDouble);
- RESOLVE_PYTHON_SYMBOL(PyObject_GetIter);
- RESOLVE_PYTHON_SYMBOL(PyIter_Next);
- RESOLVE_PYTHON_SYMBOL(PyErr_SetString);
-+ RESOLVE_PYTHON_SYMBOL(PyObject_CallFunctionObjArgs);
-+ RESOLVE_PYTHON_SYMBOL(Py_CompileString);
-+ RESOLVE_PYTHON_SYMBOL(PyEval_EvalCode);
-+ RESOLVE_PYTHON_SYMBOL(PyType_GetFlags);
-+ RESOLVE_PYTHON_SYMBOL(_Py_Dealloc);
- }
- }
-- _Py_NoneStruct.ob_refcnt = 1;
- };
- ~SharedLibraryProxy() = default;
-
-@@ -412,15 +398,7 @@ namespace Plugins {
-
- extern SharedLibraryProxy* pythonLib;
-
--// Create local pointer to Py_None, required to work around build complaints
--#ifdef Py_None
-- #undef Py_None
--#endif
--#define Py_None pythonLib->dzPy_None
--#ifdef Py_RETURN_NONE
-- #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
--#endif
--#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-+#define Py_None pythonLib->Py_None
- #define Py_LoadLibrary pythonLib->Py_LoadLibrary
- #define Py_GetVersion pythonLib->Py_GetVersion
- #define Py_IsInitialized pythonLib->Py_IsInitialized
-@@ -435,6 +413,9 @@ extern SharedLibraryProxy* pythonLib;
- #define Py_GetProgramFullPath pythonLib->Py_GetProgramFullPath
- #define PyImport_AppendInittab pythonLib->PyImport_AppendInittab
- #define PyType_Ready pythonLib->PyType_Ready
-+#define PyObject_Type pythonLib->PyObject_Type
-+#define PyType_FromSpec pythonLib->PyType_FromSpec
-+#define PyType_GetSlot pythonLib->PyType_GetSlot
- #define PyCallable_Check pythonLib->PyCallable_Check
- #define PyObject_GetAttrString pythonLib->PyObject_GetAttrString
- #define PyObject_HasAttrString pythonLib->PyObject_HasAttrString
-@@ -446,7 +427,6 @@ extern SharedLibraryProxy* pythonLib;
- #define PyUnicode_AsWideCharString pythonLib->PyUnicode_AsWideCharString
- #define PyUnicode_AsUTF8 pythonLib->PyUnicode_AsUTF8
- #define PyByteArray_AsString pythonLib->PyByteArray_AsString
--#define PyUnicode_FromKindAndData pythonLib->PyUnicode_FromKindAndData
- #define PyLong_FromLong pythonLib->PyLong_FromLong
- #define PyLong_AsLongLong pythonLib->PyLong_AsLongLong
- #define PyModule_GetDict pythonLib->PyModule_GetDict
-@@ -460,7 +440,7 @@ extern SharedLibraryProxy* pythonLib;
- #define PyDict_SetItem pythonLib->PyDict_SetItem
- #define PyDict_DelItem pythonLib->PyDict_DelItem
- #define PyDict_DelItemString pythonLib->PyDict_DelItemString
--#define PyDict_Next pythonLib->PyDict_Next
-+#define PyDict_Next pythonLib->PyDict_Next
- #define PyDict_Items pythonLib->PyDict_Items
- #define PyList_New pythonLib->PyList_New
- #define PyList_Size pythonLib->PyList_Size
-@@ -477,8 +457,6 @@ extern SharedLibraryProxy* pythonLib;
- #define PyImport_ImportModule pythonLib->PyImport_ImportModule
- #define PyObject_RichCompareBool pythonLib->PyObject_RichCompareBool
- #define PyObject_CallObject pythonLib->PyObject_CallObject
--#define PyObject_CallNoArgs pythonLib->PyObject_CallNoArgs
--#define PyFrame_GetLineNumber pythonLib->PyFrame_GetLineNumber
- #define PyEval_InitThreads pythonLib->PyEval_InitThreads
- #define PyEval_ThreadsInitialized pythonLib->PyEval_ThreadsInitialized
- #define PyThreadState_Get pythonLib->PyThreadState_Get
-@@ -488,7 +466,6 @@ extern SharedLibraryProxy* pythonLib;
- #define PyEval_RestoreThread pythonLib->PyEval_RestoreThread
- #define PyEval_ReleaseLock pythonLib->PyEval_ReleaseLock
- #define PyThreadState_Swap pythonLib->PyThreadState_Swap
--#define PyGILState_Check pythonLib->PyGILState_Check
- #define _Py_NegativeRefcount pythonLib->_Py_NegativeRefcount
- #define _PyObject_New pythonLib->_PyObject_New
- #define PyObject_IsInstance pythonLib->PyObject_IsInstance
-@@ -497,22 +474,10 @@ extern SharedLibraryProxy* pythonLib;
- #define PyArg_ParseTuple pythonLib->PyArg_ParseTuple
- #define Py_BuildValue pythonLib->Py_BuildValue
- #define PyMem_Free pythonLib->PyMem_Free
--#ifdef _DEBUG
--# define PyModule_Create2TraceRefs pythonLib->PyModule_Create2TraceRefs
--#else
--# define PyModule_Create2 pythonLib->PyModule_Create2
--#endif
-+#define PyModule_Create2 pythonLib->PyModule_Create2
- #define PyModule_AddObject pythonLib->PyModule_AddObject
- #define PyArg_ParseTupleAndKeywords pythonLib->PyArg_ParseTupleAndKeywords
--
--#ifdef _DEBUG
--# define _Py_Dealloc pythonLib->_Py_Dealloc
--#endif
--
- #define _Py_RefTotal pythonLib->_Py_RefTotal
--#define _Py_NoneStruct pythonLib->_Py_NoneStruct
--#define PyRun_SimpleStringFlags pythonLib->PyRun_SimpleStringFlags
--#define PyRun_SimpleFileExFlags pythonLib->PyRun_SimpleFileExFlags
- #define PyBool_FromLong pythonLib->PyBool_FromLong
- #define PyCapsule_Import pythonLib->PyCapsule_Import
- #define PyType_GenericAlloc pythonLib->PyType_GenericAlloc
-@@ -524,80 +489,88 @@ extern SharedLibraryProxy* pythonLib;
- #define PyLong_AsLong pythonLib->PyLong_AsLong
- #define PyUnicode_AsUTF8String pythonLib->PyUnicode_AsUTF8String
- #define PyImport_AddModule pythonLib->PyImport_AddModule
--#define PyEval_SetProfile pythonLib->PyEval_SetProfile
--#define PyEval_SetTrace pythonLib->PyEval_SetTrace
- #define PyObject_Str pythonLib->PyObject_Str
- #define PyObject_IsTrue pythonLib->PyObject_IsTrue
- #define PyFloat_AsDouble pythonLib->PyFloat_AsDouble
- #define PyObject_GetIter pythonLib->PyObject_GetIter
- #define PyIter_Next pythonLib->PyIter_Next
- #define PyErr_SetString pythonLib->PyErr_SetString
--
--#ifndef _Py_DEC_REFTOTAL
--/* _Py_DEC_REFTOTAL macro has been removed from Python 3.9 by: https://github.com/python/cpython/commit/49932fec62c616ec88da52642339d83ae719e924 */
--#ifdef Py_REF_DEBUG
--#define _Py_DEC_REFTOTAL _Py_RefTotal--
-+#define PyObject_CallFunctionObjArgs pythonLib->PyObject_CallFunctionObjArgs
-+#define Py_CompileString pythonLib->Py_CompileString
-+#define PyEval_EvalCode pythonLib->PyEval_EvalCode
-+#define PyType_GetFlags pythonLib->PyType_GetFlags
-+#ifdef WIN32
-+# define _Py_Dealloc pythonLib->_Py_Dealloc // Builds against a low Python version
-+#elif PY_VERSION_HEX < 0x03090000
-+# define _Py_Dealloc pythonLib->_Py_Dealloc
- #else
--#define _Py_DEC_REFTOTAL
--#define _Py_Dealloc
--#endif
-+# ifndef _Py_DEC_REFTOTAL
-+ /* _Py_DEC_REFTOTAL macro has been removed from Python 3.9 by: https://github.com/python/cpython/commit/49932fec62c616ec88da52642339d83ae719e924 */
-+# ifdef Py_REF_DEBUG
-+# define _Py_DEC_REFTOTAL _Py_RefTotal--
-+# else
-+# define _Py_DEC_REFTOTAL
-+# define _Py_Dealloc
-+# endif
-+# endif
- #endif
-
- #if PY_VERSION_HEX >= 0x030800f0
-- static inline void py3__Py_INCREF(PyObject *op)
-- {
-+static inline void py3__Py_INCREF(PyObject* op)
-+{
- #ifdef Py_REF_DEBUG
-- _Py_RefTotal++;
-+ _Py_RefTotal++;
- #endif
-- op->ob_refcnt++;
-- }
-+ op->ob_refcnt++;
-+}
-
- #undef Py_INCREF
- #define Py_INCREF(op) py3__Py_INCREF(_PyObject_CAST(op))
-
-- static inline void py3__Py_XINCREF(PyObject *op)
-+static inline void py3__Py_XINCREF(PyObject* op)
-+{
-+ if (op != NULL)
- {
-- if (op != NULL)
-- {
-- Py_INCREF(op);
-- }
-+ Py_INCREF(op);
- }
-+}
-
- #undef Py_XINCREF
- #define Py_XINCREF(op) py3__Py_XINCREF(_PyObject_CAST(op))
-
-- static inline void py3__Py_DECREF(const char *filename, int lineno, PyObject *op)
-+static inline void py3__Py_DECREF(const char* filename, int lineno, PyObject* op)
-+{
-+ (void)filename; /* may be unused, shut up -Wunused-parameter */
-+ (void)lineno; /* may be unused, shut up -Wunused-parameter */
-+ _Py_DEC_REFTOTAL;
-+ if (--op->ob_refcnt != 0)
- {
-- (void)filename; /* may be unused, shut up -Wunused-parameter */
-- (void)lineno; /* may be unused, shut up -Wunused-parameter */
-- _Py_DEC_REFTOTAL;
-- if (--op->ob_refcnt != 0)
-- {
- #ifdef Py_REF_DEBUG
-- if (op->ob_refcnt < 0)
-- {
-- _Py_NegativeRefcount(filename, lineno, op);
-- }
--#endif
-- }
-- else
-+ if (op->ob_refcnt < 0)
- {
-- _Py_Dealloc(op);
-+ _Py_NegativeRefcount(filename, lineno, op);
- }
-+#endif
-+ }
-+ else
-+ {
-+ _Py_Dealloc(op);
- }
-+}
-
- #undef Py_DECREF
- #define Py_DECREF(op) py3__Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op))
-
-- static inline void py3__Py_XDECREF(PyObject *op)
-+static inline void py3__Py_XDECREF(PyObject* op)
-+{
-+ if (op != nullptr)
- {
-- if (op != nullptr)
-- {
-- Py_DECREF(op);
-- }
-+ Py_DECREF(op);
- }
-+}
-
- #undef Py_XDECREF
- #define Py_XDECREF(op) py3__Py_XDECREF(_PyObject_CAST(op))
- #endif
-+#pragma pop_macro("_DEBUG")
- } // namespace Plugins
---- a/hardware/plugins/PluginManager.cpp
-+++ b/hardware/plugins/PluginManager.cpp
-@@ -31,7 +31,9 @@
- #include "DelayedLink.h"
- #include "../../main/EventsPythonModule.h"
-
--#define MINIMUM_PYTHON_VERSION "3.4.0"
-+// Python version constants
-+#define MINIMUM_MAJOR_VERSION 3
-+#define MINIMUM_MINOR_VERSION 4
-
- #define ATTRIBUTE_VALUE(pElement, Name, Value) \
- { \
-@@ -105,9 +107,18 @@ namespace Plugins {
- }
-
- std::string sVersion = szPyVersion.substr(0, szPyVersion.find_first_of(' '));
-- if (sVersion < MINIMUM_PYTHON_VERSION)
-+
-+ std::string sMajorVersion = sVersion.substr(0, sVersion.find_first_of('.'));
-+ if (std::stoi(sMajorVersion) < MINIMUM_MAJOR_VERSION)
-+ {
-+ _log.Log(LOG_STATUS, "PluginSystem: Invalid Python version '%s' found, Major version '%d' or above required.", sVersion.c_str(), MINIMUM_MAJOR_VERSION);
-+ return false;
-+ }
-+
-+ std::string sMinorVersion = sVersion.substr(sMajorVersion.length()+1);
-+ if (std::stoi(sMinorVersion) < MINIMUM_MINOR_VERSION)
- {
-- _log.Log(LOG_STATUS, "PluginSystem: Invalid Python version '%s' found, '%s' or above required.", sVersion.c_str(), MINIMUM_PYTHON_VERSION);
-+ _log.Log(LOG_STATUS, "PluginSystem: Invalid Python version '%s' found, Minor version '%d.%d' or above required.", sVersion.c_str(), MINIMUM_MAJOR_VERSION, MINIMUM_MINOR_VERSION);
- return false;
- }
-
---- a/hardware/plugins/PluginMessages.h
-+++ b/hardware/plugins/PluginMessages.h
-@@ -60,7 +60,6 @@ namespace Plugins {
- InitializeMessage() : CPluginMessageBase() { m_Name = __func__; };
- void Process(CPlugin* pPlugin) override
- {
-- //std::lock_guard<std::mutex> l(PythonMutex);
- pPlugin->Initialise();
- };
- void ProcessLocked(CPlugin* pPlugin) override{};
---- a/hardware/plugins/PluginProtocols.cpp
-+++ b/hardware/plugins/PluginProtocols.cpp
-@@ -5,6 +5,7 @@
- //
- #ifdef ENABLE_PYTHON
-
-+#include "../../main/Helper.h"
- #include "PluginMessages.h"
- #include "PluginProtocols.h"
- #include "../../main/Helper.h"
-@@ -52,32 +53,37 @@ namespace Plugins {
- std::vector<byte> CPluginProtocol::ProcessOutbound(const WriteDirective* WriteMessage)
- {
- std::vector<byte> retVal;
-+ PyBorrowedRef pObject(WriteMessage->m_Object);
-
- // Handle Bytes objects
-- if ((((PyObject*)WriteMessage->m_Object)->ob_type->tp_flags & (Py_TPFLAGS_BYTES_SUBCLASS)) != 0)
-+ if (pObject.IsBytes())
- {
-- const char* pData = PyBytes_AsString(WriteMessage->m_Object);
-- int iSize = PyBytes_Size(WriteMessage->m_Object);
-+ const char* pData = PyBytes_AsString(pObject);
-+ int iSize = PyBytes_Size(pObject);
- retVal.reserve((size_t)iSize);
- retVal.assign(pData, pData + iSize);
- }
- // Handle ByteArray objects
-- else if ((((PyObject*)WriteMessage->m_Object)->ob_type->tp_name == std::string("bytearray")))
-+ else if (pObject.IsByteArray())
- {
-- size_t len = PyByteArray_Size(WriteMessage->m_Object);
-- char* data = PyByteArray_AsString(WriteMessage->m_Object);
-+ size_t len = PyByteArray_Size(pObject);
-+ char* data = PyByteArray_AsString(pObject);
- retVal.reserve(len);
- retVal.assign((const byte*)data, (const byte*)data + len);
- }
-- // Handle String objects
-- else if ((((PyObject*)WriteMessage->m_Object)->ob_type->tp_flags & (Py_TPFLAGS_UNICODE_SUBCLASS)) != 0)
-+ // Try forcing a String conversion
-+ else
- {
-- std::string sData = PyUnicode_AsUTF8(WriteMessage->m_Object);
-- retVal.reserve((size_t)sData.length());
-- retVal.assign((const byte*)sData.c_str(), (const byte*)sData.c_str() + sData.length());
-+ PyNewRef pStr = PyObject_Str(pObject);
-+ if (pStr)
-+ {
-+ std::string sData = PyUnicode_AsUTF8(pStr);
-+ retVal.reserve((size_t)sData.length());
-+ retVal.assign((const byte*)sData.c_str(), (const byte*)sData.c_str() + sData.length());
-+ }
-+ else
-+ _log.Log(LOG_ERROR, "(%s) Unable to convert data (%s) to string representation, ignored.", __func__, pObject.Type().c_str());
- }
-- else
-- _log.Log(LOG_ERROR, "(%s) Send request Python object parameter was not of type Unicode or Byte, ignored.", __func__);
-
- return retVal;
- }
-@@ -120,7 +126,7 @@ namespace Plugins {
- if (PyDict_SetItemString(pDict, key, pObj) == -1)
- _log.Log(LOG_ERROR, "(%s) failed to add key '%s', value '%s' to dictionary.", __func__, key, value.c_str());
- }
--
-+
- static void AddStringToDict(PyObject* pDict, const char* key, const std::string& value)
- {
- PyNewRef pObj = Py_BuildValue("s#", value.c_str(), value.length());
-@@ -166,7 +172,7 @@ namespace Plugins {
- Py_ssize_t Index = 0;
- for (auto &pRef : *pJSON)
- {
-- // PyList_SetItem 'steal' a reference so use PyBorrowedRef instead of PyNewRef
-+ // PyList_SetItem 'steals' a reference so use PyBorrowedRef instead of PyNewRef
- if (pRef.isArray() || pRef.isObject())
- {
- PyBorrowedRef pObj = JSONtoPython(&pRef);
-@@ -239,7 +245,7 @@ namespace Plugins {
- bool bRet = ParseJSon(sData, root);
- if ((!bRet) || (!root.isObject()))
- {
-- _log.Log(LOG_ERROR, "JSON Protocol: Parse Error on '%s'", sData.c_str());
-+ _log.Log(LOG_ERROR, "(%s) Parse Error on '%s'", __func__, sData.c_str());
- Py_RETURN_NONE;
- }
- else
-@@ -253,66 +259,77 @@ namespace Plugins {
- std::string CPluginProtocolJSON::PythontoJSON(PyObject* pObject)
- {
- std::string sJson;
-+ PyBorrowedRef pObj(pObject);
-
-- if (PyUnicode_Check(pObject))
-- {
-- sJson += '"' + std::string(PyUnicode_AsUTF8(pObject)) + '"';
-- }
-- else if (pObject->ob_type->tp_name == std::string("bool"))
-- {
-- sJson += (PyObject_IsTrue(pObject) ? "true" : "false");
-- }
-- else if (PyLong_Check(pObject))
-- {
-- sJson += std::to_string(PyLong_AsLong(pObject));
-- }
-- else if (PyBytes_Check(pObject))
-- {
-- sJson += '"' + std::string(PyBytes_AsString(pObject)) + '"';
-- }
-- else if (pObject->ob_type->tp_name == std::string("bytearray"))
-- {
-- sJson += '"' + std::string(PyByteArray_AsString(pObject)) + '"';
-- }
-- else if (pObject->ob_type->tp_name == std::string("float"))
-- {
-- sJson += std::to_string(PyFloat_AsDouble(pObject));
-- }
-- else if (PyDict_Check(pObject))
-+ if (pObj.IsDict())
- {
- sJson += "{ ";
- PyObject* key, * value;
- Py_ssize_t pos = 0;
-- while (PyDict_Next(pObject, &pos, &key, &value))
-+ while (PyDict_Next(pObj, &pos, &key, &value))
- {
- sJson += PythontoJSON(key) + ':' + PythontoJSON(value) + ',';
- }
- sJson[sJson.length() - 1] = '}';
- }
-- else if (PyList_Check(pObject))
-+ else if (pObj.IsList())
- {
- sJson += "[ ";
-- for (Py_ssize_t i = 0; i < PyList_Size(pObject); i++)
-+ for (Py_ssize_t i = 0; i < PyList_Size(pObj); i++)
- {
-- sJson += PythontoJSON(PyList_GetItem(pObject, i)) + ',';
-+ sJson += PythontoJSON(PyList_GetItem(pObj, i)) + ',';
- }
- sJson[sJson.length() - 1] = ']';
- }
-- else if (PyTuple_Check(pObject))
-+ else if (pObj.IsTuple())
- {
- sJson += "[ ";
-- for (Py_ssize_t i = 0; i < PyTuple_Size(pObject); i++)
-+ for (Py_ssize_t i = 0; i < PyTuple_Size(pObj); i++)
- {
-- sJson += PythontoJSON(PyTuple_GetItem(pObject, i)) + ',';
-+ sJson += PythontoJSON(PyTuple_GetItem(pObj, i)) + ',';
- }
- sJson[sJson.length() - 1] = ']';
- }
-+ else if (pObj.IsBool())
-+ {
-+ sJson += (PyObject_IsTrue(pObj) ? "true" : "false");
-+ }
-+ else if (pObj.IsLong())
-+ {
-+ sJson += std::to_string(PyLong_AsLong(pObj));
-+ }
-+ else if (pObj.IsFloat())
-+ {
-+ sJson += std::to_string(PyFloat_AsDouble(pObj));
-+ }
-+ else if (pObj.IsBytes())
-+ {
-+ sJson += '"' + std::string(PyBytes_AsString(pObj)) + '"';
-+ }
-+ else if (pObj.IsByteArray())
-+ {
-+ sJson += '"' + std::string(PyByteArray_AsString(pObj)) + '"';
-+ }
-+ else
-+ {
-+ // Try forcing a String conversion
-+ PyNewRef pStr = PyObject_Str(pObject);
-+ if (pStr)
-+ {
-+ sJson += '"' + std::string(PyUnicode_AsUTF8(pStr)) + '"';
-+ }
-+ else
-+ _log.Log(LOG_ERROR, "(%s) Unable to convert data type (%s) to string representation, ignored.", __func__, pObj.Type().c_str());
-+ }
-
- return sJson;
- }
-
- void CPluginProtocolJSON::ProcessInbound(const ReadEvent* Message)
- {
-+ CConnection* pConnection = Message->m_pConnection;
-+ CPlugin* pPlugin = pConnection->pPlugin;
-+
- //
- // Handles the cases where a read contains a partial message or multiple messages
- //
-@@ -332,13 +349,13 @@ namespace Plugins {
- bool bRet = ParseJSon(sData, root);
- if ((!bRet) || (!root.isObject()))
- {
-- _log.Log(LOG_ERROR, "JSON Protocol: Parse Error on '%s'", sData.c_str());
-- Message->m_pConnection->pPlugin->MessagePlugin(new onMessageCallback(Message->m_pConnection, sData));
-+ pPlugin->Log(LOG_ERROR, "(%s) Parse Error on '%s'", __func__, sData.c_str());
-+ pPlugin->MessagePlugin(new onMessageCallback(pConnection, sData));
- }
- else
- {
- PyObject* pMessage = JSONtoPython(&root);
-- Message->m_pConnection->pPlugin->MessagePlugin(new onMessageCallback(Message->m_pConnection, pMessage));
-+ pPlugin->MessagePlugin(new onMessageCallback(pConnection, pMessage));
- }
- sData.clear();
- }
-@@ -350,13 +367,13 @@ namespace Plugins {
- bool bRet = ParseJSon(sMessage, root);
- if ((!bRet) || (!root.isObject()))
- {
-- _log.Log(LOG_ERROR, "JSON Protocol: Parse Error on '%s'", sData.c_str());
-- Message->m_pConnection->pPlugin->MessagePlugin(new onMessageCallback(Message->m_pConnection, sMessage));
-+ pPlugin->Log(LOG_ERROR, "(%s) Parse Error on '%s'", __func__, sData.c_str());
-+ pPlugin->MessagePlugin(new onMessageCallback(pConnection, sMessage));
- }
- else
- {
- PyObject* pMessage = JSONtoPython(&root);
-- Message->m_pConnection->pPlugin->MessagePlugin(new onMessageCallback(Message->m_pConnection, pMessage));
-+ pPlugin->MessagePlugin(new onMessageCallback(pConnection, pMessage));
- }
- }
- }
-@@ -467,7 +484,7 @@ namespace Plugins {
- {
- PyObject* pListObj = pPrevObj;
- // First duplicate? Create a list and add previous value
-- if (!PyList_Check(pListObj))
-+ if (!pPrevObj.IsList())
- {
- pListObj = PyList_New(1);
- if (!pListObj)
-@@ -732,7 +749,7 @@ namespace Plugins {
- std::string sHttp;
-
- // Sanity check input
-- if (!WriteMessage->m_Object || !PyDict_Check(WriteMessage->m_Object))
-+ if (PyBorrowedRef(WriteMessage->m_Object).Type() != "dict")
- {
- _log.Log(LOG_ERROR, "(%s) HTTP Send parameter was not a dictionary, ignored. See Python Plugin wiki page for help.", __func__);
- return retVal;
-@@ -763,7 +780,7 @@ namespace Plugins {
- //
- // param1=value¶m2=other+value
-
-- if (!PyUnicode_Check(pVerb))
-+ if (!pVerb.IsString())
- {
- _log.Log(LOG_ERROR, "(%s) HTTP 'Verb' dictionary entry not a string, ignored. See Python Plugin wiki page for help.", __func__);
- return retVal;
-@@ -774,7 +791,7 @@ namespace Plugins {
-
- PyBorrowedRef pURL = PyDict_GetItemString(WriteMessage->m_Object, "URL");
- std::string sHttpURL = "/";
-- if (pURL && PyUnicode_Check(pURL))
-+ if (pURL.IsString())
- {
- sHttpURL = PyUnicode_AsUTF8(pURL);
- }
-@@ -840,7 +857,7 @@ namespace Plugins {
- // </body>
- // </html>
-
-- if (!PyUnicode_Check(pStatus))
-+ if (!pStatus.IsString())
- {
- _log.Log(LOG_ERROR, "(%s) HTTP 'Status' dictionary entry was not a string, ignored. See Python Plugin wiki page for help.", __func__);
- return retVal;
-@@ -886,53 +903,53 @@ namespace Plugins {
- // Did we get headers to send?
- if (pHeaders)
- {
-- if (PyDict_Check(pHeaders))
-+ if (pHeaders.IsDict())
- {
- PyObject* key, * value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(pHeaders, &pos, &key, &value))
- {
- std::string sKey = PyUnicode_AsUTF8(key);
-- if (PyUnicode_Check(value))
-+ PyBorrowedRef pValue(value);
-+ if (pValue.IsString())
- {
- std::string sValue = PyUnicode_AsUTF8(value);
- sHttp += sKey + ": " + sValue + "\r\n";
- }
-- else if (PyBytes_Check(value))
-+ else if (pValue.IsBytes())
- {
- const char* pBytes = PyBytes_AsString(value);
- sHttp += sKey + ": " + pBytes + "\r\n";
- }
-- else if (value->ob_type->tp_name == std::string("bytearray"))
-+ else if (pValue.IsByteArray())
- {
- const char* pByteArray = PyByteArray_AsString(value);
- sHttp += sKey + ": " + pByteArray + "\r\n";
- }
-- else if (PyList_Check(value))
-+ else if (pValue.IsList())
- {
-- PyObject* iterator = PyObject_GetIter(value);
-- PyObject* item;
-- while ((item = PyIter_Next(iterator)))
-+ PyNewRef iterator = PyObject_GetIter(value);
-+ PyObject* item;
-+ while (item = PyIter_Next(iterator))
- {
-- if (PyUnicode_Check(item))
-+ PyBorrowedRef pItem(item);
-+ if (pItem.IsString())
- {
- std::string sValue = PyUnicode_AsUTF8(item);
- sHttp += sKey + ": " + sValue + "\r\n";
- }
-- else if (PyBytes_Check(item))
-+ else if (pItem.IsBytes())
- {
- const char* pBytes = PyBytes_AsString(item);
- sHttp += sKey + ": " + pBytes + "\r\n";
- }
-- else if (item->ob_type->tp_name == std::string("bytearray"))
-+ else if (pItem.IsByteArray())
- {
- const char* pByteArray = PyByteArray_AsString(item);
- sHttp += sKey + ": " + pByteArray + "\r\n";
- }
- Py_DECREF(item);
- }
--
-- Py_DECREF(iterator);
- }
- }
- }
-@@ -949,11 +966,11 @@ namespace Plugins {
- if (!pLength && pData && !pChunk)
- {
- Py_ssize_t iLength = 0;
-- if (PyUnicode_Check(pData))
-+ if (pData.IsString())
- iLength = PyUnicode_GetLength(pData);
-- else if (pData->ob_type->tp_name == std::string("bytearray"))
-+ else if (pData.IsByteArray())
- iLength = PyByteArray_Size(pData);
-- else if (PyBytes_Check(pData))
-+ else if (pData.IsBytes())
- iLength = PyBytes_Size(pData);
- sHttp += "Content-Length: " + std::to_string(iLength) + "\r\n";
- }
-@@ -977,15 +994,12 @@ namespace Plugins {
- if (pChunk)
- {
- long lChunkLength = 0;
-- if (pData)
-- {
-- if (PyUnicode_Check(pData))
-- lChunkLength = PyUnicode_GetLength(pData);
-- else if (pData->ob_type->tp_name == std::string("bytearray"))
-- lChunkLength = PyByteArray_Size(pData);
-- else if (PyBytes_Check(pData))
-- lChunkLength = PyBytes_Size(pData);
-- }
-+ if (pData.IsString())
-+ lChunkLength = PyUnicode_GetLength(pData);
-+ else if (pData.IsByteArray())
-+ lChunkLength = PyByteArray_Size(pData);
-+ else if (pData.IsBytes())
-+ lChunkLength = PyBytes_Size(pData);
- std::stringstream stream;
- stream << std::hex << lChunkLength;
- sHttp += std::string(stream.str());
-@@ -993,13 +1007,13 @@ namespace Plugins {
- }
-
- // Append data if supplied (for POST) or Response
-- if (pData && PyUnicode_Check(pData))
-+ if (pData.IsString())
- {
- sHttp += PyUnicode_AsUTF8(pData);
- retVal.reserve(sHttp.length() + 2);
- retVal.assign(sHttp.c_str(), sHttp.c_str() + sHttp.length());
- }
-- else if (pData && (pData->ob_type->tp_name == std::string("bytearray")))
-+ else if (pData.IsByteArray())
- {
- retVal.reserve(sHttp.length() + PyByteArray_Size(pData) + 2);
- retVal.assign(sHttp.c_str(), sHttp.c_str() + sHttp.length());
-@@ -1010,7 +1024,7 @@ namespace Plugins {
- retVal.push_back(pByteArray[i]);
- }
- }
-- else if (pData && PyBytes_Check(pData))
-+ else if (pData.IsBytes())
- {
- retVal.reserve(sHttp.length() + PyBytes_Size(pData) + 2);
- retVal.assign(sHttp.c_str(), sHttp.c_str() + sHttp.length());
-@@ -1700,7 +1714,7 @@ namespace Plugins {
- std::vector<byte> retVal;
-
- // Sanity check input
-- if (!WriteMessage->m_Object || !PyDict_Check(WriteMessage->m_Object))
-+ if (!PyBorrowedRef(WriteMessage->m_Object).IsDict())
- {
- _log.Log(LOG_ERROR, "(%s) MQTT Send parameter was not a dictionary, ignored. See Python Plugin wiki page for help.", __func__);
- return retVal;
-@@ -1710,7 +1724,7 @@ namespace Plugins {
- PyBorrowedRef pVerb = PyDict_GetItemString(WriteMessage->m_Object, "Verb");
- if (pVerb)
- {
-- if (!PyUnicode_Check(pVerb))
-+ if (!pVerb.IsString())
- {
- _log.Log(LOG_ERROR, "(%s) MQTT 'Verb' dictionary entry not a string, ignored. See Python Plugin wiki page for help.", __func__);
- return retVal;
-@@ -1726,7 +1740,7 @@ namespace Plugins {
-
- // Client Identifier
- PyBorrowedRef pID = PyDict_GetItemString(WriteMessage->m_Object, "ID");
-- if (pID && PyUnicode_Check(pID))
-+ if (pID.IsString())
- {
- MQTTPushBackStringWLen(std::string(PyUnicode_AsUTF8(pID)), vPayload);
- }
-@@ -1735,7 +1749,7 @@ namespace Plugins {
-
- byte bCleanSession = 1;
- PyBorrowedRef pCleanSession = PyDict_GetItemString(WriteMessage->m_Object, "CleanSession");
-- if (pCleanSession && PyLong_Check(pCleanSession))
-+ if (pCleanSession.IsLong())
- {
- bCleanSession = (byte)PyLong_AsLong(pCleanSession);
- }
-@@ -1743,7 +1757,7 @@ namespace Plugins {
-
- // Will topic
- PyBorrowedRef pTopic = PyDict_GetItemString(WriteMessage->m_Object, "WillTopic");
-- if (pTopic && PyUnicode_Check(pTopic))
-+ if (pTopic.IsString())
- {
- MQTTPushBackStringWLen(std::string(PyUnicode_AsUTF8(pTopic)), vPayload);
- bControlFlags |= 4;
-@@ -1753,14 +1767,14 @@ namespace Plugins {
- if (bControlFlags & 4)
- {
- PyBorrowedRef pQoS = PyDict_GetItemString(WriteMessage->m_Object, "WillQoS");
-- if (pQoS && PyLong_Check(pQoS))
-+ if (pQoS.IsLong())
- {
- byte bQoS = (byte)PyLong_AsLong(pQoS);
- bControlFlags |= (bQoS & 3) << 3; // Set QoS flag
- }
-
- PyBorrowedRef pRetain = PyDict_GetItemString(WriteMessage->m_Object, "WillRetain");
-- if (pRetain && PyLong_Check(pRetain))
-+ if (pRetain.IsLong())
- {
- byte bRetain = (byte)PyLong_AsLong(pRetain);
- bControlFlags |= (bRetain & 1) << 5; // Set retain flag
-@@ -1770,11 +1784,11 @@ namespace Plugins {
- PyBorrowedRef pPayload = PyDict_GetItemString(WriteMessage->m_Object, "WillPayload");
- // Support both string and bytes
- //if (pPayload && PyByteArray_Check(pPayload)) // Gives linker error, why?
-- if (pPayload && pPayload->ob_type->tp_name == std::string("bytearray"))
-+ if (pPayload.IsByteArray())
- {
- sPayload = std::string(PyByteArray_AsString(pPayload), PyByteArray_Size(pPayload));
- }
-- else if (pPayload && PyUnicode_Check(pPayload))
-+ else if (pPayload.IsString())
- {
- sPayload = std::string(PyUnicode_AsUTF8(pPayload));
- }
-@@ -1786,7 +1800,7 @@ namespace Plugins {
- std::string Pass;
- PyObject* pModule = (PyObject*)WriteMessage->m_pConnection->pPlugin->PythonModule();
- PyNewRef pDict = PyObject_GetAttrString(pModule, "Parameters");
-- if (pDict)
-+ if (pDict.IsDict())
- {
- PyBorrowedRef pUser = PyDict_GetItemString(pDict, "Username");
- if (pUser) User = PyUnicode_AsUTF8(pUser);
-@@ -1829,7 +1843,7 @@ namespace Plugins {
- // Connect Reason Code
- pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "ReasonCode");
- byteValue = 0;
-- if (pDictEntry && PyLong_Check(pDictEntry))
-+ if (pDictEntry.IsLong())
- {
- byteValue = PyLong_AsLong(pDictEntry) & 0xFF;
- }
-@@ -1838,35 +1852,35 @@ namespace Plugins {
- // CONNACK Properties
- std::vector<byte> vProperties;
- pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "SessionExpiryInterval");
-- if (pDictEntry && PyLong_Check(pDictEntry))
-+ if (pDictEntry.IsLong())
- {
- vProperties.push_back(17);
- MQTTPushBackLong(PyLong_AsLong(pDictEntry), vProperties);
- }
-
- pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "MaximumQoS");
-- if (pDictEntry && PyLong_Check(pDictEntry))
-+ if (pDictEntry.IsLong())
- {
- vProperties.push_back(36);
- vProperties.push_back((byte)PyLong_AsLong(pDictEntry));
- }
-
- pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "RetainAvailable");
-- if (pDictEntry && PyLong_Check(pDictEntry))
-+ if (pDictEntry.IsLong())
- {
- vProperties.push_back(37);
- vProperties.push_back((byte)PyLong_AsLong(pDictEntry));
- }
-
- pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "MaximumPacketSize");
-- if (pDictEntry && PyLong_Check(pDictEntry))
-+ if (pDictEntry.IsLong())
- {
- vProperties.push_back(39);
- MQTTPushBackLong(PyLong_AsLong(pDictEntry), vProperties);
- }
-
- pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "AssignedClientID");
-- if (pDictEntry && (pDictEntry != Py_None))
-+ if (pDictEntry && !pDictEntry.IsNone())
- {
- PyNewRef pStr = PyObject_Str(pDictEntry);
- vProperties.push_back(18);
-@@ -1874,7 +1888,7 @@ namespace Plugins {
- }
-
- pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "ReasonString");
-- if (pDictEntry && (pDictEntry != Py_None))
-+ if (pDictEntry && !pDictEntry.IsNone())
- {
- PyNewRef pStr = PyObject_Str(pDictEntry);
- vProperties.push_back(26);
-@@ -1882,7 +1896,7 @@ namespace Plugins {
- }
-
- pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "ResponseInformation");
-- if (pDictEntry && (pDictEntry != Py_None))
-+ if (pDictEntry && !pDictEntry.IsNone())
- {
- PyNewRef pStr = PyObject_Str(pDictEntry);
- vProperties.push_back(18);
-@@ -1904,7 +1918,7 @@ namespace Plugins {
- // If supplied then use it otherwise create one
- PyBorrowedRef pID = PyDict_GetItemString(WriteMessage->m_Object, "PacketIdentifier");
- long iPacketIdentifier = 0;
-- if (pID && PyLong_Check(pID))
-+ if (pID.IsLong())
- {
- iPacketIdentifier = PyLong_AsLong(pID);
- }
-@@ -1913,25 +1927,25 @@ namespace Plugins {
-
- // Payload is list of topics and QoS numbers
- PyBorrowedRef pTopicList = PyDict_GetItemString(WriteMessage->m_Object, "Topics");
-- if (!pTopicList || !PyList_Check(pTopicList))
-+ if (!pTopicList.IsList())
- {
- _log.Log(LOG_ERROR, "(%s) MQTT Subscribe: No 'Topics' list present, nothing to subscribe to. See Python Plugin wiki page for help.", __func__);
- return retVal;
- }
- for (Py_ssize_t i = 0; i < PyList_Size(pTopicList); i++)
- {
-- PyObject* pTopicDict = PyList_GetItem(pTopicList, i);
-- if (!pTopicDict || !PyDict_Check(pTopicDict))
-+ PyBorrowedRef pTopicDict = PyList_GetItem(pTopicList, i);
-+ if (!pTopicDict.IsDict())
- {
- _log.Log(LOG_ERROR, "(%s) MQTT Subscribe: Topics list entry is not a dictionary (Topic, QoS), nothing to subscribe to. See Python Plugin wiki page for help.", __func__);
- return retVal;
- }
- PyBorrowedRef pTopic = PyDict_GetItemString(pTopicDict, "Topic");
-- if (pTopic && PyUnicode_Check(pTopic))
-+ if (pTopic.IsString())
- {
- MQTTPushBackStringWLen(std::string(PyUnicode_AsUTF8(pTopic)), vPayload);
- PyBorrowedRef pQoS = PyDict_GetItemString(pTopicDict, "QoS");
-- if (pQoS && PyLong_Check(pQoS))
-+ if (pQoS.IsLong())
- {
- vPayload.push_back((byte)PyLong_AsLong(pQoS));
- }
-@@ -1949,7 +1963,7 @@ namespace Plugins {
- // Variable Header
- PyBorrowedRef pID = PyDict_GetItemString(WriteMessage->m_Object, "PacketIdentifier");
- long iPacketIdentifier = 0;
-- if (pID && PyLong_Check(pID))
-+ if (pID.IsLong())
- {
- iPacketIdentifier = PyLong_AsLong(pID);
- MQTTPushBackNumber((int)iPacketIdentifier, vVariableHeader);
-@@ -1961,7 +1975,7 @@ namespace Plugins {
- }
-
- PyBorrowedRef pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "QoS");
-- if (pDictEntry && PyLong_Check(pDictEntry))
-+ if (pDictEntry.IsLong())
- {
- vPayload.push_back((byte)PyLong_AsLong(pDictEntry));
- }
-@@ -1978,7 +1992,7 @@ namespace Plugins {
- // Variable Header
- PyBorrowedRef pID = PyDict_GetItemString(WriteMessage->m_Object, "PacketIdentifier");
- long iPacketIdentifier = 0;
-- if (pID && PyLong_Check(pID))
-+ if (pID.IsLong())
- {
- iPacketIdentifier = PyLong_AsLong(pID);
- }
-@@ -1987,15 +2001,15 @@ namespace Plugins {
-
- // Payload is a Python list of topics
- PyBorrowedRef pTopicList = PyDict_GetItemString(WriteMessage->m_Object, "Topics");
-- if (!pTopicList || !PyList_Check(pTopicList))
-+ if (!pTopicList.IsList())
- {
- _log.Log(LOG_ERROR, "(%s) MQTT Subscribe: No 'Topics' list present, nothing to unsubscribe from. See Python Plugin wiki page for help.", __func__);
- return retVal;
- }
- for (Py_ssize_t i = 0; i < PyList_Size(pTopicList); i++)
- {
-- PyObject* pTopic = PyList_GetItem(pTopicList, i);
-- if (pTopic && PyUnicode_Check(pTopic))
-+ PyBorrowedRef pTopic = PyList_GetItem(pTopicList, i);
-+ if (pTopic.IsString())
- {
- MQTTPushBackStringWLen(std::string(PyUnicode_AsUTF8(pTopic)), vPayload);
- }
-@@ -2009,7 +2023,7 @@ namespace Plugins {
-
- // Fixed Header
- PyBorrowedRef pDUP = PyDict_GetItemString(WriteMessage->m_Object, "Duplicate");
-- if (pDUP && PyLong_Check(pDUP))
-+ if (pDUP.IsLong())
- {
- long bDUP = PyLong_AsLong(pDUP);
- if (bDUP) bByte0 |= 0x08; // Set duplicate flag
-@@ -2017,14 +2031,14 @@ namespace Plugins {
-
- PyBorrowedRef pQoS = PyDict_GetItemString(WriteMessage->m_Object, "QoS");
- long iQoS = 0;
-- if (pQoS && PyLong_Check(pQoS))
-+ if (pQoS.IsLong())
- {
- iQoS = PyLong_AsLong(pQoS);
- bByte0 |= ((iQoS & 3) << 1); // Set QoS flag
- }
-
- PyBorrowedRef pRetain = PyDict_GetItemString(WriteMessage->m_Object, "Retain");
-- if (pRetain && PyLong_Check(pRetain))
-+ if (pRetain.IsLong())
- {
- long bRetain = PyLong_AsLong(pRetain);
- bByte0 |= (bRetain & 1); // Set retain flag
-@@ -2032,7 +2046,7 @@ namespace Plugins {
-
- // Variable Header
- PyBorrowedRef pTopic = PyDict_GetItemString(WriteMessage->m_Object, "Topic");
-- if (pTopic && PyUnicode_Check(pTopic))
-+ if (pTopic && pTopic.IsString())
- {
- MQTTPushBackStringWLen(std::string(PyUnicode_AsUTF8(pTopic)), vVariableHeader);
- }
-@@ -2046,7 +2060,7 @@ namespace Plugins {
- if (iQoS)
- {
- long iPacketIdentifier = 0;
-- if (pID && PyLong_Check(pID))
-+ if (pID.IsLong())
- {
- iPacketIdentifier = PyLong_AsLong(pID);
- }
-@@ -2062,20 +2076,22 @@ namespace Plugins {
- PyBorrowedRef pPayload = PyDict_GetItemString(WriteMessage->m_Object, "Payload");
- // Support both string and bytes
- //if (pPayload && PyByteArray_Check(pPayload)) // Gives linker error, why?
-- if (pPayload) {
-- _log.Debug(DEBUG_NORM, "(%s) MQTT Publish: payload %p (%s)", __func__, (PyObject*)pPayload, pPayload->ob_type->tp_name);
-+ if (pPayload)
-+ {
-+ PyNewRef pName = PyObject_GetAttrString((PyObject*)pPayload->ob_type, "__name__");
-+ _log.Debug(DEBUG_NORM, "(%s) MQTT Publish: payload %p (%s)", __func__, (PyObject*)pPayload, ((std::string)pName).c_str());
- }
-- if (pPayload && pPayload->ob_type->tp_name == std::string("bytearray"))
-+ if (pPayload.IsByteArray())
- {
- std::string sPayload = std::string(PyByteArray_AsString(pPayload), PyByteArray_Size(pPayload));
- MQTTPushBackString(sPayload, vPayload);
- }
-- else if (pPayload && PyUnicode_Check(pPayload))
-+ else if (pPayload.IsString())
- {
- std::string sPayload = std::string(PyUnicode_AsUTF8(pPayload));
- MQTTPushBackString(sPayload, vPayload);
- }
-- else if (pPayload && PyLong_Check(pPayload))
-+ else if (pPayload.IsLong())
- {
- MQTTPushBackLong(PyLong_AsLong(pPayload), vPayload);
- }
-@@ -2086,7 +2102,7 @@ namespace Plugins {
- // Variable Header
- PyBorrowedRef pID = PyDict_GetItemString(WriteMessage->m_Object, "PacketIdentifier");
- long iPacketIdentifier = 0;
-- if (pID && PyLong_Check(pID))
-+ if (pID.IsLong())
- {
- iPacketIdentifier = PyLong_AsLong(pID);
- MQTTPushBackNumber((int)iPacketIdentifier, vVariableHeader);
-@@ -2104,7 +2120,7 @@ namespace Plugins {
- // Variable Header
- PyBorrowedRef pID = PyDict_GetItemString(WriteMessage->m_Object, "PacketIdentifier");
- long iPacketIdentifier = 0;
-- if (pID && PyLong_Check(pID))
-+ if (pID.IsLong())
- {
- iPacketIdentifier = PyLong_AsLong(pID);
- MQTTPushBackNumber((int)iPacketIdentifier, vVariableHeader);
-@@ -2117,7 +2133,7 @@ namespace Plugins {
-
- // Connect Reason Code
- PyBorrowedRef pDictEntry = PyDict_GetItemString(WriteMessage->m_Object, "ReasonCode");
-- if (pDictEntry && PyLong_Check(pDictEntry))
-+ if (pDictEntry.IsLong())
- {
- vVariableHeader.push_back((byte)PyLong_AsLong(pDictEntry));
- }
-@@ -2381,7 +2397,7 @@ namespace Plugins {
- // Parameters need to be in a dictionary.
- // if a 'URL' key is found message is assumed to be HTTP otherwise WebSocket is assumed
- //
-- if (!WriteMessage->m_Object || !PyDict_Check(WriteMessage->m_Object))
-+ if (!PyBorrowedRef(WriteMessage->m_Object).IsDict())
- {
- _log.Log(LOG_ERROR, "(%s) Dictionary parameter expected.", __func__);
- }
-@@ -2444,7 +2460,7 @@ namespace Plugins {
-
- if (pOperation)
- {
-- if (!PyUnicode_Check(pOperation))
-+ if (!pOperation.IsString())
- {
- _log.Log(LOG_ERROR, "(%s) Expected dictionary 'Operation' key to have a string value.", __func__);
- return retVal;
-@@ -2466,36 +2482,33 @@ namespace Plugins {
- }
-
- // If there is no specific OpCode then set it from the payload datatype
-- if (pPayload)
-+ if (pPayload.IsString())
- {
-- if (PyUnicode_Check(pPayload))
-- {
-- lPayloadLength = PyUnicode_GetLength(pPayload);
-- if (!iOpCode)
-- iOpCode = 0x01; // Text message
-- }
-- else if (PyBytes_Check(pPayload))
-- {
-- lPayloadLength = PyBytes_Size(pPayload);
-- if (!iOpCode)
-- iOpCode = 0x02; // Binary message
-- }
-- else if (pPayload->ob_type->tp_name == std::string("bytearray"))
-- {
-- lPayloadLength = PyByteArray_Size(pPayload);
-- if (!iOpCode)
-- iOpCode = 0x02; // Binary message
-- }
-+ lPayloadLength = PyUnicode_GetLength(pPayload);
-+ if (!iOpCode)
-+ iOpCode = 0x01; // Text message
-+ }
-+ else if (pPayload.IsBytes())
-+ {
-+ lPayloadLength = PyBytes_Size(pPayload);
-+ if (!iOpCode)
-+ iOpCode = 0x02; // Binary message
-+ }
-+ else if (pPayload.IsByteArray())
-+ {
-+ lPayloadLength = PyByteArray_Size(pPayload);
-+ if (!iOpCode)
-+ iOpCode = 0x02; // Binary message
- }
-
- if (pMask)
- {
-- if (PyLong_Check(pMask))
-+ if (pMask.IsLong())
- {
- lMaskingKey = PyLong_AsLong(pMask);
- bMaskBit = 0x80; // Set mask bit in header
- }
-- else if (PyUnicode_Check(pMask))
-+ else if (pMask.IsString())
- {
- std::string sMask = PyUnicode_AsUTF8(pMask);
- lMaskingKey = atoi(sMask.c_str());
-@@ -2503,7 +2516,7 @@ namespace Plugins {
- }
- else
- {
-- _log.Log(LOG_ERROR, "(%s) Invalid mask, expected number (integer or string).", __func__);
-+ _log.Log(LOG_ERROR, "(%s) Invalid mask, expected number (integer or string) but got '%s'.", __func__, pMask.Type().c_str());
- return retVal;
- }
- }
-@@ -2534,31 +2547,28 @@ namespace Plugins {
- retVal.push_back(lMaskingKey & 0xFF); // Encode mask
- }
-
-- if (pPayload)
-+ if (pPayload.IsString())
- {
-- if (PyUnicode_Check(pPayload))
-+ std::string sPayload = PyUnicode_AsUTF8(pPayload);
-+ for (int i = 0; i < lPayloadLength; i++)
- {
-- std::string sPayload = PyUnicode_AsUTF8(pPayload);
-- for (int i = 0; i < lPayloadLength; i++)
-- {
-- retVal.push_back(sPayload[i] ^ pbMask[i % 4]);
-- }
-+ retVal.push_back(sPayload[i] ^ pbMask[i % 4]);
- }
-- else if (PyBytes_Check(pPayload))
-+ }
-+ else if (pPayload.IsBytes())
-+ {
-+ byte *pByte = (byte *)PyBytes_AsString(pPayload);
-+ for (int i = 0; i < lPayloadLength; i++)
- {
-- byte *pByte = (byte *)PyBytes_AsString(pPayload);
-- for (int i = 0; i < lPayloadLength; i++)
-- {
-- retVal.push_back(pByte[i] ^ pbMask[i % 4]);
-- }
-+ retVal.push_back(pByte[i] ^ pbMask[i % 4]);
- }
-- else if (pPayload->ob_type->tp_name == std::string("bytearray"))
-+ }
-+ else if (pPayload.IsByteArray())
-+ {
-+ byte *pByte = (byte *)PyByteArray_AsString(pPayload);
-+ for (int i = 0; i < lPayloadLength; i++)
- {
-- byte *pByte = (byte *)PyByteArray_AsString(pPayload);
-- for (int i = 0; i < lPayloadLength; i++)
-- {
-- retVal.push_back(pByte[i] ^ pbMask[i % 4]);
-- }
-+ retVal.push_back(pByte[i] ^ pbMask[i % 4]);
- }
- }
- }
---- a/hardware/plugins/PluginTransports.cpp
-+++ b/hardware/plugins/PluginTransports.cpp
-@@ -15,6 +15,8 @@
-
- namespace Plugins {
-
-+ extern PyTypeObject* CConnectionType;
-+
- void CPluginTransport::configureTimeout()
- {
- if (m_pConnection->Timeout)
-@@ -198,8 +200,6 @@ namespace Plugins {
- {
- try
- {
-- PyType_Ready(&CConnectionType);
--
- if (!m_Socket)
- {
- if (!m_Acceptor)
-@@ -239,8 +239,21 @@ namespace Plugins {
- std::string sAddress = remote_ep.address().to_string();
- std::string sPort = std::to_string(remote_ep.port());
-
-- CConnection *pConnection
-- = (CConnection *)CConnection_new(&CConnectionType, (PyObject *)nullptr, (PyObject *)nullptr);
-+ PyNewRef nrArgList = Py_BuildValue("(sssss)",
-+ std::string(sAddress+":"+sPort).c_str(),
-+ PyUnicode_AsUTF8(((CConnection*)m_pConnection)->Transport),
-+ PyUnicode_AsUTF8(((CConnection*)m_pConnection)->Protocol),
-+ sAddress.c_str(),
-+ sPort.c_str());
-+ if (!nrArgList)
-+ {
-+ pPlugin->Log(LOG_ERROR, "Building connection argument list failed for TCP %s:%s.", sAddress.c_str(), sPort.c_str());
-+ }
-+ CConnection* pConnection = (CConnection*)PyObject_CallObject((PyObject*)CConnectionType, nrArgList);
-+ if (!pConnection)
-+ {
-+ pPlugin->Log(LOG_ERROR, "Connection object creation failed for TCP %s:%s.", sAddress.c_str(), sPort.c_str());
-+ }
- CPluginTransportTCP* pTcpTransport = new CPluginTransportTCP(m_HwdID, pConnection, sAddress, sPort);
- Py_DECREF(pConnection);
-
-@@ -252,20 +265,10 @@ namespace Plugins {
-
- // Configure Python Connection object
- pConnection->pTransport = pTcpTransport;
-- Py_XDECREF(pConnection->Name);
-- pConnection->Name = PyUnicode_FromString(std::string(sAddress+":"+sPort).c_str());
-- Py_XDECREF(pConnection->Address);
-- pConnection->Address = PyUnicode_FromString(sAddress.c_str());
-- Py_XDECREF(pConnection->Port);
-- pConnection->Port = PyUnicode_FromString(sPort.c_str());
-
- Py_XDECREF(pConnection->Parent);
- pConnection->Parent = (PyObject*)m_pConnection;
- Py_INCREF(m_pConnection);
-- pConnection->Transport = ((CConnection*)m_pConnection)->Transport;
-- Py_INCREF(pConnection->Transport);
-- pConnection->Protocol = ((CConnection*)m_pConnection)->Protocol;
-- Py_INCREF(pConnection->Protocol);
- pConnection->Target = ((CConnection *)m_pConnection)->Target;
- if (pConnection->Target)
- Py_INCREF(pConnection->Target);
-@@ -626,8 +629,6 @@ namespace Plugins {
- {
- try
- {
-- PyType_Ready(&CConnectionType);
--
- if (!m_Socket)
- {
- boost::system::error_code ec;
-@@ -680,21 +681,22 @@ namespace Plugins {
- std::string sAddress = m_remote_endpoint.address().to_string();
- std::string sPort = std::to_string(m_remote_endpoint.port());
-
-- CConnection *pConnection
-- = (CConnection *)CConnection_new(&CConnectionType, (PyObject *)nullptr, (PyObject *)nullptr);
-+ PyNewRef nrArgList = Py_BuildValue("(sssss)",
-+ PyUnicode_AsUTF8(((CConnection*)m_pConnection)->Name),
-+ PyUnicode_AsUTF8(((CConnection*)m_pConnection)->Transport),
-+ PyUnicode_AsUTF8(((CConnection*)m_pConnection)->Protocol),
-+ sAddress.c_str(),
-+ sPort.c_str());
-+ if (!nrArgList)
-+ {
-+ pPlugin->Log(LOG_ERROR, "Building connection argument list failed for UDP %s:%s.", sAddress.c_str(), sPort.c_str());
-+ }
-+ CConnection* pConnection = (CConnection*)PyObject_CallObject((PyObject*)CConnectionType, nrArgList);
-+ if (!pConnection)
-+ {
-+ pPlugin->Log(LOG_ERROR, "Connection object creation failed for UDP %s:%s.", sAddress.c_str(), sPort.c_str());
-+ }
-
-- // Configure temporary Python Connection object
-- Py_XDECREF(pConnection->Name);
-- pConnection->Name = ((CConnection*)m_pConnection)->Name;
-- Py_INCREF(pConnection->Name);
-- Py_XDECREF(pConnection->Address);
-- pConnection->Address = PyUnicode_FromString(sAddress.c_str());
-- Py_XDECREF(pConnection->Port);
-- pConnection->Port = PyUnicode_FromString(sPort.c_str());
-- pConnection->Transport = ((CConnection*)m_pConnection)->Transport;
-- Py_INCREF(pConnection->Transport);
-- pConnection->Protocol = ((CConnection*)m_pConnection)->Protocol;
-- Py_INCREF(pConnection->Protocol);
- pConnection->Target = ((CConnection *)m_pConnection)->Target;
- if (pConnection->Target)
- Py_INCREF(pConnection->Target);
---- a/hardware/plugins/Plugins.cpp
-+++ b/hardware/plugins/Plugins.cpp
-@@ -5,6 +5,8 @@
- //
- #ifdef ENABLE_PYTHON
-
-+#include "../../main/Helper.h"
-+
- #include "Plugins.h"
- #include "PluginMessages.h"
- #include "PluginProtocols.h"
-@@ -41,44 +43,22 @@ extern MainWorker m_mainworker;
-
- namespace Plugins
- {
-- std::mutex AccessPython::PythonMutex;
-- volatile bool AccessPython::m_bHasThreadState = false;
-+ extern PyTypeObject* CDeviceType;
-+ extern PyTypeObject* CConnectionType;
-+ extern PyTypeObject* CImageType;
-
-- AccessPython::AccessPython(CPlugin* pPlugin, const char* sWhat) : m_Python(NULL)
-+ AccessPython::AccessPython(CPlugin* pPlugin, const char* sWhat)
- {
- m_pPlugin = pPlugin;
- m_Text = sWhat;
-
-- m_Lock = new std::unique_lock<std::mutex>(PythonMutex, std::defer_lock);
-- if (!m_Lock->try_lock())
-- {
-- if (m_pPlugin)
-- {
-- if (m_pPlugin->m_bDebug & PDM_LOCKING)
-- {
-- _log.Log(LOG_NORM, "(%s) Requesting lock for '%s', waiting...", m_pPlugin->m_Name.c_str(), m_Text);
-- }
-- }
-- else _log.Log(LOG_NORM, "Python lock requested for '%s' in use, will wait.", m_Text);
-- m_Lock->lock();
-- }
--
-- if (pPlugin)
-+ if (m_pPlugin)
- {
-- if (pPlugin->m_bDebug & PDM_LOCKING)
-- {
-- _log.Log(LOG_NORM, "(%s) Acquiring lock for '%s'", pPlugin->m_Name.c_str(), m_Text);
-- }
-- m_Python = pPlugin->PythonInterpreter();
-- if (m_Python)
-+ if (m_pPlugin->m_bDebug & PDM_LOCKING)
- {
-- PyEval_RestoreThread(m_Python);
-- m_bHasThreadState = true;
-- }
-- else
-- {
-- _log.Log(LOG_ERROR, "Attempt to aquire the GIL with NULL Interpreter details.");
-+ m_pPlugin->Log(LOG_NORM, "Acquiring GIL for '%s'", m_Text.c_str());
- }
-+ m_pPlugin->RestoreThread();
- }
- else
- {
-@@ -88,215 +68,39 @@ namespace Plugins
-
- AccessPython::~AccessPython()
- {
-- if (m_Python && m_pPlugin)
-+ if (m_pPlugin)
- {
- if (PyErr_Occurred())
- {
-- _log.Log(LOG_NORM, "(%s) Python error was set during unlock for '%s'", m_pPlugin->m_Name.c_str(), m_Text);
-+ m_pPlugin->Log(LOG_NORM, "Python error was set during unlock for '%s'", m_Text.c_str());
- m_pPlugin->LogPythonException();
- PyErr_Clear();
- }
--
-- m_bHasThreadState = false;
-- if (m_pPlugin->PythonInterpreter() && !PyEval_SaveThread())
-- {
-- _log.Log(LOG_ERROR, "(%s) Python Save state returned NULL value for '%s'", m_pPlugin->m_Name.c_str(), m_Text);
-- }
-- }
-- if (m_Lock)
-- {
-- if (m_pPlugin && m_pPlugin->m_bDebug & PDM_LOCKING)
-- {
-- _log.Log(LOG_NORM, "(%s) Releasing lock for '%s'", m_pPlugin->m_Name.c_str(), m_Text);
-- }
-- delete m_Lock;
-- }
-- }
--
-- void LogPythonException(CPlugin *pPlugin, const std::string &sHandler)
-- {
-- PyTracebackObject *pTraceback;
-- PyNewRef pExcept;
-- PyNewRef pValue;
-- PyTypeObject *TypeName;
-- PyBytesObject *pErrBytes = nullptr;
-- const char *pTypeText = nullptr;
-- std::string Name = "Unknown";
--
-- if (pPlugin)
-- Name = pPlugin->m_Name;
--
-- PyErr_Fetch(&pExcept, &pValue, (PyObject **)&pTraceback);
--
-- if (pExcept)
-- {
-- TypeName = (PyTypeObject *)pExcept;
-- pTypeText = TypeName->tp_name;
-- }
-- if (pValue)
-- {
-- pErrBytes = (PyBytesObject *)PyUnicode_AsASCIIString(pValue);
-- }
-- if (pTypeText && pErrBytes)
-- {
-- if (pPlugin)
-- pPlugin->Log(LOG_ERROR, "'%s' failed '%s':'%s'.", sHandler.c_str(), pTypeText, pErrBytes->ob_sval);
-- else
-- _log.Log(LOG_ERROR, "'%s' failed '%s':'%s'.", sHandler.c_str(), pTypeText, pErrBytes->ob_sval);
-- }
-- if (pTypeText && !pErrBytes)
-- {
-- if (pPlugin)
-- pPlugin->Log(LOG_ERROR, "'%s' failed '%s'.", sHandler.c_str(), pTypeText);
-- else
-- _log.Log(LOG_ERROR, "'%s' failed '%s'.", sHandler.c_str(), pTypeText);
-- }
-- if (!pTypeText && pErrBytes)
-- {
-- if (pPlugin)
-- pPlugin->Log(LOG_ERROR, "'%s' failed '%s'.", sHandler.c_str(), pErrBytes->ob_sval);
-- else
-- _log.Log(LOG_ERROR, "'%s' failed '%s'.", sHandler.c_str(), pErrBytes->ob_sval);
-- }
-- if (!pTypeText && !pErrBytes)
-- {
-- if (pPlugin)
-- pPlugin->Log(LOG_ERROR, "'%s' failed, unable to determine error.", sHandler.c_str());
-- else
-- _log.Log(LOG_ERROR, "'%s' failed, unable to determine error.", sHandler.c_str());
-- }
-- if (pErrBytes)
-- Py_XDECREF(pErrBytes);
--
-- // Log a stack trace if there is one
-- if (pPlugin && pTraceback)
-- pPlugin->LogTraceback(pTraceback);
--
-- if (!pExcept && !pValue && !pTraceback)
-- {
-- if (pPlugin)
-- pPlugin->Log(LOG_ERROR, "Call to message handler '%s' failed, unable to decode exception.", sHandler.c_str());
-- else
-- _log.Log(LOG_ERROR, "Call to message handler '%s' failed, unable to decode exception.", sHandler.c_str());
-- }
--
-- if (pTraceback)
-- Py_XDECREF(pTraceback);
-- }
--
-- int PyDomoticz_ProfileFunc(PyObject *self, PyFrameObject *frame, int what, PyObject *arg)
-- {
-- module_state *pModState = CPlugin::FindModule();
-- if (!pModState)
-- {
-- return 0;
-- }
-- else if (!pModState->pPlugin)
-- {
-- _log.Log(LOG_ERROR, "CPlugin:%s, illegal operation, Plugin has not started yet.", __func__);
-- }
-- else
-- {
-- int lineno = PyFrame_GetLineNumber(frame);
-- std::string sFuncName = "Unknown";
-- PyCodeObject *pCode = frame->f_code;
-- if (pCode && pCode->co_filename)
-- {
-- sFuncName = (std::string)PyBorrowedRef(pCode->co_filename);
-- }
-- if (pCode && pCode->co_name)
-- {
-- if (!sFuncName.empty())
-- sFuncName += "\\";
-- sFuncName += (std::string)PyBorrowedRef(pCode->co_name);
-- }
--
-- switch (what)
-- {
-- case PyTrace_CALL:
-- pModState->pPlugin->Log(LOG_NORM, "Calling function at line %d in '%s'", lineno, sFuncName.c_str());
-- break;
-- case PyTrace_RETURN:
-- pModState->pPlugin->Log(LOG_NORM, "Returning from line %d in '%s'", lineno, sFuncName.c_str());
-- break;
-- case PyTrace_EXCEPTION:
-- pModState->pPlugin->Log(LOG_NORM, "Exception at line %d in '%s'", lineno, sFuncName.c_str());
-- break;
-- }
-- }
--
-- return 0;
-- }
--
-- int PyDomoticz_TraceFunc(PyObject *self, PyFrameObject *frame, int what, PyObject *arg)
-- {
-- module_state *pModState = CPlugin::FindModule();
-- if (!pModState)
-- {
-- return 0;
-- }
-- else if (!pModState->pPlugin)
-- {
-- _log.Log(LOG_ERROR, "CPlugin:%s, illegal operation, Plugin has not started yet.", __func__);
-- }
-- else
-- {
-- int lineno = PyFrame_GetLineNumber(frame);
-- std::string sFuncName = "Unknown";
-- PyCodeObject *pCode = frame->f_code;
-- if (pCode && pCode->co_filename)
-- {
-- sFuncName = (std::string)PyBorrowedRef(pCode->co_filename);
-- }
-- if (pCode && pCode->co_name)
-- {
-- if (!sFuncName.empty())
-- sFuncName += "\\";
-- sFuncName += (std::string)PyBorrowedRef(pCode->co_name);
-- }
--
-- switch (what)
-- {
-- case PyTrace_CALL:
-- pModState->pPlugin->Log(LOG_NORM, "Calling function at line %d in '%s'", lineno, sFuncName.c_str());
-- break;
-- case PyTrace_LINE:
-- pModState->pPlugin->Log(LOG_NORM, "Executing line %d in '%s'", lineno, sFuncName.c_str());
-- break;
-- case PyTrace_EXCEPTION:
-- pModState->pPlugin->Log(LOG_NORM, "Exception at line %d in '%s'", lineno, sFuncName.c_str());
-- break;
-- }
-+ m_pPlugin->ReleaseThread();
- }
--
-- return 0;
- }
-
- static PyObject *PyDomoticz_Debug(PyObject *self, PyObject *args)
- {
-- module_state *pModState = CPlugin::FindModule();
-- if (!pModState)
-+ CPlugin* pPlugin = CPlugin::FindPlugin();
-+ if (!pPlugin)
- {
-- Py_RETURN_NONE;
-- }
-- else if (!pModState->pPlugin)
-- {
-- _log.Log(LOG_ERROR, "CPlugin:%s, illegal operation, Plugin has not started yet.", __func__);
-+ _log.Log(LOG_ERROR, "%s, illegal operation, Plugin has not started yet.", __func__);
- }
- else
- {
-- if (pModState->pPlugin->m_bDebug & PDM_PYTHON)
-+ if (pPlugin->m_bDebug & PDM_PYTHON)
- {
- char *msg;
- if (!PyArg_ParseTuple(args, "s", &msg))
- {
- // TODO: Dump data to aid debugging
-- pModState->pPlugin->Log(LOG_ERROR, "PyDomoticz_Debug failed to parse parameters: string expected.");
-- LogPythonException(pModState->pPlugin, std::string(__func__));
-+ pPlugin->Log(LOG_ERROR, "%s failed to parse parameters: string expected.", __func__);
-+ pPlugin->LogPythonException(std::string(__func__));
- }
- else
- {
-- pModState->pPlugin->Log(LOG_NORM, (std::string)msg);
-+ pPlugin->Log(LOG_NORM, (std::string)msg);
- }
- }
- }
-@@ -306,12 +110,8 @@ namespace Plugins
-
- static PyObject *PyDomoticz_Log(PyObject *self, PyObject *args)
- {
-- module_state *pModState = CPlugin::FindModule();
-- if (!pModState)
-- {
-- Py_RETURN_NONE;
-- }
-- else if (!pModState->pPlugin)
-+ CPlugin* pPlugin = CPlugin::FindPlugin();
-+ if (!pPlugin)
- {
- _log.Log(LOG_ERROR, "CPlugin:%s, illegal operation, Plugin has not started yet.", __func__);
- }
-@@ -320,12 +120,12 @@ namespace Plugins
- char *msg;
- if (!PyArg_ParseTuple(args, "s", &msg))
- {
-- pModState->pPlugin->Log(LOG_ERROR, "PyDomoticz_Log failed to parse parameters: string expected.");
-- LogPythonException(pModState->pPlugin, std::string(__func__));
-+ pPlugin->Log(LOG_ERROR, "%s failed to parse parameters: string expected.", __func__);
-+ pPlugin->LogPythonException(std::string(__func__));
- }
- else
- {
-- pModState->pPlugin->Log(LOG_NORM, (std::string)msg);
-+ pPlugin->Log(LOG_NORM, (std::string)msg);
- }
- }
-
-@@ -334,26 +134,22 @@ namespace Plugins
-
- static PyObject *PyDomoticz_Status(PyObject *self, PyObject *args)
- {
-- module_state *pModState = CPlugin::FindModule();
-- if (!pModState)
-+ CPlugin* pPlugin = CPlugin::FindPlugin();
-+ if (!pPlugin)
- {
-- Py_RETURN_NONE;
-- }
-- else if (!pModState->pPlugin)
-- {
-- _log.Log(LOG_ERROR, "CPlugin:%s, illegal operation, Plugin has not started yet.", __func__);
-+ _log.Log(LOG_ERROR, "%s, illegal operation, Plugin has not started yet.", __func__);
- }
- else
- {
- char *msg;
- if (!PyArg_ParseTuple(args, "s", &msg))
- {
-- pModState->pPlugin->Log(LOG_ERROR, "%s failed to parse parameters: string expected.", std::string(__func__).c_str());
-- LogPythonException(pModState->pPlugin, std::string(__func__));
-+ pPlugin->Log(LOG_ERROR, "%s failed to parse parameters: string expected.", __func__);
-+ pPlugin->LogPythonException(std::string(__func__));
- }
- else
- {
-- pModState->pPlugin->Log(LOG_STATUS, (std::string)msg);
-+ pPlugin->Log(LOG_STATUS, (std::string)msg);
- }
- }
-
-@@ -362,14 +158,10 @@ namespace Plugins
-
- static PyObject *PyDomoticz_Error(PyObject *self, PyObject *args)
- {
-- module_state *pModState = CPlugin::FindModule();
-- if (!pModState)
-- {
-- Py_RETURN_NONE;
-- }
-- else if (!pModState->pPlugin)
-+ CPlugin* pPlugin = CPlugin::FindPlugin();
-+ if (!pPlugin)
- {
-- _log.Log(LOG_ERROR, "CPlugin:%s, illegal operation, Plugin has not started yet.", __func__);
-+ _log.Log(LOG_ERROR, "%s, illegal operation, Plugin has not started yet.", __func__);
- }
- else
- {
-@@ -377,12 +169,12 @@ namespace Plugins
- if ((PyTuple_Size(args) != 1) || !PyArg_ParseTuple(args, "s", &msg))
- {
- // TODO: Dump data to aid debugging
-- pModState->pPlugin->Log(LOG_ERROR, "PyDomoticz_Error failed to parse parameters: string expected.");
-- LogPythonException(pModState->pPlugin, std::string(__func__));
-+ pPlugin->Log(LOG_ERROR, "%s failed to parse parameters: string expected.", __func__);
-+ pPlugin->LogPythonException(std::string(__func__));
- }
- else
- {
-- pModState->pPlugin->Log(LOG_ERROR, (std::string)msg);
-+ pPlugin->Log(LOG_ERROR, (std::string)msg);
- }
- }
-
-@@ -406,7 +198,7 @@ namespace Plugins
- if (!PyArg_ParseTuple(args, "i", &type))
- {
- pModState->pPlugin->Log(LOG_ERROR, "Failed to parse parameters, integer expected.");
-- LogPythonException(pModState->pPlugin, std::string(__func__));
-+ pModState->pPlugin->LogPythonException(std::string(__func__));
- }
- else
- {
-@@ -440,12 +232,12 @@ namespace Plugins
- else
- {
- iPollinterval = pModState->pPlugin->PollInterval(0);
-- if (PyTuple_Check(args) && PyTuple_Size(args))
-+ if (PyBorrowedRef(args).IsTuple() && PyTuple_Size(args))
- {
- if (!PyArg_ParseTuple(args, "i", &iPollinterval))
- {
- pModState->pPlugin->Log(LOG_ERROR, "failed to parse parameters, integer expected.");
-- LogPythonException(pModState->pPlugin, std::string(__func__));
-+ pModState->pPlugin->LogPythonException(std::string(__func__));
- }
- else
- {
-@@ -475,7 +267,7 @@ namespace Plugins
- if (!PyArg_ParseTuple(args, "s", &szNotifier))
- {
- pModState->pPlugin->Log(LOG_ERROR, "Failed to parse parameters, Notifier Name expected.");
-- LogPythonException(pModState->pPlugin, std::string(__func__));
-+ pModState->pPlugin->LogPythonException(std::string(__func__));
- }
- else
- {
-@@ -508,28 +300,7 @@ namespace Plugins
- }
- else
- {
-- int bTrace = 0;
-- if (!PyArg_ParseTuple(args, "p", &bTrace))
-- {
-- pModState->pPlugin->Log(LOG_ERROR, "Failed to parse parameter, True/False expected.");
-- LogPythonException(pModState->pPlugin, std::string(__func__));
-- }
-- else
-- {
-- pModState->pPlugin->m_bTracing = (bool)bTrace;
-- pModState->pPlugin->Log(LOG_NORM, "Low level Python tracing %s.", (pModState->pPlugin->m_bTracing ? "ENABLED" : "DISABLED"));
--
-- if (pModState->pPlugin->m_bTracing)
-- {
-- PyEval_SetProfile(PyDomoticz_ProfileFunc, self);
-- PyEval_SetTrace(PyDomoticz_TraceFunc, self);
-- }
-- else
-- {
-- PyEval_SetProfile(nullptr, nullptr);
-- PyEval_SetTrace(nullptr, nullptr);
-- }
-- }
-+ pModState->pPlugin->Log(LOG_ERROR, "CPlugin:%s, Low level trace functions have been removed.", __func__);
- }
-
- Py_RETURN_NONE;
-@@ -554,7 +325,7 @@ namespace Plugins
- if (PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &pNewConfig))
- {
- // Python object supplied if it is not a dictionary
-- if (!PyDict_Check(pNewConfig))
-+ if (!PyBorrowedRef(pNewConfig).IsDict())
- {
- pModState->pPlugin->Log(LOG_ERROR, "CPlugin:%s, Function expects no parameter or a Dictionary.", __func__);
- Py_RETURN_NONE;
-@@ -603,46 +374,26 @@ namespace Plugins
- {
- if (pDeviceClass)
- {
-- PyTypeObject *pBaseClass = pDeviceClass->tp_base;
-- while (pBaseClass)
-+ if (!PyType_IsSubtype(pDeviceClass, pModState->pDeviceClass))
- {
-- if (pBaseClass->tp_name == pModState->pDeviceClass->tp_name)
-- {
-- //_log.Log((_eLogLevel)LOG_NORM, "Class '%s' registered to override '%s'.", pDeviceClass->tp_name, pModState->pDeviceClass->tp_name);
-- pModState->pDeviceClass = pDeviceClass;
-- break;
-- }
-- pBaseClass = pBaseClass->tp_base;
-+ pModState->pPlugin->Log(LOG_ERROR, "Device class registration failed, Supplied class is not derived from 'DomoticzEx.Device'");
- }
-- if (pDeviceClass->tp_name != pModState->pDeviceClass->tp_name)
-+ else
- {
-- pModState->pPlugin->Log(LOG_ERROR, "Class '%s' registration failed, Device is not derived from '%s'", pDeviceClass->tp_name, pModState->pDeviceClass->tp_name);
-+ pModState->pDeviceClass = pDeviceClass;
-+ PyType_Ready(pModState->pDeviceClass);
- }
- }
- if (pUnitClass)
- {
-- if (pModState->pUnitClass)
-+ if (!PyType_IsSubtype(pUnitClass, pModState->pUnitClass))
- {
-- PyTypeObject *pBaseClass = pUnitClass->tp_base;
-- while (pBaseClass)
-- {
-- if (pBaseClass->tp_name == pModState->pUnitClass->tp_name)
-- {
-- //_log.Log((_eLogLevel)LOG_NORM, "Class '%s' registered to override '%s'.", pDeviceClass->tp_name, pModState->pUnitClass->tp_name);
-- pModState->pUnitClass = pUnitClass;
-- break;
-- }
-- pBaseClass = pBaseClass->tp_base;
-- }
-- if (pUnitClass->tp_name != pModState->pUnitClass->tp_name)
-- {
-- pModState->pPlugin->Log(LOG_ERROR, "Class '%s' registration failed, Unit is not derived from '%s'", pUnitClass->tp_name,
-- pModState->pDeviceClass->tp_name);
-- }
-+ pModState->pPlugin->Log(LOG_ERROR, "Unit class registration failed, Supplied class is not derived from 'DomoticzEx.Unit'");
- }
- else
- {
-- pModState->pPlugin->Log(LOG_ERROR, "Class '%s' registration failed, imported Domoticz module does not support Unit objects", pUnitClass->tp_name);
-+ pModState->pUnitClass = pUnitClass;
-+ PyType_Ready(pModState->pUnitClass);
- }
- }
- }
-@@ -669,12 +420,12 @@ namespace Plugins
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &pTarget))
- {
- pModState->pPlugin->Log(LOG_ERROR, "%s failed to parse parameters: Object expected (Optional).", __func__);
-- LogPythonException(pModState->pPlugin, std::string(__func__));
-+ pModState->pPlugin->LogPythonException(std::string(__func__));
- }
- else
- {
- PyNewRef pLocals = PyObject_Dir(pModState->lastCallback);
-- if (PyList_Check(pLocals)) // && PyIter_Check(pLocals)) // Check fails but iteration works??!?
-+ if (pLocals.IsList()) // && PyIter_Check(pLocals)) // Check fails but iteration works??!?
- {
- pModState->pPlugin->Log(LOG_NORM, "Context dump:");
- PyNewRef pIter = PyObject_GetIter(pLocals);
-@@ -702,7 +453,7 @@ namespace Plugins
- }
- }
- PyBorrowedRef pLocalVars = PyEval_GetLocals();
-- if (PyDict_Check(pLocalVars))
-+ if (pLocalVars.IsDict())
- {
- pModState->pPlugin->Log(LOG_NORM, "Locals dump:");
- PyBorrowedRef key;
-@@ -717,7 +468,7 @@ namespace Plugins
- }
- }
- PyBorrowedRef pGlobalVars = PyEval_GetGlobals();
-- if (PyDict_Check(pGlobalVars))
-+ if (pGlobalVars.IsDict())
- {
- pModState->pPlugin->Log(LOG_NORM, "Globals dump:");
- PyBorrowedRef key;
-@@ -753,6 +504,30 @@ namespace Plugins
- { "Dump", (PyCFunction)PyDomoticz_Dump, METH_VARARGS | METH_KEYWORDS, "Dump string values of an object or all locals to the log." },
- { nullptr, nullptr, 0, nullptr } };
-
-+ PyType_Slot ConnectionSlots[] = {
-+ { Py_tp_doc, (void*)"Domoticz Connection" },
-+ { Py_tp_new, (void*)CConnection_new },
-+ { Py_tp_init, (void*)CConnection_init },
-+ { Py_tp_dealloc, (void*)CConnection_dealloc },
-+ { Py_tp_members, CConnection_members },
-+ { Py_tp_methods, CConnection_methods },
-+ { Py_tp_str, (void*)CConnection_str },
-+ { 0 },
-+ };
-+ PyType_Spec ConnectionSpec = { "Domoticz.Connection", sizeof(CConnection), 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, ConnectionSlots };
-+
-+ PyType_Slot ImageSlots[] = {
-+ { Py_tp_doc, (void*)"Domoticz Image" },
-+ { Py_tp_new, (void*)CImage_new },
-+ { Py_tp_init, (void*)CImage_init },
-+ { Py_tp_dealloc, (void*)CImage_dealloc },
-+ { Py_tp_members, CImage_members },
-+ { Py_tp_methods, CImage_methods },
-+ { Py_tp_str, (void*)CImage_str },
-+ { 0 },
-+ };
-+ PyType_Spec ImageSpec = { "Domoticz.Image", sizeof(CImage), 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, ImageSlots };
-+
- static int DomoticzTraverse(PyObject *m, visitproc visit, void *arg)
- {
- Py_VISIT(GETSTATE(m)->error);
-@@ -769,37 +544,46 @@ namespace Plugins
-
- PyMODINIT_FUNC PyInit_Domoticz(void)
- {
--
- // This is called during the import of the plugin module
- // triggered by the "import Domoticz" statement
- PyObject *pModule = PyModule_Create2(&DomoticzModuleDef, PYTHON_API_VERSION);
- module_state *pModState = ((struct module_state *)PyModule_GetState(pModule));
-
-- if (PyType_Ready(&CDeviceType) < 0)
-+ if (!CDeviceType)
- {
-- _log.Log(LOG_ERROR, "%s, Device Type not ready.", __func__);
-- return pModule;
-+ PyType_Slot DeviceSlots[] = {
-+ { Py_tp_doc, (void*)"Domoticz Device" },
-+ { Py_tp_new, (void*)CDevice_new },
-+ { Py_tp_init, (void*)CDevice_init },
-+ { Py_tp_dealloc, (void*)CDevice_dealloc },
-+ { Py_tp_members, CDevice_members },
-+ { Py_tp_methods, CDevice_methods },
-+ { Py_tp_str, (void*)CDevice_str },
-+ { 0 },
-+ };
-+ PyType_Spec DeviceSpec = { "Domoticz.Device", sizeof(CDevice), 0,
-+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, DeviceSlots };
-+
-+ CDeviceType = (PyTypeObject*)PyType_FromSpec(&DeviceSpec);
-+ PyType_Ready(CDeviceType);
- }
-- Py_INCREF((PyObject *)&CDeviceType);
-- PyModule_AddObject(pModule, "Device", (PyObject *)&CDeviceType);
-- pModState->pDeviceClass = &CDeviceType;
-+ pModState->pDeviceClass = CDeviceType;
- pModState->pUnitClass = nullptr;
-+ PyModule_AddObject(pModule, "Device", (PyObject*)CDeviceType);
-
-- if (PyType_Ready(&CConnectionType) < 0)
-+ if (!CConnectionType)
- {
-- _log.Log(LOG_ERROR, "%s, Connection Type not ready.", __func__);
-- return pModule;
-+ CConnectionType = (PyTypeObject*)PyType_FromSpec(&ConnectionSpec);
-+ PyType_Ready(CConnectionType);
- }
-- Py_INCREF((PyObject *)&CConnectionType);
-- PyModule_AddObject(pModule, "Connection", (PyObject *)&CConnectionType);
-+ PyModule_AddObject(pModule, "Connection", (PyObject*)CConnectionType);
-
-- if (PyType_Ready(&CImageType) < 0)
-+ if (!CImageType)
- {
-- _log.Log(LOG_ERROR, "%s, Image Type not ready.", __func__);
-- return pModule;
-+ CImageType = (PyTypeObject*)PyType_FromSpec(&ImageSpec);
-+ PyType_Ready(CImageType);
- }
-- Py_INCREF((PyObject *)&CImageType);
-- PyModule_AddObject(pModule, "Image", (PyObject *)&CImageType);
-+ PyModule_AddObject(pModule, "Image", (PyObject*)CImageType);
-
- return pModule;
- }
-@@ -808,45 +592,58 @@ namespace Plugins
-
- PyMODINIT_FUNC PyInit_DomoticzEx(void)
- {
--
- // This is called during the import of the plugin module
-- // triggered by the "import Domoticz" statement
-+ // triggered by the "import DomoticzEx" statement
- PyObject *pModule = PyModule_Create2(&DomoticzExModuleDef, PYTHON_API_VERSION);
- module_state *pModState = ((struct module_state *)PyModule_GetState(pModule));
-
-- if (PyType_Ready(&CDeviceExType) < 0)
-- {
-- _log.Log(LOG_ERROR, "%s, Device Type not ready.", __func__);
-- return pModule;
-- }
-- Py_INCREF((PyObject *)&CDeviceExType);
-- PyModule_AddObject(pModule, "Device", (PyObject *)&CDeviceExType);
-- pModState->pDeviceClass = &CDeviceExType;
--
-- if (PyType_Ready(&CUnitExType) < 0)
-- {
-- _log.Log(LOG_ERROR, "%s, Unit Type not ready.", __func__);
-- return pModule;
-- }
-- Py_INCREF((PyObject *)&CUnitExType);
-- PyModule_AddObject(pModule, "Unit", (PyObject *)&CUnitExType);
-- pModState->pUnitClass = &CUnitExType;
--
-- if (PyType_Ready(&CConnectionType) < 0)
-- {
-- _log.Log(LOG_ERROR, "%s, Connection Type not ready.", __func__);
-- return pModule;
-+ PyType_Slot DeviceExSlots[] = {
-+ { Py_tp_doc, (void*)"DomoticzEx Device" },
-+ { Py_tp_new, (void*)CDeviceEx_new },
-+ { Py_tp_init, (void*)CDeviceEx_init },
-+ { Py_tp_dealloc, (void*)CDeviceEx_dealloc },
-+ { Py_tp_members, CDeviceEx_members },
-+ { Py_tp_methods, CDeviceEx_methods },
-+ { Py_tp_str, (void*)CDeviceEx_str },
-+ { 0 },
-+ };
-+ PyType_Spec DeviceExSpec = { "DomoticzEx.Device", sizeof(CDeviceEx), 0,
-+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, DeviceExSlots };
-+
-+ pModState->pDeviceClass = (PyTypeObject*)PyType_FromSpec(&DeviceExSpec); // Calls PyType_Ready internally from, 3.9 onwards
-+ PyModule_AddObject(pModule, "Device", (PyObject *)pModState->pDeviceClass);
-+ PyType_Ready(pModState->pDeviceClass);
-+
-+ PyType_Slot UnitExSlots[] = {
-+ { Py_tp_doc, (void*)"DomoticzEx Unit" },
-+ { Py_tp_new, (void*)CUnitEx_new },
-+ { Py_tp_init, (void*)CUnitEx_init },
-+ { Py_tp_dealloc, (void*)CUnitEx_dealloc },
-+ { Py_tp_members, CUnitEx_members },
-+ { Py_tp_methods, CUnitEx_methods },
-+ { Py_tp_str, (void*)CUnitEx_str },
-+ { 0 },
-+ };
-+ PyType_Spec UnitExSpec = { "DomoticzEx.Unit", sizeof(CUnitEx), 0,
-+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, UnitExSlots };
-+
-+ pModState->pUnitClass = (PyTypeObject*)PyType_FromSpec(&UnitExSpec);
-+ PyModule_AddObject(pModule, "Unit", (PyObject*)pModState->pUnitClass);
-+ PyType_Ready(pModState->pUnitClass);
-+
-+ if (!CConnectionType)
-+ {
-+ CConnectionType = (PyTypeObject*)PyType_FromSpec(&ConnectionSpec);
-+ PyType_Ready(CConnectionType);
- }
-- Py_INCREF((PyObject *)&CConnectionType);
-- PyModule_AddObject(pModule, "Connection", (PyObject *)&CConnectionType);
-+ PyModule_AddObject(pModule, "Connection", (PyObject*)CConnectionType);
-
-- if (PyType_Ready(&CImageType) < 0)
-+ if (!CImageType)
- {
-- _log.Log(LOG_ERROR, "%s, Image Type not ready.", __func__);
-- return pModule;
-+ CImageType = (PyTypeObject*)PyType_FromSpec(&ImageSpec);
-+ PyType_Ready(CImageType);
- }
-- Py_INCREF((PyObject *)&CImageType);
-- PyModule_AddObject(pModule, "Image", (PyObject *)&CImageType);
-+ PyModule_AddObject(pModule, "Image", (PyObject*)CImageType);
-
- return pModule;
- }
-@@ -900,8 +697,7 @@ namespace Plugins
- module_state *pModState = ((struct module_state *)PyModule_GetState(brModule));
- if (!pModState)
- {
-- _log.Log(LOG_ERROR, "CPlugin:%s, unable to obtain module state.", __func__);
-- return nullptr;
-+ _log.Log(LOG_ERROR, "%s, unable to obtain module state.", __func__);
- }
-
- return pModState;
-@@ -910,205 +706,76 @@ namespace Plugins
- CPlugin *CPlugin::FindPlugin()
- {
- module_state *pModState = FindModule();
-- if (!pModState)
-- return nullptr;
-- return pModState->pPlugin;
-+ return pModState ? pModState->pPlugin : nullptr;
- }
-
-- void CPlugin::LogTraceback(PyTracebackObject *pTraceback)
-- {
-- if (pTraceback)
-- {
-- Log(LOG_ERROR, "Exception traceback:");
-- }
-- else
-- {
-- Log(LOG_ERROR, "No traceback available");
-- }
--
-- // Log a stack trace if there is one
-- PyTracebackObject *pTraceFrame = pTraceback;
-- while (pTraceFrame)
-- {
-- PyFrameObject *frame = pTraceFrame->tb_frame;
-- if (frame)
-- {
-- int lineno = PyFrame_GetLineNumber(frame);
-- PyCodeObject *pCode = frame->f_code;
-- std::string FileName;
-- if (pCode->co_filename)
-- {
-- FileName = (std::string)PyBorrowedRef(pCode->co_filename);
-- }
-- std::string FuncName = "Unknown";
-- if (pCode->co_name)
-- {
-- FuncName = (std::string)PyBorrowedRef(pCode->co_name);
-- }
-- if (!FileName.empty())
-- Log(LOG_ERROR, " ----> Line %d in '%s', function %s", lineno, FileName.c_str(), FuncName.c_str());
-- else
-- Log(LOG_ERROR, " ----> Line %d in '%s'", lineno, FuncName.c_str());
-- }
-- pTraceFrame = pTraceFrame->tb_next;
-- }
-- }
--
- void CPlugin::LogPythonException()
- {
-- PyTracebackObject *pTraceback;
-+ PyNewRef pTraceback;
- PyNewRef pExcept;
- PyNewRef pValue;
-
-- PyErr_Fetch(&pExcept, &pValue, (PyObject **)&pTraceback);
-- PyErr_NormalizeException(&pExcept, &pValue, (PyObject **)&pTraceback);
-- PyErr_Clear();
-+ PyErr_Fetch(&pExcept, &pValue, &pTraceback);
-+ PyErr_NormalizeException(&pExcept, &pValue, &pTraceback);
-
-- if (pExcept)
-+ if (!pExcept && !pValue && !pTraceback)
- {
-- Log(LOG_ERROR, "Module Import failed, exception: '%s'", ((PyTypeObject *)pExcept)->tp_name);
-+ Log(LOG_ERROR, "Unable to decode exception.");
- }
-- if (pValue)
-+ else
- {
-- std::string sError;
-- PyNewRef pErrBytes = PyUnicode_AsASCIIString(pValue); // Won't normally return text for Import related errors
-- if (!pErrBytes)
-+ std::string sTypeText("Unknown");
-+ if (pExcept)
- {
-- // ImportError has name and path attributes
-- PyErr_Clear();
-- if (PyObject_HasAttrString(pValue, "path"))
-- {
-- std::string sPath = PyNewRef(PyObject_GetAttrString(pValue, "path"));
-- if (sPath.length() && (sPath != "None"))
-- {
-- sError += "Path: " + sPath;
-- }
-- }
-- PyErr_Clear();
-- if (PyObject_HasAttrString(pValue, "name"))
-- {
-- std::string sName = PyNewRef(PyObject_GetAttrString(pValue, "name"));
-- if (sName.length() && (sName != "None"))
-- {
-- sError += " Name: " + sName;
-- }
-- }
-- if (!sError.empty())
-- {
-- Log(LOG_ERROR, "Module Import failed: '%s'", sError.c_str());
-- sError = "";
-- }
--
-- // SyntaxError, IndentationError & TabError have filename, lineno, offset and text attributes
-- PyErr_Clear();
-- if (PyObject_HasAttrString(pValue, "filename"))
-- {
-- std::string sName = PyNewRef(PyObject_GetAttrString(pValue, "name"));
-- sError += "File: " + sName;
-- }
-- long long lineno = -1;
-- long long offset = -1;
-- PyErr_Clear();
-- if (PyObject_HasAttrString(pValue, "lineno"))
-- {
-- PyNewRef pString = PyObject_GetAttrString(pValue, "lineno");
-- lineno = PyLong_AsLongLong(pString);
-- }
-- PyErr_Clear();
-- if (PyObject_HasAttrString(pValue, "offset"))
-- {
-- PyNewRef pString = PyObject_GetAttrString(pValue, "offset");
-- offset = PyLong_AsLongLong(pString);
-- }
-+ PyTypeObject* TypeName = (PyTypeObject*)pExcept;
-+ PyNewRef pName = PyObject_GetAttrString((PyObject*)TypeName, "__name__");
-+ sTypeText = (std::string)pName;
-+ }
-
-- if (!sError.empty())
-- {
-- if ((lineno > 0) && (lineno < 1000))
-+ /* See if we can get a full traceback */
-+ PyNewRef pModule = PyImport_ImportModule("traceback");
-+ if (pModule)
-+ {
-+ PyNewRef pFunc = PyObject_GetAttrString(pModule, "format_exception");
-+ if (pFunc && PyCallable_Check(pFunc)) {
-+ PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, pExcept, pValue, pTraceback, NULL);
-+ if (pList)
- {
-- Log(LOG_ERROR, "Import detail: %s, Line: %lld, offset: %lld", sError.c_str(), lineno, offset);
-+ for (Py_ssize_t i = 0; i < PyList_Size(pList); i++)
-+ {
-+ PyBorrowedRef pPyStr = PyList_GetItem(pList, i);
-+ std::string pStr(pPyStr);
-+ size_t pos = 0;
-+ std::string token;
-+ while ((pos = pStr.find('\n')) != std::string::npos) {
-+ token = pStr.substr(0, pos);
-+ Log(LOG_ERROR, "%s", token.c_str());
-+ pStr.erase(0, pos + 1);
-+ }
-+ }
- }
- else
- {
-- Log(LOG_ERROR, "Import detail: %s, Line: %lld", sError.c_str(), offset);
-+ Log(LOG_ERROR, "Exception: '%s'. No traceback available.", sTypeText.c_str());
- }
-- sError = "";
-- }
--
-- PyErr_Clear();
-- if (PyObject_HasAttrString(pValue, "text"))
-- {
-- std::string sUTF = PyNewRef(PyObject_GetAttrString(pValue, "text"));
-- Log(LOG_ERROR, "Error Line '%s'", sUTF.c_str());
- }
- else
- {
-- Log(LOG_ERROR, "Error Line details not available.");
-- }
--
-- if (!sError.empty())
-- {
-- Log(LOG_ERROR, "Import detail: %s", sError.c_str());
-+ Log(LOG_ERROR, "'format_exception' lookup failed, exception: '%s'. No traceback available.", sTypeText.c_str());
- }
- }
- else
-- Log(LOG_ERROR, "Module Import failed '%s'", std::string(pErrBytes).c_str());
-- }
--
-- // Log a stack trace if there is one
-- LogTraceback(pTraceback);
--
-- if (!pExcept && !pValue && !pTraceback)
-- {
-- Log(LOG_ERROR, "Call to import module failed, unable to decode exception.");
-+ {
-+ Log(LOG_ERROR, "'Traceback' module import failed, exception: '%s'. No traceback available.", sTypeText.c_str());
-+ }
- }
--
-- if (pTraceback)
-- Py_XDECREF(pTraceback);
-+ PyErr_Clear();
- }
-
- void CPlugin::LogPythonException(const std::string &sHandler)
- {
-- PyTracebackObject *pTraceback;
-- PyNewRef pExcept;
-- PyNewRef pValue;
-- PyTypeObject *TypeName;
-- PyNewRef pErrBytes;
-- const char *pTypeText = nullptr;
--
-- PyErr_Fetch(&pExcept, &pValue, (PyObject **)&pTraceback);
--
-- if (pExcept)
-- {
-- TypeName = (PyTypeObject *)pExcept;
-- pTypeText = TypeName->tp_name;
-- }
-- if (pTypeText && pValue)
-- {
-- Log(LOG_ERROR, "'%s' failed '%s':'%s'.", sHandler.c_str(), pTypeText, std::string(pValue).c_str());
-- }
-- if (pTypeText && !pValue)
-- {
-- Log(LOG_ERROR, "'%s' failed '%s'.", sHandler.c_str(), pTypeText);
-- }
-- if (!pTypeText && pValue)
-- {
-- Log(LOG_ERROR, "'%s' failed '%s'.",sHandler.c_str(), std::string(pValue).c_str());
-- }
-- if (!pTypeText && !pValue)
-- {
-- Log(LOG_ERROR, "'%s' failed, unable to determine error.", sHandler.c_str());
-- }
--
-- // Log a stack trace if there is one
-- LogTraceback(pTraceback);
--
-- if (!pExcept && !pValue && !pTraceback)
-- {
-- Log(LOG_ERROR, "Call to message handler '%s' failed, unable to decode exception.", sHandler.c_str());
-- }
--
-- if (pTraceback)
-- Py_XDECREF(pTraceback);
-+ Log(LOG_ERROR, "Call to function '%s' failed, exception details:", sHandler.c_str());
-+ LogPythonException();
- }
-
- int CPlugin::PollInterval(int Interval)
-@@ -1222,7 +889,6 @@ namespace Plugins
- // Tell transport to disconnect if required
- if (pPluginTransport)
- {
-- // std::lock_guard<std::mutex> l(PythonMutex); // Take mutex to guard access to CPluginTransport::m_pConnection
- MessagePlugin(new DisconnectDirective(pPluginTransport->Connection()));
- }
- }
-@@ -1314,25 +980,26 @@ namespace Plugins
- {
- if (m_bDebug & PDM_QUEUE)
- {
-- Log(LOG_NORM, "(" + m_Name + ") Processing '" + std::string(Message->Name()) + "' message");
-+ Log(LOG_NORM, "Processing '" + std::string(Message->Name()) + "' message");
- }
- Message->Process(this);
- }
- catch (...)
- {
-- Log(LOG_ERROR, "PluginSystem: Exception processing message.");
-+ Log(LOG_ERROR, "Exception processing '%s' message.", Message->Name());
-+ }
-+
-+ // Free the memory for the message
-+ if (!m_PyInterpreter)
-+ {
-+ // Can't lock because there is no interpreter to lock
-+ delete Message;
-+ }
-+ else
-+ {
-+ AccessPython Guard(this, Message->Name());
-+ delete Message;
- }
-- }
-- // Free the memory for the message
-- if (!m_PyInterpreter)
-- {
-- // Can't lock because there is no interpreter to lock
-- delete Message;
-- }
-- else
-- {
-- AccessPython Guard(this, m_Name.c_str());
-- delete Message;
- }
- }
-
-@@ -1351,7 +1018,6 @@ namespace Plugins
- {
- for (const auto &pPluginTransport : m_Transports)
- {
-- // std::lock_guard<std::mutex> l(PythonMutex); // Take mutex to guard access to CPluginTransport::m_pConnection
- pPluginTransport->VerifyConnection();
- }
- }
-@@ -1371,6 +1037,7 @@ namespace Plugins
-
- try
- {
-+ // Only initialise one plugin at a time to prevent issues with module creation
- PyEval_RestoreThread((PyThreadState *)m_mainworker.m_pluginsystem.PythonThread());
- m_PyInterpreter = Py_NewInterpreter();
- if (!m_PyInterpreter)
-@@ -1379,10 +1046,6 @@ namespace Plugins
- goto Error;
- }
-
-- // Get an instance of the single, central Py_None to use in local code
-- PyBorrowedRef globalNone = Py_BuildValue("");
-- Py_None = globalNone;
--
- // Prepend plugin directory to path so that python will search it early when importing
- #ifdef WIN32
- std::wstring sSeparator = L";";
-@@ -1433,7 +1096,7 @@ namespace Plugins
- for (Py_ssize_t i = 0; i < PyList_Size(pSites); i++)
- {
- PyBorrowedRef pSite = PyList_GetItem(pSites, i);
-- if (pSite && PyUnicode_Check(pSite))
-+ if (pSite.IsString())
- {
- std::wstringstream ssPath;
- ssPath << ((std::string)PyBorrowedRef(pSite)).c_str();
-@@ -1501,6 +1164,25 @@ namespace Plugins
- }
- pModState->pPlugin = this;
-
-+ // Get reference to global 'Py_None' instance for comparisons
-+ if (!Py_None)
-+ {
-+ PyBorrowedRef global_dict = PyModule_GetDict(m_PyModule);
-+ PyNewRef local_dict = PyDict_New();
-+ PyNewRef pCode = Py_CompileString("# Eval will return 'None'\n", "<domoticz>", Py_file_input);
-+ if (pCode)
-+ {
-+ PyNewRef pEval = PyEval_EvalCode(pCode, global_dict, local_dict);
-+ Py_None = pEval;
-+ Py_INCREF(Py_None);
-+ }
-+ else
-+ {
-+ Log(LOG_ERROR, "Failed to compile script to set global Py_None");
-+ }
-+ }
-+
-+
- // Add start command to message queue
- MessagePlugin(new onStartCallback());
-
-@@ -1611,7 +1293,7 @@ namespace Plugins
- }
- }
-
-- m_DeviceDict = (PyDictObject*)PyDict_New();
-+ m_DeviceDict = PyDict_New();
- if (PyDict_SetItemString(pModuleDict, "Devices", (PyObject *)m_DeviceDict) == -1)
- {
- Log(LOG_ERROR, "(%s) failed to add Device dictionary.", m_PluginKey.c_str());
-@@ -1647,7 +1329,6 @@ namespace Plugins
- // load associated devices to make them available to python
- if (!result.empty())
- {
-- PyType_Ready(pModState->pDeviceClass);
- // Add device objects into the device dictionary with Unit as the key
- for (const auto &sd : result)
- {
-@@ -1689,7 +1370,7 @@ namespace Plugins
- }
- }
-
-- m_ImageDict = (PyDictObject *)PyDict_New();
-+ m_ImageDict = PyDict_New();
- if (PyDict_SetItemString(pModuleDict, "Images", (PyObject *)m_ImageDict) == -1)
- {
- Log(LOG_ERROR, "(%s) failed to add Image dictionary.", m_PluginKey.c_str());
-@@ -1700,11 +1381,10 @@ namespace Plugins
- result = m_sql.safe_query("SELECT ID, Base, Name, Description FROM CustomImages WHERE Base LIKE '%q%%' ORDER BY ID ASC", m_PluginKey.c_str());
- if (!result.empty())
- {
-- PyType_Ready(&CImageType);
- // Add image objects into the image dictionary with ID as the key
- for (const auto &sd : result)
- {
-- CImage *pImage = (CImage *)CImage_new(&CImageType, (PyObject *)nullptr, (PyObject *)nullptr);
-+ CImage *pImage = (CImage *)CImage_new(CImageType, (PyObject *)nullptr, (PyObject *)nullptr);
-
- PyNewRef pKey = PyUnicode_FromString(sd[1].c_str());
- if (PyDict_SetItem((PyObject *)m_ImageDict, pKey, (PyObject *)pImage) == -1)
-@@ -2098,7 +1778,7 @@ namespace Plugins
- }
- else
- {
-- CDevice *pDevice = (CDevice *)CDevice_new(&CDeviceType, (PyObject *)nullptr, (PyObject *)nullptr);
-+ CDevice *pDevice = (CDevice *)CDevice_new(CDeviceType, (PyObject *)nullptr, (PyObject *)nullptr);
-
- PyNewRef pKey = PyLong_FromLong(Unit);
- if (PyDict_SetItem((PyObject *)m_DeviceDict, pKey, (PyObject *)pDevice) == -1)
-@@ -2250,13 +1930,24 @@ namespace Plugins
- void CPlugin::RestoreThread()
- {
- if (m_PyInterpreter)
-- PyEval_RestoreThread((PyThreadState *)m_PyInterpreter);
-+ {
-+ PyEval_RestoreThread((PyThreadState*)m_PyInterpreter);
-+ }
-+ else
-+ {
-+ Log(LOG_ERROR, "Attempt to aquire the GIL with NULL Interpreter details.");
-+ }
- }
-
- void CPlugin::ReleaseThread()
- {
- if (m_PyInterpreter)
-- PyEval_SaveThread();
-+ {
-+ if (!PyEval_SaveThread())
-+ {
-+ Log(LOG_ERROR, "Attempt to release GIL returned NULL value");
-+ }
-+ }
- }
-
- void CPlugin::Callback(PyObject *pTarget, const std::string &sHandler, PyObject *pParams)
-@@ -2294,7 +1985,11 @@ namespace Plugins
- }
-
- if (m_bDebug & PDM_QUEUE)
-- Log(LOG_NORM, "Calling message handler '%s' on '%s' type object.", sHandler.c_str(), pTarget->ob_type->tp_name);
-+ {
-+ PyNewRef pName = PyObject_GetAttrString((PyObject*)(pTarget->ob_type), "__name__");
-+ if (pName)
-+ Log(LOG_NORM, "Calling message handler '%s' on '%s' type object.", sHandler.c_str(), (std::string(pName).c_str()));
-+ }
-
- PyErr_Clear();
-
-@@ -2315,7 +2010,7 @@ namespace Plugins
- {
- // See if additional information is available
- PyNewRef pLocals = PyObject_Dir(pTarget);
-- if (PyList_Check(pLocals)) // && PyIter_Check(pLocals)) // Check fails but iteration works??!?
-+ if (pLocals.IsList()) // && PyIter_Check(pLocals)) // Check fails but iteration works??!?
- {
- Log(LOG_NORM, "Local context:");
- PyNewRef pIter = PyObject_GetIter(pLocals);
-@@ -2391,7 +2086,7 @@ namespace Plugins
- module_state *pModState = ((struct module_state *)PyModule_GetState(brModule));
- if (!pModState)
- {
-- Log(LOG_ERROR, "CPlugin:%s, unable to obtain module state.", __func__);
-+ Log(LOG_ERROR, "%s, unable to obtain module state.", __func__);
- return;
- }
-
-@@ -2409,7 +2104,8 @@ namespace Plugins
- }
- else if (isDevice == 0)
- {
-- Log(LOG_NORM, "%s: Device dictionary contained non-Device entry '%s'.", __func__, pDevice->ob_type->tp_name);
-+ PyNewRef pName = PyObject_GetAttrString((PyObject*)pDevice->ob_type, "__name__");
-+ Log(LOG_NORM, "%s: Device dictionary contained non-Device entry '%s'.", __func__, ((std::string)pName).c_str());
- }
- else
- {
-@@ -2430,7 +2126,8 @@ namespace Plugins
- }
- else if (isValue == 0)
- {
-- _log.Log(LOG_NORM, "%s: Unit dictionary contained non-Unit entry '%s'.", __func__, pUnit->ob_type->tp_name);
-+ PyNewRef pName = PyObject_GetAttrString((PyObject*)pUnit->ob_type, "__name__");
-+ _log.Log(LOG_NORM, "%s: Unit dictionary contained non-Unit entry '%s'.", __func__, ((std::string)pName).c_str());
- }
- else
- {
-@@ -2520,7 +2217,7 @@ namespace Plugins
- PyBorrowedRef pModuleDict = PyModule_GetDict(PythonModule()); // returns a borrowed referece to the __dict__ object for the module
- if (m_SettingsDict)
- Py_XDECREF(m_SettingsDict);
-- m_SettingsDict = (PyDictObject *)PyDict_New();
-+ m_SettingsDict = PyDict_New();
- if (PyDict_SetItemString(pModuleDict, "Settings", (PyObject *)m_SettingsDict) == -1)
- {
- Log(LOG_ERROR, "(%s) failed to add Settings dictionary.", m_PluginKey.c_str());
-@@ -2532,7 +2229,6 @@ namespace Plugins
- result = m_sql.safe_query("SELECT Key, nValue, sValue FROM Preferences");
- if (!result.empty())
- {
-- PyType_Ready(&CDeviceType);
- // Add settings strings into the settings dictionary with Unit as the key
- for (const auto &sd : result)
- {
-@@ -2617,12 +2313,15 @@ namespace Plugins
- if (!m_DeviceDict)
- return true;
-
-+ return false;
-+
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next((PyObject *)m_DeviceDict, &pos, &key, &value))
- {
- // Handle different Device dictionaries types
-- if (PyUnicode_Check(key))
-+ PyBorrowedRef pKeyType(key);
-+ if (pKeyType.IsString())
- {
- // Version 2+ of the framework, keyed by DeviceID
- std::string sKey = PyUnicode_AsUTF8(key);
-@@ -2632,7 +2331,7 @@ namespace Plugins
- return (pDevice->TimedOut != 0);
- }
- }
-- else
-+ else if (pKeyType.IsLong())
- {
- // Version 1 of the framework, keyed by Unit
- long iKey = PyLong_AsLong(key);
-@@ -2648,6 +2347,10 @@ namespace Plugins
- return (pDevice->TimedOut != 0);
- }
- }
-+ else
-+ {
-+ Log(LOG_ERROR, "'%s' Invalid Node key type.", __func__);
-+ }
- }
-
- return false;
-@@ -2655,7 +2358,7 @@ namespace Plugins
-
- PyBorrowedRef CPlugin::FindDevice(const std::string &Key)
- {
-- if (m_DeviceDict && PyDict_Check(m_DeviceDict))
-+ if (m_DeviceDict && PyBorrowedRef(m_DeviceDict).IsDict())
- {
- return PyDict_GetItemString((PyObject*)m_DeviceDict, Key.c_str());
- }
-@@ -2934,5 +2637,47 @@ namespace Plugins
-
- return true;
- }
-+
-+ bool PyBorrowedRef::TypeCheck(long PyType)
-+ {
-+ if (m_pObject)
-+ {
-+ PyNewRef pType = PyObject_Type(m_pObject);
-+ return pType && (PyType_GetFlags((PyTypeObject*)pType) & PyType);
-+ }
-+ return false;
-+ }
-+
-+ std::string PyBorrowedRef::Attribute(const char* name)
-+ {
-+ std::string sAttr = "";
-+ if (m_pObject)
-+ {
-+ try
-+ {
-+ if (PyObject_HasAttrString(m_pObject, name))
-+ {
-+ PyNewRef pAttr = PyObject_GetAttrString(m_pObject, name);
-+ sAttr = (std::string)pAttr;
-+ }
-+ }
-+ catch (...)
-+ {
-+ _log.Log(LOG_ERROR, "[%s] Exception determining Python object attribute '%s'.", __func__, name);
-+ }
-+ }
-+ return sAttr;
-+ }
-+
-+ std::string PyBorrowedRef::Type()
-+ {
-+ std::string sType = "";
-+ if (m_pObject)
-+ {
-+ PyNewRef pType = PyObject_Type(m_pObject);
-+ sType = pType.Attribute("__name__");
-+ }
-+ return sType;
-+ }
- } // namespace Plugins
- #endif
---- a/hardware/plugins/Plugins.h
-+++ b/hardware/plugins/Plugins.h
-@@ -62,8 +62,6 @@ namespace Plugins {
-
- void Do_Work();
-
-- void LogPythonException(const std::string &);
--
- public:
- CPlugin(int HwdID, const std::string &Name, const std::string &PluginKey);
- ~CPlugin() override;
-@@ -75,7 +73,7 @@ namespace Plugins {
- bool StopHardware() override;
-
- void LogPythonException();
-- void LogTraceback(PyTracebackObject *pTraceback);
-+ void LogPythonException(const std::string&);
-
- int PollInterval(int Interval = -1);
- PyObject* PythonModule() { return m_PyModule; };
-@@ -119,9 +117,9 @@ namespace Plugins {
- PyBorrowedRef FindUnitInDevice(const std::string &deviceKey, const int unitKey);
-
- std::string m_PluginKey;
-- PyDictObject* m_DeviceDict;
-- PyDictObject* m_ImageDict;
-- PyDictObject* m_SettingsDict;
-+ PyObject* m_DeviceDict;
-+ PyObject* m_ImageDict;
-+ PyObject* m_SettingsDict;
- std::string m_HomeFolder;
- PluginDebugMask m_bDebug;
- bool m_bTracing;
-@@ -147,16 +145,29 @@ namespace Plugins {
- //
- class PyBorrowedRef
- {
-- protected:
-+ protected:
- PyObject *m_pObject;
-+ bool TypeCheck(long);
-
-- public:
-+ public:
- PyBorrowedRef()
- : m_pObject(NULL){};
- PyBorrowedRef(PyObject *pObject)
- {
- m_pObject = pObject;
- };
-+ std::string Attribute(const char* name);
-+ std::string Type();
-+ bool IsDict() { return TypeCheck(Py_TPFLAGS_DICT_SUBCLASS); };
-+ bool IsList() { return TypeCheck(Py_TPFLAGS_LIST_SUBCLASS); };
-+ bool IsLong() { return TypeCheck(Py_TPFLAGS_LONG_SUBCLASS); };
-+ bool IsTuple() { return TypeCheck(Py_TPFLAGS_TUPLE_SUBCLASS); };
-+ bool IsString() { return TypeCheck(Py_TPFLAGS_UNICODE_SUBCLASS); };
-+ bool IsBytes() { return TypeCheck(Py_TPFLAGS_BYTES_SUBCLASS); };
-+ bool IsByteArray() { return Type() == "bytearray"; };
-+ bool IsFloat() { return Type() == "float"; };
-+ bool IsBool() { return Type() == "bool"; };
-+ bool IsNone() { return m_pObject && (m_pObject == Py_None); };
- operator PyObject *() const
- {
- return m_pObject;
-@@ -165,10 +176,6 @@ namespace Plugins {
- {
- return (PyTypeObject *)m_pObject;
- }
-- operator PyBytesObject *() const
-- {
-- return (PyBytesObject *)m_pObject;
-- }
- operator bool() const
- {
- return (m_pObject != NULL);
-@@ -283,12 +290,8 @@ namespace Plugins {
- class AccessPython
- {
- private:
-- static std::mutex PythonMutex;
-- static volatile bool m_bHasThreadState;
-- std::unique_lock<std::mutex>* m_Lock;
-- PyThreadState* m_Python;
- CPlugin* m_pPlugin;
-- const char* m_Text;
-+ std::string m_Text;
-
- public:
- AccessPython(CPlugin* pPlugin, const char* sWhat);
---- a/hardware/plugins/PythonObjectEx.cpp
-+++ b/hardware/plugins/PythonObjectEx.cpp
-@@ -8,7 +8,6 @@
- #include "../../main/Logger.h"
- #include "../../main/SQLHelper.h"
- #include "../../hardware/hardwaretypes.h"
--#include "../../main/localtime_r.h"
- #include "../../main/mainstructs.h"
- #include "../../main/mainworker.h"
- #include "../../main/EventSystem.h"
-@@ -23,19 +22,22 @@
- namespace Plugins {
-
- extern struct PyModuleDef DomoticzExModuleDef;
-- extern void LogPythonException(CPlugin *pPlugin, const std::string &sHandler);
- extern void maptypename(const std::string &sTypeName, int &Type, int &SubType, int &SwitchType, std::string &sValue, PyObject *OptionsIn, PyObject *OptionsOut);
-
- void CDeviceEx_dealloc(CDeviceEx *self)
- {
- Py_XDECREF(self->DeviceID);
- Py_XDECREF(self->m_UnitDict);
-- Py_TYPE(self)->tp_free((PyObject *)self);
-+
-+ PyNewRef pType = PyObject_Type((PyObject*)self);
-+ freefunc pFree = (freefunc)PyType_GetSlot(pType, Py_tp_free);
-+ pFree((PyObject*)self);
- }
-
- PyObject *CDeviceEx_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
-- CDeviceEx *self = (CDeviceEx *)type->tp_alloc(type, 0);
-+ allocfunc pAlloc = (allocfunc)PyType_GetSlot(type, Py_tp_alloc);
-+ CDeviceEx* self = (CDeviceEx*)pAlloc(type, 0);
-
- try
- {
-@@ -95,11 +97,8 @@ namespace Plugins {
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &DeviceID))
- {
-- CPlugin *pPlugin = nullptr;
-- if (pModState)
-- pPlugin = pModState->pPlugin;
- pModState->pPlugin->Log(LOG_ERROR, R"(Expected: myVar = Domoticz.DeviceEx(DeviceID='xxxx'))");
-- LogPythonException(pPlugin, __func__);
-+ pModState->pPlugin->LogPythonException(__func__);
- }
- else
- {
-@@ -108,7 +107,7 @@ namespace Plugins {
- {
- self->DeviceID = PyUnicode_FromString(DeviceID);
- }
-- self->m_UnitDict = (PyDictObject *)PyDict_New();
-+ self->m_UnitDict = (PyObject *)PyDict_New();
- }
-
- return true;
-@@ -147,7 +146,6 @@ namespace Plugins {
- if (!result.empty())
- {
-
-- PyType_Ready(&CUnitExType);
- // Create Unit objects and add the Units dictionary with Unit number as the key
- for (auto itt = result.begin(); itt != result.end(); ++itt)
- {
-@@ -236,12 +234,16 @@ namespace Plugins {
- Py_XDECREF(self->Options);
- Py_XDECREF(self->Color);
- Py_XDECREF(self->Parent);
-- Py_TYPE(self)->tp_free((PyObject *)self);
-+
-+ PyNewRef pType = PyObject_Type((PyObject*)self);
-+ freefunc pFree = (freefunc)PyType_GetSlot(pType, Py_tp_free);
-+ pFree((PyObject*)self);
- }
-
- PyObject *CUnitEx_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
-- CUnitEx *self = (CUnitEx *)type->tp_alloc(type, 0);
-+ allocfunc pAlloc = (allocfunc)PyType_GetSlot(type, Py_tp_alloc);
-+ CUnitEx *self = (CUnitEx*)pAlloc(type, 0);
-
- try
- {
-@@ -380,7 +382,6 @@ namespace Plugins {
- else
- {
- // Create a temporary one
-- PyType_Ready(pModState->pDeviceClass);
- PyNewRef nrArgList = Py_BuildValue("(s)", DeviceID);
- if (!nrArgList)
- {
-@@ -411,43 +412,40 @@ namespace Plugins {
- self->Image = Image;
- if (Used == 1)
- self->Used = Used;
-- if (Options && PyDict_Check(Options) && PyDict_Size(Options) > 0)
-+ if (Options && PyBorrowedRef(Options).IsDict() && PyDict_Size(Options) > 0)
- {
- PyObject *pKey, *pValue;
- Py_ssize_t pos = 0;
- PyDict_Clear(self->Options);
- while (PyDict_Next(Options, &pos, &pKey, &pValue))
- {
-- if (PyUnicode_Check(pValue))
-+ PyNewRef pKeyDict = PyObject_Str(pKey);
-+ PyNewRef pValueDict = PyObject_Str(pValue);
-+
-+ if (pKeyDict && pValueDict)
- {
-- PyNewRef pKeyDict = PyUnicode_FromKindAndData(PyUnicode_KIND(pKey), PyUnicode_DATA(pKey), PyUnicode_GET_LENGTH(pKey));
-- PyNewRef pValueDict = PyUnicode_FromKindAndData(PyUnicode_KIND(pValue), PyUnicode_DATA(pValue), PyUnicode_GET_LENGTH(pValue));
- if (PyDict_SetItem(self->Options, pKeyDict, pValueDict) == -1)
- {
-- _log.Log(LOG_ERROR, "(%s) Failed to initialize Options dictionary for Hardware/Unit combination (%d:%d).",
-- pModState->pPlugin->m_Name.c_str(), pModState->pPlugin->m_HwdID, self->Unit);
-+ pModState->pPlugin->Log(LOG_ERROR, "(%s) Failed to initialize Options dictionary for Hardware/Unit combination (%d:%d).",
-+ pModState->pPlugin->m_Name.c_str(), pModState->pPlugin->m_HwdID, self->Unit);
- break;
- }
- }
- else
- {
-- _log.Log(
-+ PyNewRef pName = PyObject_GetAttrString((PyObject*)pValue->ob_type, "__name__");
-+ pModState->pPlugin->Log(
- LOG_ERROR,
-- R"((%s) Failed to initialize Options dictionary for Hardware/Unit combination (%d:%d): Only "string" type dictionary entries supported, but entry has type "%s")",
-- pModState->pPlugin->m_Name.c_str(), pModState->pPlugin->m_HwdID, self->Unit, pValue->ob_type->tp_name);
-+ "(%s) Failed to initialize Options dictionary for Hardware / Unit combination(%d:%d): Unable to convert to string.)",
-+ pModState->pPlugin->m_Name.c_str(), pModState->pPlugin->m_HwdID, self->Unit);
- }
- }
- }
- }
- else
- {
-- CPlugin *pPlugin = nullptr;
-- if (pModState)
-- {
-- pPlugin = pModState->pPlugin;
-- _log.Log(LOG_ERROR, R"(Expected: myVar = DomoticzEx.Unit(Name="myDevice", DeviceID="", Unit=0, TypeName="", Type=0, Subtype=0, Switchtype=0, Image=0, Options={}, Used=1, Description=""))");
-- LogPythonException(pPlugin, __func__);
-- }
-+ pModState->pPlugin->Log(LOG_ERROR, R"(Expected: myVar = DomoticzEx.Unit(Name="myDevice", DeviceID="", Unit=0, TypeName="", Type=0, Subtype=0, Switchtype=0, Image=0, Options={}, Used=1, Description=""))");
-+ pModState->pPlugin->LogPythonException(__func__);
- }
- }
- catch (std::exception *e)
-@@ -756,7 +754,7 @@ namespace Plugins {
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ps", kwlist, &bWriteLog, &TypeName))
- {
- pModState->pPlugin->Log(LOG_ERROR, "(%s) Failed to parse parameters: 'Log' and/or 'TypeName' expected.", __func__);
-- LogPythonException(pModState->pPlugin, __func__);
-+ pModState->pPlugin->LogPythonException(__func__);
- Py_RETURN_NONE;
- }
-
-@@ -789,7 +787,7 @@ namespace Plugins {
-
- // Options provided, assume change
- std::string sOptionValue;
-- if (pOptionsDict && PyDict_Check(pOptionsDict))
-+ if (pOptionsDict && pOptionsDict.IsDict())
- {
- if (self->SubType != sTypeCustom)
- {
---- a/hardware/plugins/PythonObjectEx.h
-+++ b/hardware/plugins/PythonObjectEx.h
-@@ -12,7 +12,7 @@ namespace Plugins {
- PyObject_HEAD
- PyObject* DeviceID;
- int TimedOut;
-- PyDictObject* m_UnitDict;
-+ PyObject* m_UnitDict;
-
- static bool isInstance(PyObject *pObject);
- };
-@@ -36,46 +36,6 @@ namespace Plugins {
- { nullptr } /* Sentinel */
- };
-
-- static PyTypeObject CDeviceExType = {
-- PyVarObject_HEAD_INIT(nullptr, 0) "DomoticzEx.Device", /* tp_name */
-- sizeof(CDeviceEx), /* tp_basicsize */
-- 0, /* tp_itemsize */
-- (destructor)CDeviceEx_dealloc, /* tp_dealloc */
-- 0, /* tp_print */
-- nullptr, /* tp_getattr */
-- nullptr, /* tp_setattr */
-- nullptr, /* tp_reserved */
-- nullptr, /* tp_repr */
-- nullptr, /* tp_as_number */
-- nullptr, /* tp_as_sequence */
-- nullptr, /* tp_as_mapping */
-- nullptr, /* tp_hash */
-- nullptr, /* tp_call */
-- (reprfunc)CDeviceEx_str, /* tp_str */
-- nullptr, /* tp_getattro */
-- nullptr, /* tp_setattro */
-- nullptr, /* tp_as_buffer */
-- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-- "DomoticzEx Device", /* tp_doc */
-- nullptr, /* tp_traverse */
-- nullptr, /* tp_clear */
-- nullptr, /* tp_richcompare */
-- 0, /* tp_weaklistoffset */
-- nullptr, /* tp_iter */
-- nullptr, /* tp_iternext */
-- CDeviceEx_methods, /* tp_methods */
-- CDeviceEx_members, /* tp_members */
-- nullptr, /* tp_getset */
-- nullptr, /* tp_base */
-- nullptr, /* tp_dict */
-- nullptr, /* tp_descr_get */
-- nullptr, /* tp_descr_set */
-- 0, /* tp_dictoffset */
-- (initproc)CDeviceEx_init, /* tp_init */
-- nullptr, /* tp_alloc */
-- CDeviceEx_new /* tp_new */
-- };
--
- class CUnitEx
- {
- public:
-@@ -146,44 +106,5 @@ namespace Plugins {
- { "Touch", (PyCFunction)CUnitEx_touch, METH_NOARGS, "Notify Domoticz that device has been seen." },
- { nullptr } /* Sentinel */
- };
--
-- static PyTypeObject CUnitExType = {
-- PyVarObject_HEAD_INIT(nullptr, 0) "DomoticzEx.Unit", /* tp_name */
-- sizeof(CUnitEx), /* tp_basicsize */
-- 0, /* tp_itemsize */
-- (destructor)CUnitEx_dealloc, /* tp_dealloc */
-- 0, /* tp_print */
-- nullptr, /* tp_getattr */
-- nullptr, /* tp_setattr */
-- nullptr, /* tp_reserved */
-- nullptr, /* tp_repr */
-- nullptr, /* tp_as_number */
-- nullptr, /* tp_as_sequence */
-- nullptr, /* tp_as_mapping */
-- nullptr, /* tp_hash */
-- nullptr, /* tp_call */
-- (reprfunc)CUnitEx_str, /* tp_str */
-- nullptr, /* tp_getattro */
-- nullptr, /* tp_setattro */
-- nullptr, /* tp_as_buffer */
-- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-- "DomoticzEx Unit", /* tp_doc */
-- nullptr, /* tp_traverse */
-- nullptr, /* tp_clear */
-- nullptr, /* tp_richcompare */
-- 0, /* tp_weaklistoffset */
-- nullptr, /* tp_iter */
-- nullptr, /* tp_iternext */
-- CUnitEx_methods, /* tp_methods */
-- CUnitEx_members, /* tp_members */
-- nullptr, /* tp_getset */
-- nullptr, /* tp_base */
-- nullptr, /* tp_dict */
-- nullptr, /* tp_descr_get */
-- nullptr, /* tp_descr_set */
-- 0, /* tp_dictoffset */
-- (initproc)CUnitEx_init, /* tp_init */
-- nullptr, /* tp_alloc */
-- CUnitEx_new /* tp_new */
-- };
-+
- } // namespace Plugins
---- a/hardware/plugins/PythonObjects.cpp
-+++ b/hardware/plugins/PythonObjects.cpp
-@@ -8,7 +8,6 @@
- #include "../../main/Logger.h"
- #include "../../main/SQLHelper.h"
- #include "../../hardware/hardwaretypes.h"
--#include "../../main/localtime_r.h"
- #include "../../main/mainstructs.h"
- #include "../../main/mainworker.h"
- #include "../../main/EventSystem.h"
-@@ -22,21 +21,28 @@
-
- namespace Plugins {
-
-+ PyTypeObject* CDeviceType = nullptr;
-+ PyTypeObject* CConnectionType = nullptr;
-+ PyTypeObject* CImageType = nullptr;
-+
- extern struct PyModuleDef DomoticzModuleDef;
- extern struct PyModuleDef DomoticzExModuleDef;
-- extern void LogPythonException(CPlugin *pPlugin, const std::string &sHandler);
-
- void CImage_dealloc(CImage* self)
- {
- Py_XDECREF(self->Base);
- Py_XDECREF(self->Name);
- Py_XDECREF(self->Description);
-- Py_TYPE(self)->tp_free((PyObject*)self);
-+
-+ PyNewRef pType = PyObject_Type((PyObject*)self);
-+ freefunc pFree = (freefunc)PyType_GetSlot(pType, Py_tp_free);
-+ pFree((PyObject*)self);
- }
-
- PyObject* CImage_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
-- CImage *self = (CImage *)type->tp_alloc(type, 0);
-+ allocfunc pAlloc = (allocfunc)PyType_GetSlot(type, Py_tp_alloc);
-+ CImage *self = (CImage *)pAlloc(type, 0);
-
- try
- {
-@@ -130,10 +136,8 @@ namespace Plugins {
- }
- else
- {
-- CPlugin *pPlugin = nullptr;
-- if (pModState) pPlugin = pModState->pPlugin;
-- _log.Log(LOG_ERROR, "Expected: myVar = Domoticz.Image(Filename=\"MyImages.zip\")");
-- LogPythonException(pPlugin, __func__);
-+ pModState->pPlugin->Log(LOG_ERROR, "Expected: myVar = Domoticz.Image(Filename=\"MyImages.zip\")");
-+ pModState->pPlugin->LogPythonException(__func__);
- }
- }
- catch (std::exception *e)
-@@ -177,11 +181,10 @@ namespace Plugins {
- std::vector<std::vector<std::string> > result = m_sql.safe_query("SELECT max(ID), Base, Name, Description FROM CustomImages");
- if (!result.empty())
- {
-- PyType_Ready(&CImageType);
- // Add image objects into the image dictionary with ID as the key
- for (const auto &sd : result)
- {
-- CImage *pImage = (CImage *)CImage_new(&CImageType, (PyObject *)nullptr,
-+ CImage *pImage = (CImage *)CImage_new(CImageType, (PyObject *)nullptr,
- (PyObject *)nullptr);
-
- PyObject* pKey = PyUnicode_FromString(sd[1].c_str());
-@@ -226,7 +229,7 @@ namespace Plugins {
- {
- if (self->pPlugin->m_bDebug & PDM_IMAGE)
- {
-- _log.Log(LOG_NORM, "(%s) Deleting Image '%s'.", self->pPlugin->m_Name.c_str(), sName.c_str());
-+ _log.Log(LOG_NORM, "Deleting Image '%s'.", sName.c_str());
- }
-
- std::vector<std::vector<std::string> > result;
-@@ -238,19 +241,18 @@ namespace Plugins {
- PyNewRef pKey = PyLong_FromLong(self->ImageID);
- if (PyDict_DelItem((PyObject*)self->pPlugin->m_ImageDict, pKey) == -1)
- {
-- _log.Log(LOG_ERROR, "(%s) failed to delete image '%d' from images dictionary.", self->pPlugin->m_Name.c_str(), self->ImageID);
-- Py_INCREF(Py_None);
-- return Py_None;
-+ self->pPlugin->Log(LOG_ERROR, "Failed to delete image '%d' from images dictionary.", self->ImageID);
-+ Py_RETURN_NONE;
- }
- }
- else
- {
-- _log.Log(LOG_ERROR, "(%s) Image deletion failed, Image %d not found in Domoticz.", self->pPlugin->m_Name.c_str(), self->ImageID);
-+ self->pPlugin->Log(LOG_ERROR, "Image deletion failed, Image %d not found in Domoticz.", self->ImageID);
- }
- }
- else
- {
-- _log.Log(LOG_ERROR, "(%s) Image deletion failed, '%s' does not represent a Image in Domoticz.", self->pPlugin->m_Name.c_str(), sName.c_str());
-+ self->pPlugin->Log(LOG_ERROR, "Image deletion failed, '%s' does not represent a Image in Domoticz.", sName.c_str());
- }
- }
- else
-@@ -278,12 +280,16 @@ namespace Plugins {
- PyDict_Clear(self->Options);
- Py_XDECREF(self->Options);
- Py_XDECREF(self->Color);
-- Py_TYPE(self)->tp_free((PyObject*)self);
-+
-+ PyNewRef pType = PyObject_Type((PyObject*)self);
-+ freefunc pFree = (freefunc)PyType_GetSlot(pType, Py_tp_free);
-+ pFree((PyObject*)self);
- }
-
- PyObject* CDevice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
-- CDevice *self = (CDevice *)type->tp_alloc(type, 0);
-+ allocfunc pAlloc = (allocfunc)PyType_GetSlot(type, Py_tp_alloc);
-+ CDevice *self = (CDevice*)pAlloc(type, 0);
-
- try
- {
-@@ -473,7 +479,7 @@ namespace Plugins {
- }
- else if (sTypeName == "Selector Switch")
- {
-- if (!OptionsIn || !PyDict_Check(OptionsIn)) {
-+ if (!OptionsIn || !PyBorrowedRef(OptionsIn).IsDict()) {
- PyDict_Clear(OptionsOut);
- PyDict_SetItemString(OptionsOut, "LevelActions", PyUnicode_FromString("|||"));
- PyDict_SetItemString(OptionsOut, "LevelNames", PyUnicode_FromString("Off|Level1|Level2|Level3"));
-@@ -517,7 +523,7 @@ namespace Plugins {
- else if (sTypeName == "Custom")
- {
- SubType = sTypeCustom;
-- if (!OptionsIn || !PyDict_Check(OptionsIn)) {
-+ if (!OptionsIn || !PyBorrowedRef(OptionsIn).IsDict()) {
- PyDict_Clear(OptionsOut);
- PyDict_SetItemString(OptionsOut, "Custom", PyUnicode_FromString("1"));
- }
-@@ -615,42 +621,39 @@ namespace Plugins {
- if (SwitchType != -1) self->SwitchType = SwitchType;
- if (Image != -1) self->Image = Image;
- if (Used == 1) self->Used = Used;
-- if (Options && PyDict_Check(Options) && PyDict_Size(Options) > 0) {
-+ if (Options && PyBorrowedRef(Options).IsDict() && PyDict_Size(Options) > 0) {
- PyObject *pKey, *pValue;
- Py_ssize_t pos = 0;
- PyDict_Clear(self->Options);
-- while(PyDict_Next(Options, &pos, &pKey, &pValue))
-+ while (PyDict_Next(Options, &pos, &pKey, &pValue))
- {
-- if (PyUnicode_Check(pValue))
-+ PyNewRef pKeyDict = PyObject_Str(pKey);
-+ PyNewRef pValueDict = PyObject_Str(pValue);
-+
-+ if (pKeyDict && pValueDict)
- {
-- PyObject *pKeyDict = PyUnicode_FromKindAndData(PyUnicode_KIND(pKey), PyUnicode_DATA(pKey), PyUnicode_GET_LENGTH(pKey));
-- PyObject *pValueDict = PyUnicode_FromKindAndData(PyUnicode_KIND(pValue), PyUnicode_DATA(pValue), PyUnicode_GET_LENGTH(pValue));
- if (PyDict_SetItem(self->Options, pKeyDict, pValueDict) == -1)
- {
-- _log.Log(LOG_ERROR, "(%s) Failed to initialize Options dictionary for Hardware/Unit combination (%d:%d).", self->pPlugin->m_Name.c_str(), self->HwdID, self->Unit);
-- Py_XDECREF(pKeyDict);
-- Py_XDECREF(pValueDict);
-+ pModState->pPlugin->Log(LOG_ERROR, "(%s) Failed to initialize Options dictionary for Hardware/Unit combination (%d:%d).",
-+ pModState->pPlugin->m_Name.c_str(), pModState->pPlugin->m_HwdID, self->Unit);
- break;
- }
-- Py_XDECREF(pKeyDict);
-- Py_XDECREF(pValueDict);
- }
- else
- {
-- _log.Log(
-+ PyNewRef pName = PyObject_GetAttrString((PyObject*)pValue->ob_type, "__name__");
-+ pModState->pPlugin->Log(
- LOG_ERROR,
-- R"((%s) Failed to initialize Options dictionary for Hardware/Unit combination (%d:%d): Only "string" type dictionary entries supported, but entry has type "%s")",
-- self->pPlugin->m_Name.c_str(), self->HwdID, self->Unit, pValue->ob_type->tp_name);
-+ "(%s) Failed to initialize Options dictionary for Hardware / Unit combination(%d:%d): Unable to convert to string.)",
-+ pModState->pPlugin->m_Name.c_str(), pModState->pPlugin->m_HwdID, self->Unit);
- }
- }
- }
- }
- else
- {
-- CPlugin *pPlugin = nullptr;
-- if (pModState) pPlugin = pModState->pPlugin;
-- _log.Log(LOG_ERROR, R"(Expected: myVar = Domoticz.Device(Name="myDevice", Unit=0, TypeName="", Type=0, Subtype=0, Switchtype=0, Image=0, Options={}, Used=1))");
-- LogPythonException(pPlugin, __func__);
-+ pModState->pPlugin->Log(LOG_ERROR, R"(Expected: myVar = Domoticz.Device(Name="myDevice", Unit=0, TypeName="", Type=0, Subtype=0, Switchtype=0, Image=0, Options={}, Used=1))");
-+ pModState->pPlugin->LogPythonException(__func__);
- }
- }
- catch (std::exception *e)
-@@ -745,12 +748,12 @@ namespace Plugins {
- {
- if (self->pPlugin->m_bDebug & PDM_DEVICE)
- {
-- _log.Log(LOG_NORM, "(%s) Creating device '%s'.", self->pPlugin->m_Name.c_str(), sName.c_str());
-+ self->pPlugin->Log(LOG_NORM, "Creating device '%s'.", sName.c_str());
- }
-
- if (!m_sql.m_bAcceptNewHardware)
- {
-- _log.Log(LOG_ERROR, "(%s) Device creation failed, Domoticz settings prevent accepting new devices.", self->pPlugin->m_Name.c_str());
-+ self->pPlugin->Log(LOG_ERROR, "Device creation failed, Domoticz settings prevent accepting new devices.");
- }
- else
- {
-@@ -792,9 +795,8 @@ namespace Plugins {
- PyNewRef pKey = PyLong_FromLong(self->Unit);
- if (PyDict_SetItem((PyObject*)self->pPlugin->m_DeviceDict, pKey, (PyObject*)self) == -1)
- {
-- _log.Log(LOG_ERROR, "(%s) failed to add unit '%d' to device dictionary.", self->pPlugin->m_Name.c_str(), self->Unit);
-- Py_INCREF(Py_None);
-- return Py_None;
-+ self->pPlugin->Log(LOG_ERROR, "Failed to add unit '%d' to device dictionary.", self->Unit);
-+ Py_RETURN_NONE;
- }
-
- // Device successfully created, now set the options when supplied
-@@ -817,18 +819,18 @@ namespace Plugins {
- }
- else
- {
-- _log.Log(LOG_ERROR, "(%s) Device creation failed, Hardware/Unit combination (%d:%d) not found in Domoticz.", self->pPlugin->m_Name.c_str(), self->HwdID, self->Unit);
-+ self->pPlugin->Log(LOG_ERROR, "Device creation failed, Hardware/Unit combination (%d:%d) not found in Domoticz.", self->HwdID, self->Unit);
- }
- }
- else
- {
-- _log.Log(LOG_ERROR, "(%s) Device creation failed, Hardware/Unit combination (%d:%d) already exists in Domoticz.", self->pPlugin->m_Name.c_str(), self->HwdID, self->Unit);
-+ self->pPlugin->Log(LOG_ERROR, "Device creation failed, Hardware/Unit combination (%d:%d) already exists in Domoticz.", self->HwdID, self->Unit);
- }
- }
- }
- else
- {
-- _log.Log(LOG_ERROR, "(%s) Device creation failed, '%s' already exists in Domoticz with Device ID '%d'.", self->pPlugin->m_Name.c_str(), sName.c_str(), self->ID);
-+ self->pPlugin->Log(LOG_ERROR, "Device creation failed, '%s' already exists in Domoticz with Device ID '%d'.", sName.c_str(), self->ID);
- }
- }
- else
-@@ -874,11 +876,10 @@ namespace Plugins {
-
- // Try to extract parameters needed to update device settings
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "is|iiiOissiiiissp", kwlist, &nValue, &sValue, &iImage, &iSignalLevel, &iBatteryLevel, &pOptionsDict, &iTimedOut, &Name, &TypeName, &iType, &iSubType, &iSwitchType, &iUsed, &Description, &Color, &SuppressTriggers))
-- {
-- _log.Log(LOG_ERROR, "(%s) %s: Failed to parse parameters: 'nValue', 'sValue', 'Image', 'SignalLevel', 'BatteryLevel', 'Options', 'TimedOut', 'Name', 'TypeName', 'Type', 'Subtype', 'Switchtype', 'Used', 'Description', 'Color' or 'SuppressTriggers' expected.", __func__, sName.c_str());
-- LogPythonException(self->pPlugin, __func__);
-- Py_INCREF(Py_None);
-- return Py_None;
-+ {
-+ self->pPlugin->Log(LOG_ERROR, "(%s) %s: Failed to parse parameters: 'nValue', 'sValue', 'Image', 'SignalLevel', 'BatteryLevel', 'Options', 'TimedOut', 'Name', 'TypeName', 'Type', 'Subtype', 'Switchtype', 'Used', 'Description', 'Color' or 'SuppressTriggers' expected.", __func__, sName.c_str());
-+ self->pPlugin->LogPythonException(__func__);
-+ Py_RETURN_NONE;
- }
-
- std::string sID = std::to_string(self->ID);
-@@ -979,7 +980,7 @@ namespace Plugins {
- }
-
- // Options provided, assume change
-- if (pOptionsDict && PyDict_Check(pOptionsDict))
-+ if (pOptionsDict && PyBorrowedRef(pOptionsDict).IsDict())
- {
- if (self->SubType != sTypeCustom)
- {
-@@ -1094,7 +1095,7 @@ namespace Plugins {
- {
- if (self->pPlugin->m_bDebug & PDM_DEVICE)
- {
-- _log.Log(LOG_NORM, "(%s) Deleting device '%s'.", self->pPlugin->m_Name.c_str(), sName.c_str());
-+ self->pPlugin->Log(LOG_NORM, "Deleting device '%s'.", sName.c_str());
- }
-
- std::vector<std::vector<std::string> > result;
-@@ -1106,19 +1107,18 @@ namespace Plugins {
- PyNewRef pKey = PyLong_FromLong(self->Unit);
- if (PyDict_DelItem((PyObject*)self->pPlugin->m_DeviceDict, pKey) == -1)
- {
-- _log.Log(LOG_ERROR, "(%s) failed to delete unit '%d' from device dictionary.", self->pPlugin->m_Name.c_str(), self->Unit);
-- Py_INCREF(Py_None);
-- return Py_None;
-+ self->pPlugin->Log(LOG_ERROR, "Failed to delete unit '%d' from device dictionary.", self->Unit);
-+ Py_RETURN_NONE;
- }
- }
- else
- {
-- _log.Log(LOG_ERROR, "(%s) Device deletion failed, Hardware/Unit combination (%d:%d) not found in Domoticz.", self->pPlugin->m_Name.c_str(), self->HwdID, self->Unit);
-+ self->pPlugin->Log(LOG_ERROR, "Device deletion failed, Hardware/Unit combination (%d:%d) not found in Domoticz.", self->HwdID, self->Unit);
- }
- }
- else
- {
-- _log.Log(LOG_ERROR, "(%s) Device deletion failed, '%s' does not represent a device in Domoticz.", self->pPlugin->m_Name.c_str(), sName.c_str());
-+ self->pPlugin->Log(LOG_ERROR, "Device deletion failed, '%s' does not represent a device in Domoticz.", sName.c_str());
- }
- }
- else
-@@ -1155,10 +1155,14 @@ namespace Plugins {
-
- void CConnection_dealloc(CConnection * self)
- {
-- CPlugin *pPlugin = CPlugin::FindPlugin();
-+ CPlugin *pPlugin = self->pPlugin;
-+ if (!pPlugin)
-+ {
-+ pPlugin = CPlugin::FindPlugin();
-+ }
- if (pPlugin && (pPlugin->m_bDebug & PDM_CONNECTION))
- {
-- _log.Log(LOG_NORM, "(%s) Deallocating connection object '%s' (%s:%s).", pPlugin->m_Name.c_str(), PyUnicode_AsUTF8(self->Name), PyUnicode_AsUTF8(self->Address), PyUnicode_AsUTF8(self->Port));
-+ pPlugin->Log(LOG_NORM, "Deallocating connection object '%s' (%s:%s).", PyUnicode_AsUTF8(self->Name), PyUnicode_AsUTF8(self->Address), PyUnicode_AsUTF8(self->Port));
- }
-
- Py_XDECREF(self->Target);
-@@ -1180,22 +1184,15 @@ namespace Plugins {
- self->pProtocol = nullptr;
- }
-
-- Py_TYPE(self)->tp_free((PyObject*)self);
-+ PyNewRef pType = PyObject_Type((PyObject*)self);
-+ freefunc pFree = (freefunc)PyType_GetSlot(pType, Py_tp_free);
-+ pFree((PyObject*)self);
- }
-
- PyObject * CConnection_new(PyTypeObject * type, PyObject * args, PyObject * kwds)
- {
-- CConnection *self = nullptr;
-- if ((CConnection *)type->tp_alloc)
-- {
-- self = (CConnection *)type->tp_alloc(type, 0);
-- }
-- else
-- {
-- //!Giz: self = NULL here!!
-- //_log.Log(LOG_ERROR, "(%s) CConnection Type is not ready.", self->pPlugin->m_Name.c_str());
-- _log.Log(LOG_ERROR, "(Python plugin) CConnection Type is not ready!");
-- }
-+ allocfunc pAlloc = (allocfunc)PyType_GetSlot(type, Py_tp_alloc);
-+ CConnection *self = (CConnection*)pAlloc(type, 0);
-
- try
- {
-@@ -1335,19 +1332,19 @@ namespace Plugins {
- if (pPlugin->IsStopRequested(0))
- {
- pPlugin->Log(LOG_NORM, "%s, connect request from '%s' ignored. Plugin is stopping.", __func__, self->pPlugin->m_Name.c_str());
-- return Py_None;
-+ Py_RETURN_NONE;
- }
-
- if (self->pTransport && self->pTransport->IsConnecting())
- {
- pPlugin->Log(LOG_ERROR, "%s, connect request from '%s' ignored. Transport is connecting.", __func__, self->pPlugin->m_Name.c_str());
-- return Py_None;
-+ Py_RETURN_NONE;
- }
-
- if (self->pTransport && self->pTransport->IsConnected())
- {
- pPlugin->Log(LOG_ERROR, "%s, connect request from '%s' ignored. Transport is connected.", __func__, self->pPlugin->m_Name.c_str());
-- return Py_None;
-+ Py_RETURN_NONE;
- }
-
- PyObject *pTarget = NULL;
-@@ -1457,7 +1454,7 @@ namespace Plugins {
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i", kwlist, &pData, &iDelay))
- {
- pPlugin->Log(LOG_ERROR, "(%s) failed to parse parameters, Message or Message, Delay expected.", pPlugin->m_Name.c_str());
-- LogPythonException(pPlugin, std::string(__func__));
-+ pPlugin->LogPythonException(__func__);
- }
- else
- {
---- a/hardware/plugins/PythonObjects.h
-+++ b/hardware/plugins/PythonObjects.h
-@@ -40,46 +40,6 @@ namespace Plugins {
- { nullptr } /* Sentinel */
- };
-
-- static PyTypeObject CImageType = {
-- PyVarObject_HEAD_INIT(nullptr, 0) "Domoticz.Image", /* tp_name */
-- sizeof(CImage), /* tp_basicsize */
-- 0, /* tp_itemsize */
-- (destructor)CImage_dealloc, /* tp_dealloc */
-- 0, /* tp_print */
-- nullptr, /* tp_getattr */
-- nullptr, /* tp_setattr */
-- nullptr, /* tp_reserved */
-- nullptr, /* tp_repr */
-- nullptr, /* tp_as_number */
-- nullptr, /* tp_as_sequence */
-- nullptr, /* tp_as_mapping */
-- nullptr, /* tp_hash */
-- nullptr, /* tp_call */
-- (reprfunc)CImage_str, /* tp_str */
-- nullptr, /* tp_getattro */
-- nullptr, /* tp_setattro */
-- nullptr, /* tp_as_buffer */
-- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-- "Domoticz Image", /* tp_doc */
-- nullptr, /* tp_traverse */
-- nullptr, /* tp_clear */
-- nullptr, /* tp_richcompare */
-- 0, /* tp_weaklistoffset */
-- nullptr, /* tp_iter */
-- nullptr, /* tp_iternext */
-- CImage_methods, /* tp_methods */
-- CImage_members, /* tp_members */
-- nullptr, /* tp_getset */
-- nullptr, /* tp_base */
-- nullptr, /* tp_dict */
-- nullptr, /* tp_descr_get */
-- nullptr, /* tp_descr_set */
-- 0, /* tp_dictoffset */
-- (initproc)CImage_init, /* tp_init */
-- nullptr, /* tp_alloc */
-- CImage_new /* tp_new */
-- };
--
- class CDevice
- {
- public:
-@@ -151,46 +111,6 @@ namespace Plugins {
- { nullptr } /* Sentinel */
- };
-
-- static PyTypeObject CDeviceType = {
-- PyVarObject_HEAD_INIT(nullptr, 0) "Domoticz.Device", /* tp_name */
-- sizeof(CDevice), /* tp_basicsize */
-- 0, /* tp_itemsize */
-- (destructor)CDevice_dealloc, /* tp_dealloc */
-- 0, /* tp_print */
-- nullptr, /* tp_getattr */
-- nullptr, /* tp_setattr */
-- nullptr, /* tp_reserved */
-- nullptr, /* tp_repr */
-- nullptr, /* tp_as_number */
-- nullptr, /* tp_as_sequence */
-- nullptr, /* tp_as_mapping */
-- nullptr, /* tp_hash */
-- nullptr, /* tp_call */
-- (reprfunc)CDevice_str, /* tp_str */
-- nullptr, /* tp_getattro */
-- nullptr, /* tp_setattro */
-- nullptr, /* tp_as_buffer */
-- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-- "Domoticz Device", /* tp_doc */
-- nullptr, /* tp_traverse */
-- nullptr, /* tp_clear */
-- nullptr, /* tp_richcompare */
-- 0, /* tp_weaklistoffset */
-- nullptr, /* tp_iter */
-- nullptr, /* tp_iternext */
-- CDevice_methods, /* tp_methods */
-- CDevice_members, /* tp_members */
-- nullptr, /* tp_getset */
-- nullptr, /* tp_base */
-- nullptr, /* tp_dict */
-- nullptr, /* tp_descr_get */
-- nullptr, /* tp_descr_set */
-- 0, /* tp_dictoffset */
-- (initproc)CDevice_init, /* tp_init */
-- nullptr, /* tp_alloc */
-- CDevice_new /* tp_new */
-- };
--
- class CPluginTransport;
- class CPluginProtocol;
-
-@@ -248,43 +168,4 @@ namespace Plugins {
- { nullptr } /* Sentinel */
- };
-
-- static PyTypeObject CConnectionType = {
-- PyVarObject_HEAD_INIT(nullptr, 0) "Domoticz.Connection", /* tp_name */
-- sizeof(CConnection), /* tp_basicsize */
-- 0, /* tp_itemsize */
-- (destructor)CConnection_dealloc, /* tp_dealloc */
-- 0, /* tp_print */
-- nullptr, /* tp_getattr */
-- nullptr, /* tp_setattr */
-- nullptr, /* tp_reserved */
-- nullptr, /* tp_repr */
-- nullptr, /* tp_as_number */
-- nullptr, /* tp_as_sequence */
-- nullptr, /* tp_as_mapping */
-- nullptr, /* tp_hash */
-- nullptr, /* tp_call */
-- (reprfunc)CConnection_str, /* tp_str */
-- nullptr, /* tp_getattro */
-- nullptr, /* tp_setattro */
-- nullptr, /* tp_as_buffer */
-- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-- "Domoticz Connection", /* tp_doc */
-- nullptr, /* tp_traverse */
-- nullptr, /* tp_clear */
-- nullptr, /* tp_richcompare */
-- 0, /* tp_weaklistoffset */
-- nullptr, /* tp_iter */
-- nullptr, /* tp_iternext */
-- CConnection_methods, /* tp_methods */
-- CConnection_members, /* tp_members */
-- nullptr, /* tp_getset */
-- nullptr, /* tp_base */
-- nullptr, /* tp_dict */
-- nullptr, /* tp_descr_get */
-- nullptr, /* tp_descr_set */
-- 0, /* tp_dictoffset */
-- (initproc)CConnection_init, /* tp_init */
-- nullptr, /* tp_alloc */
-- CConnection_new /* tp_new */
-- };
- } // namespace Plugins
---- a/main/EventSystem.cpp
-+++ b/main/EventSystem.cpp
-@@ -42,7 +42,6 @@ extern http::server::CWebServerHelper m_
- #include "../hardware/plugins/PluginMessages.h"
- #include "EventsPythonModule.h"
- #include "EventsPythonDevice.h"
--extern PyObject * PDevice_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
- #endif
-
- // Helper table for Blockly and SQL name mapping
-@@ -275,7 +274,7 @@ void CEventSystem::LoadEvents()
- {
- s = dzv_Dir + eitem.Name + ".lua";
- _log.Log(LOG_STATUS, "dzVents: Write file: %s", s.c_str());
-- FILE *fOut = fopen(s.c_str(), "wb+");
-+ FILE* fOut = fopen(s.c_str(), "wb+");
- if (fOut)
- {
- fwrite(eitem.Actions.c_str(), 1, eitem.Actions.size(), fOut);
---- a/main/EventsPythonDevice.cpp
-+++ b/main/EventsPythonDevice.cpp
-@@ -14,15 +14,21 @@
- Py_XDECREF(self->n_value_string);
- Py_XDECREF(self->s_value);
- Py_XDECREF(self->last_update_string);
-- Py_TYPE(self)->tp_free((PyObject*)self);
-- }
-+
-+ PyTypeObject* pType = (PyTypeObject*)PyObject_Type((PyObject*)self);
-+ freefunc pFree = (freefunc)PyType_GetSlot(pType, Py_tp_free);
-+ pFree((PyObject*)self);
-+ Py_XDECREF(pType);
-+ }
-
- PyObject *
- PDevice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
- PDevice *self;
-
-- self = (PDevice *)type->tp_alloc(type, 0);
-+ allocfunc pAlloc = (allocfunc)PyType_GetSlot(type, Py_tp_alloc);
-+ self = (PDevice*)pAlloc(type, 0);
-+
- if (self != nullptr)
- {
- self->name = PyUnicode_FromString("");
---- a/main/EventsPythonDevice.h
-+++ b/main/EventsPythonDevice.h
-@@ -47,7 +47,7 @@
-
- static PyModuleDef PDevicemodule = { PyModuleDef_HEAD_INIT,
- "DomoticzEvents",
-- "Example module that creates an extension type.",
-+ "DomoticzEvents module type.",
- -1,
- nullptr,
- nullptr,
-@@ -55,44 +55,6 @@
- nullptr,
- nullptr };
-
-- static PyTypeObject PDeviceType = {
-- PyVarObject_HEAD_INIT(nullptr, 0) "DomoticzEvents.PDevice", /* tp_name */
-- sizeof(PDevice), /* tp_basicsize */
-- 0, /* tp_itemsize */
-- (destructor)PDevice_dealloc, /* tp_dealloc */
-- 0, /* tp_print */
-- 0, /* tp_getattr */
-- 0, /* tp_setattr */
-- 0, /* tp_reserved */
-- 0, /* tp_repr */
-- 0, /* tp_as_number */
-- 0, /* tp_as_sequence */
-- 0, /* tp_as_mapping */
-- 0, /* tp_hash */
-- 0, /* tp_call */
-- 0, /* tp_str */
-- 0, /* tp_getattro */
-- 0, /* tp_setattro */
-- 0, /* tp_as_buffer */
-- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-- "PDevice objects", /* tp_doc */
-- 0, /* tp_traverse */
-- 0, /* tp_clear */
-- 0, /* tp_richcompare */
-- 0, /* tp_weaklistoffset */
-- 0, /* tp_iter */
-- 0, /* tp_iternext */
-- PDevice_methods, /* tp_methods */
-- PDevice_members, /* tp_members */
-- 0, /* tp_getset */
-- 0, /* tp_base */
-- 0, /* tp_dict */
-- 0, /* tp_descr_get */
-- 0, /* tp_descr_set */
-- 0, /* tp_dictoffset */
-- (initproc)PDevice_init, /* tp_init */
-- 0, /* tp_alloc */
-- PDevice_new, /* tp_new */
-- };
-+ static PyObject* PDeviceType;
- }
- #endif
---- a/main/EventsPythonModule.cpp
-+++ b/main/EventsPythonModule.cpp
-@@ -6,22 +6,27 @@
- #include "EventSystem.h"
- #include "mainworker.h"
- #include "localtime_r.h"
-+#include "../hardware/plugins/Plugins.h"
-
--#ifdef ENABLE_PYTHON
--
-- namespace Plugins {
-- #define GETSTATE(m) ((struct eventModule_state*)PyModule_GetState(m))
-+#include <fstream>
-
-- void* m_PyInterpreter;
-- bool ModuleInitialized = false;
-+#ifdef ENABLE_PYTHON
-
-- struct eventModule_state {
-- PyObject* error;
-- };
--
-- static PyMethodDef DomoticzEventsMethods[] = { { "Log", PyDomoticz_EventsLog, METH_VARARGS, "Write message to Domoticz log." },
-- { "Command", PyDomoticz_EventsCommand, METH_VARARGS, "Schedule a command." },
-- { nullptr, nullptr, 0, nullptr } };
-+namespace Plugins
-+{
-+#define GETSTATE(m) ((struct eventModule_state*)PyModule_GetState(m))
-+
-+ void* m_PyInterpreter;
-+ bool ModuleInitialized = false;
-+
-+ struct eventModule_state {
-+ PyObject* error;
-+ };
-+
-+ static PyMethodDef DomoticzEventsMethods[] = {
-+ { "Log", PyDomoticz_EventsLog, METH_VARARGS, "Write message to Domoticz log." },
-+ { "Command", PyDomoticz_EventsCommand, METH_VARARGS, "Schedule a command." },
-+ { nullptr, nullptr, 0, nullptr } };
-
- static int DomoticzEventsTraverse(PyObject *m, visitproc visit, void *arg)
- {
-@@ -44,7 +49,6 @@
- if (!PyArg_ParseTuple(args, "s", &msg))
- {
- _log.Log(LOG_ERROR, "Pyhton Event System: Failed to parse parameters: string expected.");
-- // LogPythonException(pModState->pPlugin, std::string(__func__));
- }
- else
- {
-@@ -52,8 +56,7 @@
- _log.Log((_eLogLevel)LOG_NORM, message);
- }
-
-- Py_INCREF(Py_None);
-- return Py_None;
-+ Py_RETURN_NONE;
- }
-
- static PyObject *PyDomoticz_EventsCommand(PyObject *self, PyObject *args)
-@@ -68,7 +71,6 @@
- if (!PyArg_ParseTuple(args, "ss", &device, &action))
- {
- _log.Log(LOG_ERROR, "Pyhton EventSystem: Failed to parse parameters: Two strings expected.");
-- // LogPythonException(pModState->pPlugin, std::string(__func__));
- }
- else
- {
-@@ -78,13 +80,20 @@
- m_mainworker.m_eventsystem.PythonScheduleEvent(device, action, "Test");
- }
-
-- Py_INCREF(Py_None);
-- return Py_None;
-+ Py_RETURN_NONE;
- }
-
-- struct PyModuleDef DomoticzEventsModuleDef
-- = { PyModuleDef_HEAD_INIT, "DomoticzEvents", nullptr, sizeof(struct eventModule_state), DomoticzEventsMethods, nullptr,
-- DomoticzEventsTraverse, DomoticzEventsClear, nullptr };
-+ struct PyModuleDef DomoticzEventsModuleDef = {
-+ PyModuleDef_HEAD_INIT,
-+ "DomoticzEvents",
-+ nullptr,
-+ sizeof(struct eventModule_state),
-+ DomoticzEventsMethods,
-+ nullptr,
-+ DomoticzEventsTraverse,
-+ DomoticzEventsClear,
-+ nullptr
-+ };
-
- PyMODINIT_FUNC PyInit_DomoticzEvents(void)
- {
-@@ -94,6 +103,22 @@
- _log.Log(LOG_STATUS, "Python EventSystem: Initializing event module.");
-
- PyObject *pModule = PyModule_Create2(&DomoticzEventsModuleDef, PYTHON_API_VERSION);
-+
-+ PyType_Slot PDeviceSlots[] = {
-+ { Py_tp_doc, (void*)"PDevice objects" },
-+ { Py_tp_new, (void*)PDevice_new },
-+ { Py_tp_init, (void*)PDevice_init },
-+ { Py_tp_dealloc, (void*)PDevice_dealloc },
-+ { Py_tp_members, PDevice_members },
-+ { Py_tp_methods, PDevice_methods },
-+ { 0, nullptr },
-+ };
-+ PyType_Spec PDeviceSpec = { "DomoticzEvents.PDevice", sizeof(PDevice), 0,
-+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, PDeviceSlots };
-+
-+ PDeviceType = PyType_FromSpec(&PDeviceSpec);
-+ PyModule_AddObject(pModule, "PDevice", (PyObject*)PDeviceType);
-+
- return pModule;
- }
-
-@@ -166,22 +191,21 @@
-
- PyObject *PythonEventsGetModule()
- {
-- PyObject *pModule = PyState_FindModule(&DomoticzEventsModuleDef);
-+ PyBorrowedRef pModule = PyState_FindModule(&DomoticzEventsModuleDef);
-
- if (pModule)
- {
- // _log.Log(LOG_STATUS, "Python Event System: Module found");
- return pModule;
- }
-- Plugins::PyRun_SimpleStringFlags("import DomoticzEvents", nullptr);
-+ PyImport_ImportModule("DomoticzEvents");
- pModule = PyState_FindModule(&DomoticzEventsModuleDef);
-
- if (pModule)
- {
- return pModule;
- }
-- // Py_INCREF(Py_None);
-- // return Py_None;
-+
- return nullptr;
- }
-
-@@ -189,7 +213,70 @@
-
- PyObject *mapToPythonDict(const std::map<std::string, float> &floatMap)
- {
-- return Py_None;
-+ Py_RETURN_NONE;
-+ }
-+
-+ void LogPythonException()
-+ {
-+ PyNewRef pTraceback;
-+ PyNewRef pExcept;
-+ PyNewRef pValue;
-+
-+ PyErr_Fetch(&pExcept, &pValue, &pTraceback);
-+ PyErr_NormalizeException(&pExcept, &pValue, &pTraceback);
-+
-+ if (!pExcept && !pValue && !pTraceback)
-+ {
-+ _log.Log(LOG_ERROR, "Unable to decode exception.");
-+ }
-+ else
-+ {
-+ std::string sTypeText("Unknown");
-+ if (pExcept)
-+ {
-+ PyTypeObject* TypeName = (PyTypeObject*)pExcept;
-+ PyNewRef pName = PyObject_GetAttrString((PyObject*)TypeName, "__name__");
-+ sTypeText = (std::string)pName;
-+ }
-+
-+ /* See if we can get a full traceback */
-+ PyNewRef pModule = PyImport_ImportModule("traceback");
-+ if (pModule)
-+ {
-+ PyNewRef pFunc = PyObject_GetAttrString(pModule, "format_exception");
-+ if (pFunc && PyCallable_Check(pFunc)) {
-+ PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, pExcept, pValue, pTraceback, NULL);
-+ if (pList)
-+ {
-+ for (Py_ssize_t i = 0; i < PyList_Size(pList); i++)
-+ {
-+ PyBorrowedRef pPyStr = PyList_GetItem(pList, i);
-+ std::string pStr(pPyStr);
-+ size_t pos = 0;
-+ std::string token;
-+ while ((pos = pStr.find('\n')) != std::string::npos) {
-+ token = pStr.substr(0, pos);
-+ _log.Log(LOG_ERROR, "%s", token.c_str());
-+ pStr.erase(0, pos + 1);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ _log.Log(LOG_ERROR, "Exception: '%s'. No traceback available.", sTypeText.c_str());
-+ }
-+ }
-+ else
-+ {
-+ _log.Log(LOG_ERROR, "'format_exception' lookup failed, exception: '%s'. No traceback available.", sTypeText.c_str());
-+ }
-+ }
-+ else
-+ {
-+ _log.Log(LOG_ERROR, "'Traceback' module import failed, exception: '%s'. No traceback available.", sTypeText.c_str());
-+ }
-+ }
-+ PyErr_Clear();
- }
-
- void PythonEventsProcessPython(const std::string &reason, const std::string &filename, const std::string &PyString,
-@@ -202,22 +289,15 @@
- return;
- }
-
-- if (Plugins::Py_IsInitialized())
-+ if (Py_IsInitialized())
- {
--
- if (m_PyInterpreter)
- PyEval_RestoreThread((PyThreadState *)m_PyInterpreter);
-
-- /*{
-- _log.Log(LOG_ERROR, "EventSystem - Python: Failed to attach to interpreter");
-- }*/
--
-- PyObject *pModule = Plugins::PythonEventsGetModule();
-+ PyBorrowedRef pModule = PythonEventsGetModule();
- if (pModule)
- {
--
-- PyObject *pModuleDict = Plugins::PyModule_GetDict((PyObject *)pModule); // borrowed referece
--
-+ PyBorrowedRef pModuleDict = Plugins::PyModule_GetDict(pModule);
- if (!pModuleDict)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to open module dictionary.");
-@@ -225,26 +305,22 @@
- return;
- }
-
-- if (Plugins::PyDict_SetItemString(
-- pModuleDict, "changed_device_name",
-- Plugins::PyUnicode_FromString(m_devicestates[DeviceID].deviceName.c_str()))
-- == -1)
-+ PyNewRef pStrVal = PyUnicode_FromString(m_devicestates[DeviceID].deviceName.c_str());
-+ if (PyDict_SetItemString(pModuleDict, "changed_device_name", pStrVal) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to set changed_device_name.");
- return;
- }
-
-- PyObject *m_DeviceDict = Plugins::PyDict_New();
--
-- if (Plugins::PyDict_SetItemString(pModuleDict, "Devices", (PyObject *)m_DeviceDict) == -1)
-+ PyNewRef pDeviceDict = Plugins::PyDict_New();
-+ if (PyDict_SetItemString(pModuleDict, "Devices", pDeviceDict) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add Device dictionary.");
- PyEval_SaveThread();
- return;
- }
-- Py_DECREF(m_DeviceDict);
-
-- if (Plugins::PyType_Ready(&Plugins::PDeviceType) < 0)
-+ if (PyType_Ready((PyTypeObject*)Plugins::PDeviceType) < 0)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Unable to ready DeviceType Object.");
- PyEval_SaveThread();
-@@ -261,13 +337,12 @@
- // sitem.subType, sitem.switchtype, sitem.nValue, sitem.nValueWording, sitem.sValue,
- // sitem.lastUpdate); devices[sitem.deviceName] = deviceStatus;
-
-- Plugins::PDevice *aDevice = (Plugins::PDevice *)Plugins::PDevice_new(
-- &Plugins::PDeviceType, (PyObject *)nullptr, (PyObject *)nullptr);
-- PyObject *pKey = Plugins::PyUnicode_FromString(sitem.deviceName.c_str());
-+ PDevice *aDevice = (PDevice *)PDevice_new((PyTypeObject*)PDeviceType, (PyObject *)nullptr, (PyObject *)nullptr);
-+ PyNewRef pKey = PyUnicode_FromString(sitem.deviceName.c_str());
-
- if (sitem.ID == DeviceID)
- {
-- if (Plugins::PyDict_SetItemString(pModuleDict, "changed_device", (PyObject *)aDevice) == -1)
-+ if (PyDict_SetItemString(pModuleDict, "changed_device", (PyObject *)aDevice) == -1)
- {
- _log.Log(LOG_ERROR,
- "Python EventSystem: Failed to add device '%s' as changed_device.",
-@@ -275,7 +350,7 @@
- }
- }
-
-- if (Plugins::PyDict_SetItem((PyObject *)m_DeviceDict, pKey, (PyObject *)aDevice) == -1)
-+ if (PyDict_SetItem(pDeviceDict, pKey, (PyObject *)aDevice) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add device '%s' to device dictionary.",
- sitem.deviceName.c_str());
-@@ -291,19 +366,18 @@
- // If nValueWording contains %, unicode fails?
-
- aDevice->id = static_cast<int>(sitem.ID);
-- aDevice->name = Plugins::PyUnicode_FromString(sitem.deviceName.c_str());
-+ aDevice->name = PyUnicode_FromString(sitem.deviceName.c_str());
- aDevice->type = sitem.devType;
- aDevice->sub_type = sitem.subType;
- aDevice->switch_type = sitem.switchtype;
- aDevice->n_value = sitem.nValue;
-- aDevice->n_value_string = Plugins::PyUnicode_FromString(temp_n_value_string.c_str());
-+ aDevice->n_value_string = PyUnicode_FromString(temp_n_value_string.c_str());
- aDevice->s_value = Plugins::PyUnicode_FromString(sitem.sValue.c_str());
-- aDevice->last_update_string = Plugins::PyUnicode_FromString(sitem.lastUpdate.c_str());
-+ aDevice->last_update_string = PyUnicode_FromString(sitem.lastUpdate.c_str());
- // _log.Log(LOG_STATUS, "Python EventSystem: deviceName %s added to device dictionary",
- // sitem.deviceName.c_str());
- }
- Py_DECREF(aDevice);
-- Py_DECREF(pKey);
- }
- // devicestatesMutexLock1.unlock();
-
-@@ -315,28 +389,24 @@
- localtime_r(&now, <ime);
- int minutesSinceMidnight = (ltime.tm_hour * 60) + ltime.tm_min;
-
-- if (Plugins::PyDict_SetItemString(pModuleDict, "minutes_since_midnight",
-- Plugins::PyLong_FromLong(minutesSinceMidnight))
-- == -1)
-+ PyNewRef pPyLong = PyLong_FromLong(minutesSinceMidnight);
-+ if (PyDict_SetItemString(pModuleDict, "minutes_since_midnight", pPyLong) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add 'minutesSinceMidnight' to module_dict");
- }
-
-- if (Plugins::PyDict_SetItemString(pModuleDict, "sunrise_in_minutes", Plugins::PyLong_FromLong(intSunRise))
-- == -1)
-+ pPyLong = PyLong_FromLong(intSunRise);
-+ if (PyDict_SetItemString(pModuleDict, "sunrise_in_minutes", pPyLong) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add 'sunrise_in_minutes' to module_dict");
- }
-
-- if (Plugins::PyDict_SetItemString(pModuleDict, "sunset_in_minutes", Plugins::PyLong_FromLong(intSunSet))
-- == -1)
-+ pPyLong = PyLong_FromLong(intSunSet);
-+ if (PyDict_SetItemString(pModuleDict, "sunset_in_minutes", pPyLong) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add 'sunset_in_minutes' to module_dict");
- }
--
-- // PyObject* dayTimeBool = Py_False;
-- // PyObject* nightTimeBool = Py_False;
--
-+
- bool isDaytime = false;
- bool isNightime = false;
-
-@@ -349,75 +419,121 @@
- isNightime = true;
- }
-
-- if (Plugins::PyDict_SetItemString(pModuleDict, "is_daytime", Plugins::PyBool_FromLong(isDaytime)) == -1)
-+ PyNewRef pPyBool = PyBool_FromLong(isDaytime);
-+ if (PyDict_SetItemString(pModuleDict, "is_daytime", pPyBool) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add 'is_daytime' to module_dict");
- }
-
-- if (Plugins::PyDict_SetItemString(pModuleDict, "is_nighttime", Plugins::PyBool_FromLong(isNightime)) == -1)
-+ pPyBool = PyBool_FromLong(isNightime);
-+ if (PyDict_SetItemString(pModuleDict, "is_nighttime", pPyBool) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add 'is_daytime' to module_dict");
- }
-
- // UserVariables
-- PyObject *m_uservariablesDict = Plugins::PyDict_New();
--
-- if (Plugins::PyDict_SetItemString(pModuleDict, "user_variables", (PyObject *)m_uservariablesDict) == -1)
-+ PyNewRef userVariablesDict = PyDict_New();
-+ if (PyDict_SetItemString(pModuleDict, "user_variables", userVariablesDict) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add uservariables dictionary.");
- PyEval_SaveThread();
- return;
- }
-- Py_DECREF(m_uservariablesDict);
--
-- // This doesn't work
-- // boost::unique_lock<boost::shared_mutex> uservariablesMutexLock2 (m_uservariablesMutex);
-
- for (auto it_var = m_uservariables.begin(); it_var != m_uservariables.end(); ++it_var)
- {
- CEventSystem::_tUserVariable uvitem = it_var->second;
-- Plugins::PyDict_SetItemString(m_uservariablesDict, uvitem.variableName.c_str(),
-- Plugins::PyUnicode_FromString(uvitem.variableValue.c_str()));
-+ PyDict_SetItemString(userVariablesDict, uvitem.variableName.c_str(),
-+ PyUnicode_FromString(uvitem.variableValue.c_str()));
- }
-
-- // uservariablesMutexLock2.unlock();
--
- // Add __main__ module
-- PyObject *pModule = Plugins::PyImport_AddModule("__main__");
-- Py_INCREF(pModule);
-+ PyBorrowedRef pMainModule = PyImport_AddModule("__main__");
-+ PyBorrowedRef global_dict = PyModule_GetDict(pMainModule);
-+ PyNewRef local_dict = PyDict_New();
-
- // Override sys.stderr
-- Plugins::PyRun_SimpleStringFlags("import sys\nclass StdErrRedirect:\n def __init__(self):\n "
-- "self.buffer = ''\n def write(self, "
-- "msg):\n self.buffer += msg\nstdErrRedirect = "
-- "StdErrRedirect()\nsys.stderr = stdErrRedirect\n",
-- nullptr);
-+ {
-+ PyNewRef pCode = Py_CompileString("import sys\nclass StdErrRedirect:\n def __init__(self):\n "
-+ "self.buffer = ''\n def write(self, "
-+ "msg):\n self.buffer += msg\nstdErrRedirect = "
-+ "StdErrRedirect()\nsys.stderr = stdErrRedirect\n",
-+ filename.c_str(), Py_file_input);
-+ if (pCode)
-+ {
-+ PyNewRef pEval = PyEval_EvalCode(pCode, global_dict, local_dict);
-+ }
-+ else
-+ {
-+ _log.Log(LOG_ERROR, "EventSystem: Failed to compile stderror redirection for event script '%s'", reason.c_str());
-+ }
-+ }
-
-- if (PyString.length() > 0)
-+ if (!PyErr_Occurred() && (PyString.length() > 0))
- {
- // Python-string from WebEditor
-- Plugins::PyRun_SimpleStringFlags(PyString.c_str(), nullptr);
-+ PyNewRef pCode = Py_CompileString(PyString.c_str(), filename.c_str(), Py_file_input);
-+ if (pCode)
-+ {
-+ PyNewRef pEval = PyEval_EvalCode(pCode, global_dict, local_dict);
-+ }
-+ else
-+ {
-+ _log.Log(LOG_ERROR, "EventSystem: Failed to compile python '%s' event script '%s'", reason.c_str(), filename.c_str());
-+ }
- }
- else
- {
- // Script-file
-- FILE *PythonScriptFile = fopen(filename.c_str(), "r");
-- Plugins::PyRun_SimpleFileExFlags(PythonScriptFile, filename.c_str(), 0, nullptr);
-+ std::ifstream PythonScriptFile(filename.c_str());
-+ if (PythonScriptFile.is_open())
-+ {
-+ char PyLine[256];
-+ std::string PyString;
-+ while (PythonScriptFile.getline(PyLine, sizeof(PyLine), '\n'))
-+ {
-+ PyString.append(PyLine);
-+ PyString += '\n';
-+ }
-+ PythonScriptFile.close();
-+
-+ PyNewRef pCode = Py_CompileString(PyString.c_str(), filename.c_str(), Py_file_input);
-+ if (pCode)
-+ {
-+ PyNewRef pEval = PyEval_EvalCode(pCode, global_dict, local_dict);
-+ }
-+ else
-+ {
-+ _log.Log(LOG_ERROR, "EventSystem: Failed to compile python '%s' event script file '%s'", reason.c_str(), filename.c_str());
-+ }
-+ }
-+ else
-+ {
-+ _log.Log(LOG_ERROR, "EventSystem: Failed to open python script file '%s'", filename.c_str());
-+ }
-+ }
-
-- if (PythonScriptFile != nullptr)
-- fclose(PythonScriptFile);
-+ // Log any exceptions
-+ if (PyErr_Occurred())
-+ {
-+ LogPythonException();
- }
-
- // Get message from stderr redirect
-- PyObject *stdErrRedirect = nullptr, *logBuffer = nullptr, *logBytes = nullptr;
- std::string logString;
-- if ((stdErrRedirect = Plugins::PyObject_GetAttrString(pModule, "stdErrRedirect")) == nullptr)
-- goto free_module;
-- if ((logBuffer = Plugins::PyObject_GetAttrString(stdErrRedirect, "buffer")) == nullptr)
-- goto free_stderrredirect;
-- if ((logBytes = PyUnicode_AsUTF8String(logBuffer)) == nullptr)
-- goto free_logbuffer;
-- logString.append(PyBytes_AsString(logBytes));
-+ if (PyObject_HasAttrString(pModule, "stdErrRedirect"))
-+ {
-+ PyNewRef stdErrRedirect = PyObject_GetAttrString(pModule, "stdErrRedirect");
-+ if (PyObject_HasAttrString(stdErrRedirect, "buffer"))
-+ {
-+ PyNewRef logBuffer = PyObject_GetAttrString(stdErrRedirect, "buffer");
-+ PyNewRef logBytes = PyUnicode_AsUTF8String(logBuffer);
-+ if (logBytes)
-+ {
-+ logString.append(PyBytes_AsString(logBytes));
-+ }
-+ }
-+ }
-
- // Check if there were some errors written to stderr
- if (logString.length() > 0)
-@@ -436,15 +552,6 @@
- logString = logString.substr(lineBreakPos + 1);
- }
- }
--
-- // Cleanup
-- Py_DECREF(logBytes);
-- free_logbuffer:
-- Py_DECREF(logBuffer);
-- free_stderrredirect:
-- Py_DECREF(stdErrRedirect);
-- free_module:
-- Py_DECREF(pModule);
- }
- else
- {
-@@ -458,5 +565,5 @@
- _log.Log(LOG_ERROR, "EventSystem: Python not Initialized");
- }
- }
-- } // namespace Plugins
-+} // namespace Plugins
- #endif
---- a/main/SQLHelper.cpp
-+++ b/main/SQLHelper.cpp
-@@ -5226,7 +5226,7 @@ uint64_t CSQLHelper::UpdateValueInt(
- )
- {
- if (
-- (pHardware->HwdType != HTYPE_MQTTAutoDiscovery)
-+ (HWtype != HTYPE_MQTTAutoDiscovery)
- &&
- (switchtype == STYPE_BlindsPercentage
- || switchtype == STYPE_BlindsPercentageWithStop
+++ /dev/null
-From a9df45497dc79023ed1864dd9b8e435935220171 Mon Sep 17 00:00:00 2001
-From: dnpwwo <kendel.boul@gmail.com>
-Date: Tue, 1 Mar 2022 13:09:01 +1100
-Subject: [PATCH] BugFix: Linux crash when formating Python exceptions Other:
- Continue code cleanup
-
----
- hardware/plugins/Plugins.cpp | 45 +++++++++++-------------------------
- hardware/plugins/Plugins.h | 3 ++-
- main/EventsPythonModule.cpp | 6 ++---
- 3 files changed, 18 insertions(+), 36 deletions(-)
-
---- a/hardware/plugins/Plugins.cpp
-+++ b/hardware/plugins/Plugins.cpp
-@@ -724,13 +724,7 @@ namespace Plugins
- }
- else
- {
-- std::string sTypeText("Unknown");
-- if (pExcept)
-- {
-- PyTypeObject* TypeName = (PyTypeObject*)pExcept;
-- PyNewRef pName = PyObject_GetAttrString((PyObject*)TypeName, "__name__");
-- sTypeText = (std::string)pName;
-- }
-+ std::string sTypeText("Unknown Error");
-
- /* See if we can get a full traceback */
- PyNewRef pModule = PyImport_ImportModule("traceback");
-@@ -738,7 +732,7 @@ namespace Plugins
- {
- PyNewRef pFunc = PyObject_GetAttrString(pModule, "format_exception");
- if (pFunc && PyCallable_Check(pFunc)) {
-- PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, pExcept, pValue, pTraceback, NULL);
-+ PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, (PyObject*)pExcept, (PyObject*)pValue, (PyObject*)pTraceback, NULL);
- if (pList)
- {
- for (Py_ssize_t i = 0; i < PyList_Size(pList); i++)
-@@ -756,16 +750,19 @@ namespace Plugins
- }
- else
- {
-+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
- Log(LOG_ERROR, "Exception: '%s'. No traceback available.", sTypeText.c_str());
- }
- }
- else
- {
-+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
- Log(LOG_ERROR, "'format_exception' lookup failed, exception: '%s'. No traceback available.", sTypeText.c_str());
- }
- }
- else
- {
-+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
- Log(LOG_ERROR, "'Traceback' module import failed, exception: '%s'. No traceback available.", sTypeText.c_str());
- }
- }
-@@ -1950,7 +1947,7 @@ namespace Plugins
- }
- }
-
-- void CPlugin::Callback(PyObject *pTarget, const std::string &sHandler, PyObject *pParams)
-+ void CPlugin::Callback(PyBorrowedRef& pTarget, const std::string &sHandler, PyObject *pParams)
- {
- try
- {
-@@ -1966,19 +1963,8 @@ namespace Plugins
- PyNewRef pFunc = PyObject_GetAttrString(pTarget, sHandler.c_str());
- if (pFunc && PyCallable_Check(pFunc))
- {
-- module_state *pModState = nullptr;
-- PyBorrowedRef brModule = PyState_FindModule(&DomoticzModuleDef);
-- if (!brModule)
-- {
-- brModule = PyState_FindModule(&DomoticzExModuleDef);
-- }
--
-- if (brModule)
-- {
-- pModState = ((struct module_state *)PyModule_GetState(brModule));
-- }
--
- // Store the callback object so the Dump function has context if invoked
-+ module_state* pModState = FindModule();
- if (pModState)
- {
- pModState->lastCallback = pTarget;
-@@ -1986,14 +1972,12 @@ namespace Plugins
-
- if (m_bDebug & PDM_QUEUE)
- {
-- PyNewRef pName = PyObject_GetAttrString((PyObject*)(pTarget->ob_type), "__name__");
-- if (pName)
-- Log(LOG_NORM, "Calling message handler '%s' on '%s' type object.", sHandler.c_str(), (std::string(pName).c_str()));
-+ Log(LOG_NORM, "Calling message handler '%s' on '%s' type object.", sHandler.c_str(), pTarget.Type().c_str());
- }
-
- PyErr_Clear();
-
-- // Invokde the callback function
-+ // Invoke the callback function
- PyNewRef pReturnValue = PyObject_CallObject(pFunc, pParams);
-
- if (pModState)
-@@ -2020,17 +2004,14 @@ namespace Plugins
- std::string sAttrName = pItem;
- if (sAttrName.substr(0, 2) != "__") // ignore system stuff
- {
-- if (PyObject_HasAttrString(pTarget, sAttrName.c_str()))
-+ std::string strValue = pTarget.Attribute(sAttrName);
-+ if (strValue.length())
- {
- PyNewRef pValue = PyObject_GetAttrString(pTarget, sAttrName.c_str());
- if (!PyCallable_Check(pValue)) // Filter out methods
- {
-- std::string strValue = pValue;
-- if (strValue.length())
-- {
-- std::string sBlank((sAttrName.length() < 20) ? 20 - sAttrName.length() : 0, ' ');
-- Log(LOG_NORM, " ----> '%s'%s '%s'", sAttrName.c_str(), sBlank.c_str(), strValue.c_str());
-- }
-+ std::string sBlank((sAttrName.length() < 20) ? 20 - sAttrName.length() : 0, ' ');
-+ Log(LOG_NORM, " ----> '%s'%s '%s'", sAttrName.c_str(), sBlank.c_str(), strValue.c_str());
- }
- }
- }
---- a/hardware/plugins/Plugins.h
-+++ b/hardware/plugins/Plugins.h
-@@ -92,7 +92,7 @@ namespace Plugins {
- void ConnectionWrite(CDirectiveBase *);
- void ConnectionDisconnect(CDirectiveBase *);
- void DisconnectEvent(CEventBase *);
-- void Callback(PyObject* pTarget, const std::string &sHandler, PyObject *pParams);
-+ void Callback(PyBorrowedRef& pTarget, const std::string &sHandler, PyObject *pParams);
- void RestoreThread();
- void ReleaseThread();
- void Stop();
-@@ -157,6 +157,7 @@ namespace Plugins {
- m_pObject = pObject;
- };
- std::string Attribute(const char* name);
-+ std::string Attribute(std::string& name) { return Attribute(name.c_str()); };
- std::string Type();
- bool IsDict() { return TypeCheck(Py_TPFLAGS_DICT_SUBCLASS); };
- bool IsList() { return TypeCheck(Py_TPFLAGS_LIST_SUBCLASS); };
---- a/main/EventsPythonModule.cpp
-+++ b/main/EventsPythonModule.cpp
-@@ -297,7 +297,7 @@ namespace Plugins
- PyBorrowedRef pModule = PythonEventsGetModule();
- if (pModule)
- {
-- PyBorrowedRef pModuleDict = Plugins::PyModule_GetDict(pModule);
-+ PyBorrowedRef pModuleDict = PyModule_GetDict(pModule);
- if (!pModuleDict)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to open module dictionary.");
-@@ -312,7 +312,7 @@ namespace Plugins
- return;
- }
-
-- PyNewRef pDeviceDict = Plugins::PyDict_New();
-+ PyNewRef pDeviceDict = PyDict_New();
- if (PyDict_SetItemString(pModuleDict, "Devices", pDeviceDict) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add Device dictionary.");
-@@ -320,7 +320,7 @@ namespace Plugins
- return;
- }
-
-- if (PyType_Ready((PyTypeObject*)Plugins::PDeviceType) < 0)
-+ if (PyType_Ready((PyTypeObject*)PDeviceType) < 0)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Unable to ready DeviceType Object.");
- PyEval_SaveThread();
+++ /dev/null
-From 90e683a16ec1f267d3efd1b3fd1bff0b9ac9691e Mon Sep 17 00:00:00 2001
-From: dnpwwo <kendel.boul@gmail.com>
-Date: Tue, 1 Mar 2022 22:01:14 +1100
-Subject: [PATCH] BugFix: Prevent crash processing Python exceptions on Linux.
- Uplift: Create Device objects using Python rather than C++
-
----
- main/EventsPythonDevice.h | 2 +-
- main/EventsPythonModule.cpp | 92 ++++++++++++++++---------------------
- 2 files changed, 40 insertions(+), 54 deletions(-)
-
---- a/main/EventsPythonDevice.h
-+++ b/main/EventsPythonDevice.h
-@@ -55,6 +55,6 @@
- nullptr,
- nullptr };
-
-- static PyObject* PDeviceType;
-+ static PyTypeObject* PDeviceType;
- }
- #endif
---- a/main/EventsPythonModule.cpp
-+++ b/main/EventsPythonModule.cpp
-@@ -16,11 +16,11 @@ namespace Plugins
- {
- #define GETSTATE(m) ((struct eventModule_state*)PyModule_GetState(m))
-
-- void* m_PyInterpreter;
-- bool ModuleInitialized = false;
-+ PyThreadState* m_PyInterpreter;
-+ bool m_ModuleInitialized = false;
-
- struct eventModule_state {
-- PyObject* error;
-+ PyObject* error;
- };
-
- static PyMethodDef DomoticzEventsMethods[] = {
-@@ -116,7 +116,7 @@ namespace Plugins
- PyType_Spec PDeviceSpec = { "DomoticzEvents.PDevice", sizeof(PDevice), 0,
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, PDeviceSlots };
-
-- PDeviceType = PyType_FromSpec(&PDeviceSpec);
-+ PDeviceType = (PyTypeObject*)PyType_FromSpec(&PDeviceSpec);
- PyModule_AddObject(pModule, "PDevice", (PyObject*)PDeviceType);
-
- return pModule;
-@@ -169,7 +169,7 @@ namespace Plugins
- _log.Log(LOG_ERROR, "EventSystem - Python: Failed to initialize module.");
- return false;
- }
-- ModuleInitialized = true;
-+ m_ModuleInitialized = true;
- return true;
- }
-
-@@ -232,12 +232,6 @@ namespace Plugins
- else
- {
- std::string sTypeText("Unknown");
-- if (pExcept)
-- {
-- PyTypeObject* TypeName = (PyTypeObject*)pExcept;
-- PyNewRef pName = PyObject_GetAttrString((PyObject*)TypeName, "__name__");
-- sTypeText = (std::string)pName;
-- }
-
- /* See if we can get a full traceback */
- PyNewRef pModule = PyImport_ImportModule("traceback");
-@@ -245,7 +239,7 @@ namespace Plugins
- {
- PyNewRef pFunc = PyObject_GetAttrString(pModule, "format_exception");
- if (pFunc && PyCallable_Check(pFunc)) {
-- PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, pExcept, pValue, pTraceback, NULL);
-+ PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, (PyObject*)pExcept, (PyObject*)pValue, (PyObject*)pTraceback, NULL);
- if (pList)
- {
- for (Py_ssize_t i = 0; i < PyList_Size(pList); i++)
-@@ -263,16 +257,19 @@ namespace Plugins
- }
- else
- {
-+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
- _log.Log(LOG_ERROR, "Exception: '%s'. No traceback available.", sTypeText.c_str());
- }
- }
- else
- {
-+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
- _log.Log(LOG_ERROR, "'format_exception' lookup failed, exception: '%s'. No traceback available.", sTypeText.c_str());
- }
- }
- else
- {
-+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
- _log.Log(LOG_ERROR, "'Traceback' module import failed, exception: '%s'. No traceback available.", sTypeText.c_str());
- }
- }
-@@ -280,11 +277,11 @@ namespace Plugins
- }
-
- void PythonEventsProcessPython(const std::string &reason, const std::string &filename, const std::string &PyString,
-- const uint64_t DeviceID, std::map<uint64_t, CEventSystem::_tDeviceStatus> m_devicestates,
-- std::map<uint64_t, CEventSystem::_tUserVariable> m_uservariables, int intSunRise, int intSunSet)
-+ const uint64_t DeviceID, std::map<uint64_t, CEventSystem::_tDeviceStatus> deviceStates,
-+ std::map<uint64_t, CEventSystem::_tUserVariable> userVariables, int intSunRise, int intSunSet)
- {
-
-- if (!ModuleInitialized)
-+ if (!m_ModuleInitialized)
- {
- return;
- }
-@@ -292,7 +289,7 @@ namespace Plugins
- if (Py_IsInitialized())
- {
- if (m_PyInterpreter)
-- PyEval_RestoreThread((PyThreadState *)m_PyInterpreter);
-+ PyEval_RestoreThread(m_PyInterpreter);
-
- PyBorrowedRef pModule = PythonEventsGetModule();
- if (pModule)
-@@ -305,7 +302,7 @@ namespace Plugins
- return;
- }
-
-- PyNewRef pStrVal = PyUnicode_FromString(m_devicestates[DeviceID].deviceName.c_str());
-+ PyNewRef pStrVal = PyUnicode_FromString(deviceStates[DeviceID].deviceName.c_str());
- if (PyDict_SetItemString(pModuleDict, "changed_device_name", pStrVal) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to set changed_device_name.");
-@@ -327,22 +324,34 @@ namespace Plugins
- return;
- }
-
-- // Mutex
-- // boost::shared_lock<boost::shared_mutex> devicestatesMutexLock1(m_devicestatesMutex);
--
-- for (auto it_type = m_devicestates.begin(); it_type != m_devicestates.end(); ++it_type)
-+ for (auto it_type = deviceStates.begin(); it_type != deviceStates.end(); ++it_type)
- {
- CEventSystem::_tDeviceStatus sitem = it_type->second;
-- // object deviceStatus = domoticz_module.attr("Device")(sitem.ID, sitem.deviceName, sitem.devType,
-- // sitem.subType, sitem.switchtype, sitem.nValue, sitem.nValueWording, sitem.sValue,
-- // sitem.lastUpdate); devices[sitem.deviceName] = deviceStatus;
-
-- PDevice *aDevice = (PDevice *)PDevice_new((PyTypeObject*)PDeviceType, (PyObject *)nullptr, (PyObject *)nullptr);
-- PyNewRef pKey = PyUnicode_FromString(sitem.deviceName.c_str());
-+ PyNewRef nrArgList = Py_BuildValue("(iOiiiOiOO)", static_cast<int>(sitem.ID),
-+ PyUnicode_FromString(sitem.deviceName.c_str()),
-+ sitem.devType,
-+ sitem.subType,
-+ sitem.switchtype,
-+ PyUnicode_FromString(sitem.sValue.c_str()),
-+ sitem.nValue,
-+ PyUnicode_FromString(sitem.nValueWording.c_str()),
-+ PyUnicode_FromString(sitem.lastUpdate.c_str()));
-+ if (!nrArgList)
-+ {
-+ _log.Log(LOG_ERROR, "Python EventSystem: Building device argument list failed for key %s.", sitem.deviceName.c_str());
-+ continue;
-+ }
-+ PyNewRef pDevice = PyObject_CallObject((PyObject*)PDeviceType, nrArgList);
-+ if (!pDevice)
-+ {
-+ _log.Log(LOG_ERROR, "Python EventSystem: Event Device object creation failed for key %s.", sitem.deviceName.c_str());
-+ continue;
-+ }
-
- if (sitem.ID == DeviceID)
- {
-- if (PyDict_SetItemString(pModuleDict, "changed_device", (PyObject *)aDevice) == -1)
-+ if (PyDict_SetItemString(pModuleDict, "changed_device", (PyObject *)pDevice) == -1)
- {
- _log.Log(LOG_ERROR,
- "Python EventSystem: Failed to add device '%s' as changed_device.",
-@@ -350,36 +359,13 @@ namespace Plugins
- }
- }
-
-- if (PyDict_SetItem(pDeviceDict, pKey, (PyObject *)aDevice) == -1)
-+ PyNewRef pKey = PyUnicode_FromString(sitem.deviceName.c_str());
-+ if (PyDict_SetItem(pDeviceDict, pKey, (PyObject *)pDevice) == -1)
- {
- _log.Log(LOG_ERROR, "Python EventSystem: Failed to add device '%s' to device dictionary.",
- sitem.deviceName.c_str());
- }
-- else
-- {
--
-- // _log.Log(LOG_ERROR, "Python EventSystem: nValueWording '%s' - done. ",
-- // sitem.nValueWording.c_str());
--
-- std::string temp_n_value_string = sitem.nValueWording;
--
-- // If nValueWording contains %, unicode fails?
--
-- aDevice->id = static_cast<int>(sitem.ID);
-- aDevice->name = PyUnicode_FromString(sitem.deviceName.c_str());
-- aDevice->type = sitem.devType;
-- aDevice->sub_type = sitem.subType;
-- aDevice->switch_type = sitem.switchtype;
-- aDevice->n_value = sitem.nValue;
-- aDevice->n_value_string = PyUnicode_FromString(temp_n_value_string.c_str());
-- aDevice->s_value = Plugins::PyUnicode_FromString(sitem.sValue.c_str());
-- aDevice->last_update_string = PyUnicode_FromString(sitem.lastUpdate.c_str());
-- // _log.Log(LOG_STATUS, "Python EventSystem: deviceName %s added to device dictionary",
-- // sitem.deviceName.c_str());
-- }
-- Py_DECREF(aDevice);
- }
-- // devicestatesMutexLock1.unlock();
-
- // Time related
-
-@@ -440,7 +426,7 @@ namespace Plugins
- return;
- }
-
-- for (auto it_var = m_uservariables.begin(); it_var != m_uservariables.end(); ++it_var)
-+ for (auto it_var = userVariables.begin(); it_var != userVariables.end(); ++it_var)
- {
- CEventSystem::_tUserVariable uvitem = it_var->second;
- PyDict_SetItemString(userVariablesDict, uvitem.variableName.c_str(),
+++ /dev/null
-From fff4bef553cfd75030d473b3296ade88b3150909 Mon Sep 17 00:00:00 2001
-From: Rob Peters <Info@Domoticz.com>
-Date: Thu, 10 Mar 2022 07:09:18 +0100
-Subject: [PATCH] Fixed compile error when PYTHON was disabled (Fixes #5187)
-
----
- hardware/plugins/DelayedLink.h | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/hardware/plugins/DelayedLink.h
-+++ b/hardware/plugins/DelayedLink.h
-@@ -1,5 +1,5 @@
- #pragma once
--
-+#ifdef ENABLE_PYTHON
- #ifdef WIN32
- # define MS_NO_COREDLL 1
- #else
-@@ -574,3 +574,4 @@ static inline void py3__Py_XDECREF(PyObj
- #endif
- #pragma pop_macro("_DEBUG")
- } // namespace Plugins
-+#endif //#ifdef ENABLE_PYTHON
+++ /dev/null
-From ca4578980e373543d0561564863718c879fa7743 Mon Sep 17 00:00:00 2001
-From: Rob Peters <Info@Domoticz.com>
-Date: Thu, 10 Mar 2022 12:32:29 +0100
-Subject: [PATCH] Making sure code can be compiled without Python
-
----
- hardware/plugins/Plugins.h | 4 ++++
- hardware/plugins/PythonObjects.h | 1 +
- 2 files changed, 5 insertions(+)
-
---- a/hardware/plugins/Plugins.h
-+++ b/hardware/plugins/Plugins.h
-@@ -1,5 +1,7 @@
- #pragma once
-
-+#ifdef ENABLE_PYTHON
-+
- #include "../DomoticzHardware.h"
- #include "../hardwaretypes.h"
- #include "../../notifications/NotificationBase.h"
-@@ -300,3 +302,5 @@ namespace Plugins {
- };
-
- } // namespace Plugins
-+
-+#endif //#ifdef ENABLE_PYTHON
---- a/hardware/plugins/PythonObjects.h
-+++ b/hardware/plugins/PythonObjects.h
-@@ -169,3 +169,4 @@ namespace Plugins {
- };
-
- } // namespace Plugins
-+
--- /dev/null
+# SPDX-License-Identifier: GPL-3.0-only
+#
+# Copyright (C) 2023 Facundo Acevedo
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=dysk
+PKG_VERSION:=2.8.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/Canop/dysk/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=3e0f3a470539721748d7bc1acc867bdddcb824695b2f766e3a1f230ebac28c2c
+
+PKG_MAINTAINER:=Facundo Acevedo <facevedo@disroot.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENCE
+
+PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include ../../lang/rust/rust-package.mk
+
+define Package/dysk
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Utility for efficient file and directory management
+ DEPENDS:=$(RUST_ARCH_DEPENDS)
+ URL:=https://dystroy.org/dysk
+endef
+
+define Package/dysk/description
+ Dysk is a command-line tool designed for efficient file and
+ directory management in Unix-like environments. It offers a
+ streamlined approach to organizing and manipulating files,
+ potentially simplifying various file-related tasks.
+endef
+
+$(eval $(call RustBinPackage,dysk))
+$(eval $(call BuildPackage,dysk))
PKG_NAME:=efibootmgr
PKG_VERSION:=18
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/rhboot/efibootmgr.git
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Application to modify the EFI Boot Manager
- DEPENDS:=@TARGET_x86_64 +efivar +libpopt
+ DEPENDS:=@(TARGET_x86_64||TARGET_armsr_armv8) +efivar +libpopt
URL:=https://github.com/rhboot/efibootmgr
endef
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=fuse3
-PKG_VERSION:=3.10.5
-PKG_RELEASE:=2
+PKG_VERSION:=3.16.2
+PKG_RELEASE:=1
-PKG_SOURCE:=fuse-$(PKG_VERSION).tar.xz
+PKG_SOURCE:=fuse-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/libfuse/libfuse/releases/download/fuse-$(PKG_VERSION)
-PKG_HASH:=b2e283485d47404ac896dd0bb7f7ba81e1470838e677e45f659804c3a3b69666
+PKG_HASH:=f797055d9296b275e981f5f62d4e32e089614fc253d1ef2985851025b8a0ce87
PKG_BUILD_DIR:=$(BUILD_DIR)/fuse-$(PKG_VERSION)
PKG_MAINTAINER:=
PKG_CPE_ID:=cpe:/a:fuse_project:fuse
+PKG_CONFIG_DEPENDS:=CONFIG_PACKAGE_fuse3-utils
+
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/meson.mk
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=fx
+PKG_VERSION:=31.0.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/antonmedv/fx/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=8408047ef42506aac44aa805de209dd64ae4fc084e76bee8e24112ffbdc2d5dc
+
+PKG_MAINTAINER:=Fabian Lipken <dynasticorpheus@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DEPENDS:=golang/host
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+GO_PKG:=github.com/antonmedv/fx
+
+include $(INCLUDE_DIR)/package.mk
+include ../../lang/golang/golang-package.mk
+
+define Package/fx
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Terminal JSON viewer & processor
+ URL:=https://github.com/antonmedv/fx/
+ DEPENDS:=$(GO_ARCH_DEPENDS)
+endef
+
+define Package/fx/description
+ Fx is a dual-purpose command-line tool tailored for JSON, providing
+ both a terminal-based JSON viewer and a JSON processing utility.
+endef
+
+$(eval $(call GoBinPackage,fx))
+$(eval $(call BuildPackage,fx))
--- /dev/null
+choice
+ depends on PACKAGE_gl-puli-mcu
+
+ prompt "GL.iNet target"
+ default GL_PULI_MCU_XE300
+
+ config GL_PULI_MCU_XE300
+ bool "GL.iNet XE300 (Puli)"
+
+ config GL_PULI_MCU_XE3000
+ bool "GL.iNet XE3000 (Puli AX)"
+endchoice
include $(TOPDIR)/rules.mk
PKG_NAME:=gl-puli-mcu
-PKG_VERSION:=1
+PKG_VERSION:=2
PKG_RELEASE:=1
PKG_MAINTAINER:=Nuno Goncalves <nunojpg@gmail.com>
PKG_LICENSE:=GPL-3.0-or-later
+PKG_CONFIG_DEPENDS:= \
+ CONFIG_GL_PULI_MCU_XE300 \
+ CONFIG_GL_PULI_MCU_XE3000
+
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
+define Package/gl-puli-mcu/config
+ source "$(SOURCE)/Config.in"
+endef
+
define Package/gl-puli-mcu
SECTION:=utils
CATEGORY:=Utilities
- TITLE:=GL.iNet GL-XE300 (Puli) power monitoring support
- DEPENDS:=+kmod-usb-serial-ch341 +libubus +libubox
+ TITLE:=GL.iNet power monitoring support
+ DEPENDS:=+CONFIG_GL_PULI_MCU_XE300:kmod-usb-serial-ch341 +libubus +libubox
+ MENU:=1
endef
+ifeq ($(CONFIG_GL_PULI_MCU_XE300),y)
+ TARGET_CFLAGS+=-DGL_TARGET=1
+endif
+ifeq ($(CONFIG_GL_PULI_MCU_XE3000),y)
+ TARGET_CFLAGS+=-DGL_TARGET=2
+endif
+
define Package/gl-puli-mcu/description
- Interfaces with GL-XE300 (Puli) power monitoring MCU over
+ Interfaces with GL.iNet Puli family power monitoring MCU over
a USB to UART adapter present on the device and provides
battery SOC, temperature, charging state and cycle count at
ubus battery/info.
#include <libubox/uloop.h>
#include <libubus.h>
+#define GL_TARGET_XE300 1
+#define GL_TARGET_XE3000 2
+
+#if GL_TARGET == GL_TARGET_XE300
+#define MCU_PORT "/dev/ttyUSB0"
+#elif GL_TARGET == GL_TARGET_XE3000
+#define MCU_PORT "/dev/ttyS1"
+#else
+#error Please define GL_TARGET!
+#endif /* GL_TARGET */
+
static struct ustream_fd stream;
static struct ubus_auto_conn conn;
static struct blob_buf b;
bool set;
} battery;
+#if GL_TARGET == GL_TARGET_XE300
+// MCU status returns something like:
+// {OK},100,275,1,0
static bool
process(char *read)
{
return false;
return true;
}
+#elif GL_TARGET == GL_TARGET_XE3000
+static bool
+get_int_value(const char *read, const char *key, int *int_value, char **new_end)
+{
+ char *from = NULL;
+
+ from = strstr(read, key);
+ if ((!from) || (from != read))
+ {
+ return false;
+ }
+ from = (char *)read + strlen(key);
+ *int_value = strtol(from, new_end, 10);
+ if (from == *new_end)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+// MCU status returns something like:
+// {"code":0,"capacity":100,"temp":28,"chg_state":1,"charge_cycle":0}
+static bool
+process(char *read)
+{
+ int int_value = 0;
+ char *to = NULL;
+
+ if ((read[0] != '{') ||
+ (!get_int_value(&read[1], "\"code\":", &int_value, &to)) ||
+ (int_value != 0))
+ {
+ return false;
+ }
+ if (!get_int_value(to + 1, "\"capacity\":", &int_value, &to))
+ {
+ return false;
+ }
+ battery.soc = int_value;
+ if (!get_int_value(to + 1, "\"temp\":", &int_value, &to))
+ {
+ return false;
+ }
+ battery.temperature = (float) int_value;
+ if (!get_int_value(to + 1, "\"chg_state\":", &int_value, &to))
+ {
+ return false;
+ }
+ battery.charging = (bool) int_value;
+ if (!get_int_value(to + 1, "\"charge_cycle\":", &int_value, &to))
+ {
+ return false;
+ }
+ battery.cycles = (uint16_t) int_value;
+
+ return true;
+}
+#endif /* GL_TARGET */
static int
consume(struct ustream *s, char **a)
battery.set = process(*a);
if (!battery.set)
- ULOG_ERR("failed to parse message from serial: %s", a);
+ ULOG_ERR("failed to parse message from serial: %s", *a);
ustream_consume(s, eol - *a);
*a = eol;
conn.cb = ubus_connect_handler;
ubus_auto_connect(&conn);
- if (serial_open("/dev/ttyUSB0") < 0)
+ if (serial_open(MCU_PORT) < 0)
return -1;
serial_query_timer.cb = serial_query_handler;
PKG_NAME:=gummiboot
PKG_VERSION:=48.1
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://dev.alpinelinux.org/archive/gummiboot/
--- /dev/null
+--- a/src/efi/console.c
++++ b/src/efi/console.c
+@@ -21,63 +21,10 @@
+ #include "util.h"
+ #include "console.h"
+
+-#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
+- { 0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } }
+-
+ struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
+
+-typedef EFI_STATUS (EFIAPI *EFI_INPUT_RESET_EX)(
+- struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This;
+- BOOLEAN ExtendedVerification;
+-);
+-
+ typedef UINT8 EFI_KEY_TOGGLE_STATE;
+
+-typedef struct {
+- UINT32 KeyShiftState;
+- EFI_KEY_TOGGLE_STATE KeyToggleState;
+-} EFI_KEY_STATE;
+-
+-typedef struct {
+- EFI_INPUT_KEY Key;
+- EFI_KEY_STATE KeyState;
+-} EFI_KEY_DATA;
+-
+-typedef EFI_STATUS (EFIAPI *EFI_INPUT_READ_KEY_EX)(
+- struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This;
+- EFI_KEY_DATA *KeyData;
+-);
+-
+-typedef EFI_STATUS (EFIAPI *EFI_SET_STATE)(
+- struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This;
+- EFI_KEY_TOGGLE_STATE *KeyToggleState;
+-);
+-
+-typedef EFI_STATUS (EFIAPI *EFI_KEY_NOTIFY_FUNCTION)(
+- EFI_KEY_DATA *KeyData;
+-);
+-
+-typedef EFI_STATUS (EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY)(
+- struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This;
+- EFI_KEY_DATA KeyData;
+- EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction;
+- VOID **NotifyHandle;
+-);
+-
+-typedef EFI_STATUS (EFIAPI *EFI_UNREGISTER_KEYSTROKE_NOTIFY)(
+- struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This;
+- VOID *NotificationHandle;
+-);
+-
+-typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL {
+- EFI_INPUT_RESET_EX Reset;
+- EFI_INPUT_READ_KEY_EX ReadKeyStrokeEx;
+- EFI_EVENT WaitForKeyEx;
+- EFI_SET_STATE SetState;
+- EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify;
+- EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify;
+-} EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
+-
+ EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) {
+ EFI_GUID EfiSimpleTextInputExProtocolGuid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
+ static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx;
include $(TOPDIR)/rules.mk
PKG_NAME:=irqbalance
-PKG_VERSION:=1.9.2
-PKG_RELEASE:=3
+PKG_VERSION:=1.9.3
+PKG_RELEASE:=2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/Irqbalance/irqbalance.git
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
-PKG_MIRROR_HASH:=e2c81725e7b6d711a47d68755a222236d7081726d567aca1c1295e6fe1caa865
+PKG_MIRROR_HASH:=ff2936e9b7486e802206cbf9e16aa6cb7e1501bdf502441d31f409d104e757b8
PKG_MAINTAINER:=Hannu Nyman <hannu.nyman@iki.fi>
PKG_LICENSE:=GPL-2.0-or-later
+++ /dev/null
-From bbcd9a42c3cec0935b960b7f2046f1fdfab4f7ef Mon Sep 17 00:00:00 2001
-From: Vignesh Raghavendra <vigneshr@ti.com>
-Date: Wed, 7 Dec 2022 19:46:19 +0530
-Subject: [PATCH] procinterrupts: Fix IRQ name parsing on certain arm64 SoC
-
-On arm64 SoCs like TI's K3 SoC and few other SoCs, IRQ names don't get
-parsed correct due to which they end up being classified into wrong
-class. Fix this by considering last token to contain IRQ name always.
-
-Eg.: /proc/interrupt
-
-cat /proc/interrupts
- CPU0 CPU1 CPU2 CPU3
- 11: 7155 8882 7235 7791 GICv3 30 Level arch_timer
- 14: 0 0 0 0 GICv3 23 Level arm-pmu
- 15: 0 0 0 0 GICv3 208 Level 4b00000.spi
- 16: 0 0 0 0 GICv3 209 Level 4b10000.spi
-116: 0 0 0 0 MSI-INTA 1716234 Level 485c0100.dma-controller chan6
-134: 166 0 0 0 MSI-INTA 1970707 Level 8000000.ethernet-tx0
-224: 149 0 0 0 MSI-INTA 1971731 Level 8000000.ethernet
-
-W/o patch irqbalance -d
-IRQ (11) guessed as class 0
-IRQ (14) guessed as class 0
-IRQ (15) guessed as class 0
-IRQ (16) guessed as class 0
-IRQ 485c0100.dma-controller chan6(116) guessed as class 0
-IRQ (134) guessed as class 0
-IRQ (224) guessed as class 0
-
-W/ this patch
-IRQ arch_timer(11) guessed as class 0
-IRQ arm-pmu(14) guessed as class 0
-IRQ 4b00000.spi(15) guessed as class 0
-IRQ 4b10000.spi(16) guessed as class 0
-IRQ 485c0100.dma-controller chan6(116) guessed as class 0
-IRQ 8000000.ethernet-tx0(134) guessed as class 5
-IRQ 8000000.ethernet(224) guessed as class 5
-IRQ 8000000.ethernet(257) guessed as class 5
-IRQ -davinci_gpio wl18xx(362) guessed as class
-
-Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
----
- procinterrupts.c | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
-
---- a/procinterrupts.c
-+++ b/procinterrupts.c
-@@ -178,12 +178,14 @@ void init_irq_class_and_type(char *saved
- }
-
- #ifdef AARCH64
-- if (savedptr && strlen(savedptr) > 0) {
-+ if (savedptr && strlen(savedptr) > 0)
- snprintf(irq_fullname, PATH_MAX, "%s %s", last_token, savedptr);
-- tmp = strchr(irq_fullname, '\n');
-- if (tmp)
-- *tmp = 0;
-- }
-+ else
-+ snprintf(irq_fullname, PATH_MAX, "%s", last_token);
-+
-+ tmp = strchr(irq_fullname, '\n');
-+ if (tmp)
-+ *tmp = 0;
- #else
- snprintf(irq_fullname, PATH_MAX, "%s", last_token);
- #endif
Subject: [PATCH] add meson
Signed-off-by: Rosen Penev <rosenp@gmail.com>
+
+[update version string to 1.9.3]
+
---
meson.build | 43 +++++++++++++++++++++++++++++++++++++++++++
meson_options.txt | 11 +++++++++++
+++ b/meson.build
@@ -0,0 +1,43 @@
+project('irqbalance', 'c',
-+ version : '1.9.0',
++ version : '1.9.3',
+ default_options : ['warning_level=1']
+)
+
--- /dev/null
+--- a/activate.c
++++ b/activate.c
+@@ -98,11 +98,11 @@ error:
+ case ENOSPC: /* Specified CPU APIC is full. */
+ case EAGAIN: /* Interrupted by signal. */
+ case EBUSY: /* Affinity change already in progress. */
+- case EINVAL: /* IRQ would be bound to no CPU. */
+ case ERANGE: /* CPU in mask is offline. */
+ case ENOMEM: /* Kernel cannot allocate CPU mask. */
+ /* Do not blacklist the IRQ on transient errors. */
+ break;
++ case EINVAL: /* IRQ would be bound to no CPU. */
+ default:
+ /* Any other error is considered permanent. */
+ info->flags |= IRQ_FLAG_AFFINITY_UNMANAGED;
include $(TOPDIR)/rules.mk
PKG_NAME:=kmod
-PKG_VERSION:=30
+PKG_VERSION:=31
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@KERNEL/linux/utils/kernel/kmod
-PKG_HASH:=f897dd72698dc6ac1ef03255cd0a5734ad932318e4adbaebc7338ef2f5202f9f
+PKG_HASH:=f5a6949043cc72c001b728d8c218609c5a15f3c33d75614b78c79418fcf00d80
PKG_MAINTAINER:=Jeff Waugh <jdub@bethesignal.org>
PKG_LICENSE:=LGPL-2.1-or-later
#
-# Copyright (C) 2007-2015 OpenWrt.org
-#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=lsof
-PKG_VERSION:=4.94.0
+PKG_VERSION:=4.99.0
PKG_RELEASE:=1
-PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).linux.tar.bz2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/lsof-org/lsof/releases/download/$(PKG_VERSION)
-PKG_HASH:=c41709c2543ecf9de1e950795790a9786a2f225e51c3cc53d6a9a256f872472b
-PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)_$(PKG_VERSION).linux
+PKG_HASH:=180e6284aff184d94d273e34f7264edc2af849c07b1c5d6a4183d4d402734245
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
PKG_LICENSE:=Unique
-PKG_LICENSE_FILES:=00README
+PKG_LICENSE_FILES:=COPYING
include $(INCLUDE_DIR)/package.mk
URL:=http://people.freebsd.org/~abe/
endef
-ifneq ($(CONFIG_IPV6),n)
- LINUX_CLIB_IPV6=-DHASIPv6
-else
- LINUX_CLIB_IPV6=
-endif
-
-TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include/tirpc
-TARGET_LDFLAGS += -ltirpc
-
-define Build/Configure
- $(SED) 's/rpc\/rpc/\/tirpc\/rpc\/rpc/g' $(PKG_BUILD_DIR)/Configure
- cd $(PKG_BUILD_DIR); \
- LINUX_CLIB="-DGLIBCV=2 $(LINUX_CLIB_IPV6)" \
- LSOF_CC="$(TARGET_CC)" \
- LSOF_VSTR="$(LINUX_VERSION)" \
- LSOF_CFGF="$(TARGET_CFLAGS)" \
- LSOF_CFGL="$(TARGET_LDFLAGS)" \
- LSOF_AR="$(TARGET_CROSS)ar cr" \
- LSOF_RANLIB="$(TARGET_CROSS)ranlib" \
- LSOF_INCLUDE="$(STAGING_DIR)/usr/include" \
- ./Configure -n linux
-endef
-
-define Build/Compile
- LSOF_HOST="none" \
- LSOF_LOGNAME="none" \
- LSOF_SYSINFO="none" \
- LSOF_USER="none" \
- $(MAKE) -C $(PKG_BUILD_DIR)
-endef
+CONFIGURE_ARGS += --without-selinux
define Package/lsof/install
$(INSTALL_DIR) $(1)/usr/bin
--- /dev/null
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -208,13 +208,8 @@ EXTRA_DIST += 00.README.FIRST 00CREDITS
+ # Testing
+ EXTRA_DIST += tests/00README tests/TestDB tests/CkTestDB tests/Makefile tests/LsofTest.h check.bash
+
+-# Manpages
+-lsof.man: Lsof.8 version 00DIALECTS
+- soelim < Lsof.8 > $@
+-man8_MANS = lsof.man
+-EXTRA_DIST += Lsof.8
+ # Fix distcheck error
+ clean-local:
+ rm -rf lsof.man
+ distclean-local:
+- rm -rf lockf_owner.h lockf.h
+\ No newline at end of file
++ rm -rf lockf_owner.h lockf.h
+++ /dev/null
---- a/lib/Makefile.skel
-+++ b/lib/Makefile.skel
-@@ -21,8 +21,8 @@ OBJ= ckkv.o cvfs.o dvch.o fino.o isfn.o
- all: ${LIB}
-
- ${LIB}: ${OBJ}
-- ${AR}
-- ${RANLIB}
-+ ${AR} ${LIB} ${OBJ}
-+ ${RANLIB} ${LIB}
-
- clean: FRC
- rm -f ${LIB} ${OBJ} errs Makefile.bak a.out core
+++ /dev/null
---- a/print.c
-+++ b/print.c
-@@ -160,6 +160,7 @@ endnm(sz)
- static void
- fill_portmap()
- {
-+#if !defined __UCLIBC__ || (defined __UCLIBC__ && defined __UCLIBC_HAS_RPC__)
- char buf[128], *cp, *nm;
- CLIENT *c;
- int h, port, pr;
-@@ -278,6 +279,7 @@ fill_portmap()
- Pth[pr][h] = pt;
- }
- clnt_destroy(c);
-+#endif
- }
- #endif /* !defined(HASNORPC_H) */
-
+++ /dev/null
---- a/Configure
-+++ b/Configure
-@@ -2991,7 +2991,7 @@ return(0); }
- LSOF_TMP1=1
- fi # }
- fi # }
-- if test $LSOF_TMP1 -eq 1 # {
-+ if test 0 -eq 1 # {
- then
- LSOF_CFGF="$LSOF_CFGF -DHASSELINUX"
- LSOF_CFGL="$LSOF_CFGL -lselinux"
+++ /dev/null
---- a/Configure
-+++ b/Configure
-@@ -2850,6 +2850,9 @@ LOCKF_OWNER4
- if test "X$LSOF_CC" = "X" # {
- then
- LSOF_CC=cc
-+ fi # }
-+ if test "X$LSOF_CCV" = "X" # {
-+ then
- LSOF_CCV=`$LSOF_CC -v 2>&1 | sed -n 's/.*version \(.*\)/\1/p'`
- fi # }
- if test "X$LINUX_CONF_CC" = "X" # {
include $(TOPDIR)/rules.mk
PKG_NAME:=mc
-PKG_VERSION:=4.8.27
-PKG_RELEASE:=3
+PKG_VERSION:=4.8.30
+PKG_RELEASE:=1
PKG_MAINTAINER:=
PKG_LICENSE:=GPL-3.0-or-later
PKG_CPE_ID:=cpe:/a:midnight_commander:midnight_commander
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://ftp.midnight-commander.org/
-PKG_HASH:=31be59225ffa9920816e9a8b3be0ab225a16d19e4faf46890f25bdffa02a4ff4
+PKG_HASH:=5ebc3cb2144b970c5149fda556c4ad50b78780494696cdf2d14a53204c95c7df
PKG_BUILD_PARALLEL:=1
PKG_FIXUP:=autoreconf gettext-version
PKG_BUILD_DEPENDS:=MC_VFS:libtirpc
--enable-silent-rules \
--disable-tests \
--disable-doxygen-doc \
- --with-homedir=/etc/mc \
--with-screen=ncurses \
--without-x \
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/mc $(1)/usr/bin
$(INSTALL_DIR) $(1)/etc/mc
$(INSTALL_DATA) $(PKG_BUILD_DIR)/misc/mc.charsets $(1)/etc/mc
- $(INSTALL_DATA) $(PKG_BUILD_DIR)/misc/mc.ext $(1)/etc/mc
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/misc/mc.ext.ini $(1)/etc/mc
$(INSTALL_DATA) $(PKG_BUILD_DIR)/misc/mc.default.keymap $(1)/etc/mc/mc.keymap
$(INSTALL_DATA) $(PKG_BUILD_DIR)/misc/filehighlight.ini $(1)/etc/mc
$(INSTALL_DIR) $(1)/usr/share/mc/help
--- a/src/subshell/common.c
+++ b/src/subshell/common.c
-@@ -1140,7 +1140,7 @@ init_subshell_precmd (char *precmd, size
+@@ -1143,7 +1143,7 @@ init_subshell_precmd (char *precmd, size
"else "
"[ \"${PWD##$HOME/}\" = \"$PWD\" ] && MC_PWD=\"$PWD\" || MC_PWD=\"~/${PWD##$HOME/}\"; "
"fi; "
--- a/lib/tty/tty.c
+++ b/lib/tty/tty.c
-@@ -402,7 +402,7 @@ tty_init_xterm_support (gboolean is_xter
+@@ -407,7 +407,7 @@ tty_init_xterm_support (gboolean is_xter
if (xmouse_seq != NULL)
{
if (strcmp (xmouse_seq, ESC_STR "[<") == 0)
--- a/lib/shell.c
+++ b/lib/shell.c
-@@ -68,6 +68,8 @@ mc_shell_get_installed_in_system (void)
+@@ -70,6 +70,8 @@ mc_shell_get_installed_in_system (void)
mc_shell->path = g_strdup ("/bin/bash");
else if (access ("/bin/ash", X_OK) == 0)
mc_shell->path = g_strdup ("/bin/ash");
else if (access ("/bin/dash", X_OK) == 0)
mc_shell->path = g_strdup ("/bin/dash");
else if (access ("/bin/busybox", X_OK) == 0)
-@@ -149,6 +151,12 @@ mc_shell_recognize_real_path (mc_shell_t
+@@ -151,6 +153,12 @@ mc_shell_recognize_real_path (mc_shell_t
mc_shell->type = SHELL_ZSH;
mc_shell->name = "zsh";
}
SHELL_FISH
--- a/src/subshell/common.c
+++ b/src/subshell/common.c
-@@ -378,6 +378,11 @@ init_subshell_child (const char *pty_nam
+@@ -380,6 +380,11 @@ init_subshell_child (const char *pty_nam
}
break;
/* TODO: Find a way to pass initfile to TCSH and FISH */
case SHELL_TCSH:
case SHELL_FISH:
-@@ -427,6 +432,7 @@ init_subshell_child (const char *pty_nam
+@@ -429,6 +434,7 @@ init_subshell_child (const char *pty_nam
case SHELL_ASH_BUSYBOX:
case SHELL_DASH:
case SHELL_TCSH:
case SHELL_FISH:
execl (mc_global.shell->path, mc_global.shell->path, (char *) NULL);
-@@ -1091,6 +1097,10 @@ init_subshell_precmd (char *precmd, size
+@@ -1094,6 +1100,10 @@ init_subshell_precmd (char *precmd, size
"PS1='\\u@\\h:\\w\\$ '\n", command_buffer_pipe[WRITE],
command_buffer_pipe[WRITE], subshell_pipe[WRITE]);
break;
--- /dev/null
+#
+# Copyright (C) 2023 Jeffery To
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mpremote
+PKG_VERSION:=1.21.0
+PKG_RELEASE:=1
+
+PYPI_NAME:=mpremote
+PKG_HASH:=65bc94511f6ff499e901ab59462a5f0744ff7e2cf71d8c75700d14a89c54ed61
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_DEPENDS:=python-hatchling/host python-hatch-requirements-txt/host python-hatch-vcs/host
+
+include ../../lang/python/pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../../lang/python/python3-package.mk
+
+define Package/mpremote
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Interacting remotely with MicroPython devices
+ URL:=https://github.com/micropython/micropython
+ DEPENDS:=+python3-light +python3-urllib +python3-pyserial
+endef
+
+define Package/mpremote/description
+This CLI tool provides an integrated set of utilities to remotely
+interact with and automate a MicroPython device over a serial
+connection.
+endef
+
+$(eval $(call Py3Package,mpremote))
+$(eval $(call BuildPackage,mpremote))
+$(eval $(call BuildPackage,mpremote-src))
--- /dev/null
+--- a/requirements.txt
++++ b/requirements.txt
+@@ -1,2 +1 @@
+ pyserial >= 3.3
+-importlib_metadata >= 1.4
--- /dev/null
+#!/bin/sh
+
+[ "$1" = mpremote ] || exit 0
+
+mpremote version | grep -Fx "mpremote $PKG_VERSION"
PKG_NAME:=nano
PKG_VERSION:=7.2
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/nano
$(INSTALL_DIR) $(1)/etc $(1)/usr/share/nano
$(INSTALL_DATA) ./files/nanorc $(1)/etc/nanorc
$(INSTALL_DATA) ./files/uci.nanorc $(1)/usr/share/nano
+ $(INSTALL_DATA) ./files/ucode.nanorc $(1)/usr/share/nano
$(CP) $(PKG_INSTALL_DIR)/usr/share/nano/* $(1)/usr/share/nano
endef
--- /dev/null
+## Syntax highlighting for OpenWrt ucode scripts.
+
+syntax ucode "/ucode/|\.u[ct]$"
+header "^#!.*\<ucode\>"
+comment "//"
+
+# Declarations
+color green "\<(let|const|function|this)\>"
+
+# Arrow functions
+color green "(\<\w+\>|\([[:alnum:][:space:]_,.]*\))[[:space:]]*=>"
+
+# Flow control and keywords
+color brightyellow "\<(while|if|else|elif|switch|case|default|for|in|endif|endfor|endwhile|endfunction)\>"
+color brightyellow "\<(export|import|try|catch|delete)\>"
+
+# Exit points
+color magenta "\<(break|continue|return)\>"
+
+# Numeric literals
+color cyan "\<([0-9]+\.[0-9]+([eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)\>"
+color cyan "\<0[xX][[:xdigit:]]+(\.[[:xdigit:]]+)?\>"
+color cyan "\<(0[oO][0-7]+|0[bB][01]+|[0-9]+)\>"
+
+# Special values
+color cyan "\<(true|false|null|NaN|Infinity)\>"
+
+# Strings
+color brightmagenta ""([^"\{%#}]|\\.|\{[^"\{%#]|[%#}][^"\}]|[{%#}]\\.)*[{%#}]?""
+color brightmagenta "'([^'\{%#}]|\\.|\{[^'\{%#]|[%#}][^'\}]|[{%#}]\\.)*[{%#}]?'"
+color brightmagenta "`([^`\{%#}]|\\.|\{[^`\{%#]|[%#}][^`\}]|[{%#}]\\.)*[{%#}]?`"
+
+# Template string expressions
+color normal start="\$\{" end="}"
+
+# Comments
+color brightblue "(^|[[:blank:]])//.*"
+color brightblue start="(^|[[:space:]])/\*" end="\*/"
+color brightblue start="\{#" end="#\}"
+
+# Trailing whitespace.
+color ,green "[[:space:]]+$"
+
+# Text outside template directives
+color slate start="[}%#]\}" end="\{[{%#]"
+color slate start="^#!" end="\{[{%#]"
+color slate "^([^{%#}]|\{[^{%#]|[%#}][^}])+\{[{%#]"
+
+# Template tags
+color white "\{[{%][+-]?|-?[%}]\}"
+color brightblue "\{#[+-]?|-?#\}"
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nerdctl
+PKG_VERSION:=1.6.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/containerd/nerdctl/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=fb7660f7e598e4c502d4f0c26cf985290fc7bdc80cce1f7402020afdf83ef988
+
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=Luca Barbato <lu_zero@gentoo.org>
+
+PKG_BUILD_DEPENDS:=golang/host
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+GO_PKG:=github.com/containerd/nerdctl
+
+include $(INCLUDE_DIR)/package.mk
+include ../../lang/golang/golang-package.mk
+
+define Package/nerdctl
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=contaiNERD CTL - Docker-compatible CLI for containerd
+ URL:=https://containerd.io
+ DEPENDS:=$(GO_ARCH_DEPENDS)
+endef
+
+define Package/nerdctl/description
+ Docker-compatible CLI for containerd, with support for Compose, Rootless,
+ eStargz, OCIcrypt, IPFS, ...
+endef
+
+$(eval $(call GoBinPackage,nerdctl))
+$(eval $(call BuildPackage,nerdctl))
include $(TOPDIR)/rules.mk
PKG_NAME:=podman
-PKG_VERSION:=4.7.0
+PKG_VERSION:=4.8.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/containers/podman/archive/v$(PKG_VERSION)
-PKG_HASH:=8fbeab8a821c59ac10ade87c9597d7bb13be4f7868b438278a9f6a17c50bf20d
+PKG_HASH:=cd0afd1fb493b0c099fd8634525f318f35e4e84c1d7735d8426a722a4d5c8409
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
CATEGORY:=Utilities
TITLE:=Podman
URL:=https://podman.io
- DEPENDS:=$(GO_ARCH_DEPENDS) +conmon +libgpgme +libseccomp +nsenter +zoneinfo-simple +kmod-veth +slirp4netns +netavark +aardvark-dns +catatonit +PODMAN_SELINUX_SUPPORT:libselinux
+ DEPENDS:=$(GO_ARCH_DEPENDS) +conmon +libgpgme +libseccomp +nsenter +zoneinfo-simple +kmod-veth +slirp4netns +netavark +aardvark-dns +catatonit +crun +PODMAN_SELINUX_SUPPORT:libselinux
endef
define Package/podman/description
[containers]
#annotations = []
#apparmor_profile = "container-default"
+#base_hosts_file = ""
+#cgroup_conf = []
cgroupns = "private"
cgroups = "enabled"
netns = "private"
#pidns = "private"
-#rootless_networking = "slirp4netns"
+#userns = "host"
+#utsns = "private"
#seccomp_profile = "/usr/share/containers/seccomp.json"
#shm_size = "65536k"
"net.ipv4.ping_group_range=0 0",
]
+#devices = []
+#dns_options = []
+#dns_searches = []
+#dns_servers = []
+#env = [
+# "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+#]
+
+#env_host = false
+#host_containers_internal_ip = ""
+#http_proxy = true
+#init = false
+#ipcns = "shareable"
+#keyring = true
+#label = true
+#label_users = false
+#log_driver = "k8s-file"
+#log_size_max = -1
+#log_tag = ""
+#mounts = []
+#prepare_volume_on_create = false
+#privileged = false
+#read_only = false
+#seccomp_profile = "/usr/share/containers/seccomp.json"
+#tz = ""
+#umask = "0022"
+#volumes = []
+
+[secrets]
+#driver = "file"
+
+[secrets.opts]
+#root = "/example/directory"
+
[network]
network_backend = "netavark"
+#netavark_plugin_dirs = [
+# "/usr/local/libexec/netavark",
+# "/usr/libexec/netavark",
+# "/usr/local/lib/netavark",
+# "/usr/lib/netavark",
+#]
+#firewall_driver = "none"
network_config_dir = "/etc/containers/networks/"
default_network = "podman"
+#default_subnet = "10.88.0.0/16"
+#default_subnet_pools = [
+# {"base" = "10.89.0.0/16", "size" = 24},
+# {"base" = "10.90.0.0/15", "size" = 24},
+# {"base" = "10.92.0.0/14", "size" = 24},
+# {"base" = "10.96.0.0/11", "size" = 24},
+# {"base" = "10.128.0.0/9", "size" = 24},
+#]
+
+default_rootless_network_cmd = "slirp4netns"
+#dns_bind_port = 53
+
[engine]
+#add_compression = ["gzip", "zstd", "zstd:chunked"]
+#compat_api_enforce_docker_hub = true
+#compose_providers=[]
+#compose_warning_logs = true
+#compression_format = "gzip"
+#compression_level = 5
cgroup_manager = "cgroupfs"
+
+conmon_path = [ "/usr/bin/conmon" ]
+#conmon_env_vars = [
+# "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+#]
+
+#database_backend = ""
+#detach_keys = "ctrl-p,ctrl-q"
+#enable_port_reservation = true
+#env = []
+#events_logfile_path=""
+#events_logfile_max_size = "1m"
events_logger = "none"
+#events_container_create_inspect_data = false
+#image_default_format = ""
#image_default_transport = "docker://"
#image_parallel_copies = 0
+#image_volume_mode = ""
#infra_command = "/pause"
-#infra_image = "k8s.gcr.io/pause:3.4.1"
-#lock_type** = "shm"
+#infra_image = ""
+#lock_type = "shm"
+#multi_image_archive = false
#namespace = ""
-#network_cmd_path = ""
+network_cmd_path = "/usr/bin/slirp4netns"
+#network_cmd_options = []
+#no_pivot_root = false
+#num_locks = 2048
+#pod_exit_policy = "continue"
+#pull_policy = "missing"
+#remote = false
runtime = "crun"
-# runtime = "runc"
-# runtime = "uxc"
-runtime_supports_json = ["crun", "runc", "kata", "uxc"]
+runtime_supports_json = ["crun", "runc", "kata", "runsc", "youki", "krun", "uxc"]
#runtime_supports_kvm = ["kata", "krun"]
#runtime_supports_nocgroups = ["crun", "krun", "uxc"]
+#service_timeout = 5
+#stop_timeout = 10
+#exit_command_delay = 300
#static_dir = "/var/lib/containers/storage/libpod"
+tmp_dir = "/var/run/libpod"
+#volume_path = "/var/lib/containers/storage/volumes"
+#volume_plugin_timeout = 5
+#podmansh_timeout = 30
[engine.runtimes]
crun = [
"/sbin/uxc",
]
+[engine.volume_plugins]
+#testplugin = "/run/podman/plugins/test.sock"
+
[machine]
#cpus = 1
#disk_size = 10
#image = "testing"
#memory = 2048
+#user = "core"
+#volumes = [
+# "$HOME:$HOME",
+#]
+#provider = ""
+
+[farms]
+#[farms.list]
--- a/Makefile
+++ b/Makefile
-@@ -219,7 +219,7 @@ GV_SHA=db608827124caa71ba411cec8ea959bb9
+@@ -224,7 +224,7 @@ GV_VERSION=v0.7.1
default: all
.PHONY: all
.PHONY: binaries
ifeq ($(shell uname -s),FreeBSD)
-@@ -804,7 +804,7 @@ rpm-install: package ## Install rpm pac
+@@ -803,7 +803,7 @@ rpm-install: package ## Install rpm pac
/usr/bin/podman info # will catch a broken conmon
.PHONY: install
--- /dev/null
+From https://github.com/mattn/go-sqlite3/pull/1177/commits/65d6085c5d87280c0d6883c884ddb25f9273942f Mon Sep 17 00:00:00 2001
+From: leso-kn <info@lesosoftware.com>
+Date: Mon, 10 Jul 2023 14:58:52 +0200
+Subject: [PATCH] Fix musl build (#1164)
+
+--- a/vendor/github.com/mattn/go-sqlite3/sqlite3.go
++++ b/vendor/github.com/mattn/go-sqlite3/sqlite3.go
+@@ -21,7 +21,7 @@ package sqlite3
+ #cgo CFLAGS: -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1
+ #cgo CFLAGS: -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT
+ #cgo CFLAGS: -Wno-deprecated-declarations
+-#cgo linux,!android CFLAGS: -DHAVE_PREAD64=1 -DHAVE_PWRITE64=1
++#cgo linux,!android CFLAGS: -DHAVE_PREAD=1 -DHAVE_PWRITE=1
+ #cgo openbsd CFLAGS: -I/usr/local/include
+ #cgo openbsd LDFLAGS: -L/usr/local/lib
+ #ifndef USE_LIBSQLITE3
PKG_NAME:=pps-tools
PKG_VERSION:=1.0.2
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE_URL:=https://codeload.github.com/redlab-i/pps-tools/tar.gz/v$(PKG_VERSION)?
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
--- /dev/null
+--- a/ppstest.c
++++ b/ppstest.c
+@@ -110,13 +110,13 @@ retry:
+ }
+
+ printf("source %d - "
+- "assert %ld.%09ld, sequence: %ld - "
+- "clear %ld.%09ld, sequence: %ld\n",
++ "assert %lld.%09ld, sequence: %ld - "
++ "clear %lld.%09ld, sequence: %ld\n",
+ i,
+- infobuf.assert_timestamp.tv_sec,
++ (long long)infobuf.assert_timestamp.tv_sec,
+ infobuf.assert_timestamp.tv_nsec,
+ infobuf.assert_sequence,
+- infobuf.clear_timestamp.tv_sec,
++ (long long)infobuf.clear_timestamp.tv_sec,
+ infobuf.clear_timestamp.tv_nsec, infobuf.clear_sequence);
+ fflush(stdout);
+
+--- a/ppswatch.c
++++ b/ppswatch.c
+@@ -145,7 +145,7 @@ int fetch_source(pps_handle_t handle, in
+ if (max_divergence < div)
+ max_divergence = div;
+ if (div >= margin) {
+- printf("timestamp: %ld, sequence: %ld, offset: % 6ld\n", ts.tv_sec, seq, ts.tv_nsec);
++ printf("timestamp: %lld, sequence: %ld, offset: % 6ld\n", (long long)ts.tv_sec, seq, ts.tv_nsec);
+ fflush(stdout);
+ overflows++;
+ curr_unsync++;
--- /dev/null
+# SPDX-License-Identifier: GPL-3.0-only
+#
+# Copyright (C) 2023 Facundo Acevedo
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=procs
+PKG_VERSION:=0.14.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/dalance/procs/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=a3012bba984faddcf8da2a72d21eb9a7e9be8d5d86a387d321987743b0080a8c
+
+PKG_MAINTAINER:=Facundo Acevedo <facevedo@disroot.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENCE
+
+PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include ../../lang/rust/rust-package.mk
+
+define Package/procs
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Procs is feature-rich alternative to the 'ps'
+ DEPENDS:=$(RUST_ARCH_DEPENDS)
+ URL:=https://github.com/dalance/procs/
+endef
+
+define Package/procs/description
+ Procs is a 'ps' command replacement written in Rust, offering
+ enhanced usability and information display.
+ Features include color-coded output, theme auto-detection, advanced
+ search, and extended process details
+ (TCP/UDP ports, Docker names, I/O throughput).
+ It also supports pager functionality, a 'top'-like watch mode, and
+ a process tree view.
+endef
+
+define Package/procs/conffiles
+/etc/procs/procs.toml
+endef
+
+define Package/procs/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/bin/procs $(1)/usr/bin/
+ $(INSTALL_DIR) $(1)/etc/procs
+ $(INSTALL_CONF) ./files/etc/procs/procs.toml $(1)/etc/procs/
+endef
+
+$(eval $(call RustBinPackage,procs))
+$(eval $(call BuildPackage,procs))
--- /dev/null
+[[columns]]
+kind = "Pid"
+style = "BrightYellow|Yellow"
+numeric_search = true
+nonnumeric_search = false
+align = "Left"
+
+[[columns]]
+kind = "User"
+style = "BrightGreen|Green"
+numeric_search = false
+nonnumeric_search = true
+align = "Left"
+
+[[columns]]
+kind = "Separator"
+style = "White|BrightBlack"
+numeric_search = false
+nonnumeric_search = false
+align = "Left"
+
+[[columns]]
+kind = "Tty"
+style = "BrightWhite|Black"
+numeric_search = false
+nonnumeric_search = false
+align = "Left"
+
+[[columns]]
+kind = "UsageCpu"
+style = "ByPercentage"
+numeric_search = false
+nonnumeric_search = false
+align = "Right"
+
+[[columns]]
+kind = "UsageMem"
+style = "ByPercentage"
+numeric_search = false
+nonnumeric_search = false
+align = "Right"
+
+[[columns]]
+kind = "CpuTime"
+style = "BrightCyan|Cyan"
+numeric_search = false
+nonnumeric_search = false
+align = "Left"
+
+[[columns]]
+kind = "MultiSlot"
+style = "ByUnit"
+numeric_search = false
+nonnumeric_search = false
+align = "Right"
+
+[[columns]]
+kind = "Separator"
+style = "White|BrightBlack"
+numeric_search = false
+nonnumeric_search = false
+align = "Left"
+
+[[columns]]
+kind = "Command"
+style = "BrightWhite|Black"
+numeric_search = false
+nonnumeric_search = true
+align = "Left"
+
+[style]
+header = "BrightWhite|Black"
+unit = "BrightWhite|Black"
+tree = "BrightWhite|Black"
+
+[style.by_percentage]
+color_000 = "BrightBlue|Blue"
+color_025 = "BrightGreen|Green"
+color_050 = "BrightYellow|Yellow"
+color_075 = "BrightRed|Red"
+color_100 = "BrightRed|Red"
+
+[style.by_state]
+color_d = "BrightRed|Red"
+color_r = "BrightGreen|Green"
+color_s = "BrightBlue|Blue"
+color_t = "BrightCyan|Cyan"
+color_z = "BrightMagenta|Magenta"
+color_x = "BrightMagenta|Magenta"
+color_k = "BrightYellow|Yellow"
+color_w = "BrightYellow|Yellow"
+color_p = "BrightYellow|Yellow"
+
+[style.by_unit]
+color_k = "BrightBlue|Blue"
+color_m = "BrightGreen|Green"
+color_g = "BrightYellow|Yellow"
+color_t = "BrightRed|Red"
+color_p = "BrightRed|Red"
+color_x = "BrightBlue|Blue"
+
+[search]
+numeric_search = "Exact"
+nonnumeric_search = "Partial"
+logic = "And"
+case = "Smart"
+
+[display]
+show_self = false
+show_thread = false
+show_thread_in_tree = true
+show_parent_in_tree = true
+show_children_in_tree = true
+show_header = true
+show_footer = false
+cut_to_terminal = true
+cut_to_pager = false
+cut_to_pipe = false
+color_mode = "Auto"
+separator = "│"
+ascending = "▲"
+descending = "▼"
+tree_symbols = ["│", "─", "┬", "├", "└"]
+abbr_sid = true
+theme = "Auto"
+
+[sort]
+column = 0
+order = "Ascending"
+
+[docker]
+path = "unix:///var/run/docker.sock"
+
+[pager]
+mode = "Disable" # OpenWrt's less doen't support the flags '-SR', if needed install the full less pacakge
+detect_width = false
+use_builtin = false
+
include $(TOPDIR)/rules.mk
PKG_NAME:=prometheus-node-exporter-lua
-PKG_VERSION:=2022.08.08
+PKG_VERSION:=2023.07.13
PKG_RELEASE:=1
PKG_MAINTAINER:=Etienne CHAMPETIER <champetier.etienne@gmail.com>
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/hostapd_ubus_stations.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
+define Package/prometheus-node-exporter-lua-hwmon
+ $(call Package/prometheus-node-exporter-lua/Default)
+ TITLE+= (hwmon collector)
+ DEPENDS:=prometheus-node-exporter-lua +luci-lib-nixio
+endef
+
+define Package/prometheus-node-exporter-lua-hwmon/install
+ $(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
+ $(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/hwmon.lua $(1)/usr/lib/lua/prometheus-collectors/
+endef
+
define Package/prometheus-node-exporter-lua-ltq-dsl
$(call Package/prometheus-node-exporter-lua/Default)
TITLE+= (lantiq dsl collector)
$(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/textfile.lua $(1)/usr/lib/lua/prometheus-collectors/
endef
+define Package/prometheus-node-exporter-lua-thermal
+ $(call Package/prometheus-node-exporter-lua/Default)
+ TITLE+= (thermal collector)
+ DEPENDS:=prometheus-node-exporter-lua
+endef
+
+define Package/prometheus-node-exporter-lua-thermal/install
+ $(INSTALL_DIR) $(1)/usr/lib/lua/prometheus-collectors
+ $(INSTALL_BIN) ./files/usr/lib/lua/prometheus-collectors/thermal.lua $(1)/usr/lib/lua/prometheus-collectors/
+endef
+
define Package/prometheus-node-exporter-lua-ubnt-manager
$(call Package/prometheus-node-exporter-lua/Default)
TITLE+= (ubnt-manager collector)
$(eval $(call BuildPackage,prometheus-node-exporter-lua-dawn))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-hostapd_stations))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-hostapd_ubus_stations))
+$(eval $(call BuildPackage,prometheus-node-exporter-lua-hwmon))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-ltq-dsl))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-nat_traffic))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-netstat))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-openwrt))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-textfile))
+$(eval $(call BuildPackage,prometheus-node-exporter-lua-thermal))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-ubnt-manager))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-uci_dhcp_host))
$(eval $(call BuildPackage,prometheus-node-exporter-lua-wifi))
--- /dev/null
+#!/usr/bin/lua
+
+local fs = require "nixio.fs"
+
+local function rtrim(s)
+ return string.gsub(s, "\n$", "")
+end
+
+local function scrape()
+ local metric_chip_names = metric("node_hwmon_chip_names", "gauge")
+ local metric_sensor_label = metric("node_hwmon_sensor_label", "gauge")
+ local metric_temp_celsius = metric("node_hwmon_temp_celsius", "gauge")
+ local metric_pwm = metric("node_hwmon_pwm", "gauge")
+
+ for hwmon_path in fs.glob("/sys/class/hwmon/hwmon*") do
+ -- Produce node_hwmon_chip_names
+ -- See https://github.com/prometheus/node_exporter/blob/7c564bcbeffade3dacac43b07c2eeca4957ca71d/collector/hwmon_linux.go#L415
+ local chip_name = rtrim(get_contents(hwmon_path .. "/name"))
+ if chip_name == "" then
+ chip_name = fs.basename(hwmon_path)
+ end
+
+ -- See https://github.com/prometheus/node_exporter/blob/7c564bcbeffade3dacac43b07c2eeca4957ca71d/collector/hwmon_linux.go#L355
+ local chip = chip_name
+ local real_dev_path, status = fs.realpath(hwmon_path .. "/device")
+ if not status then
+ local dev_name = fs.basename(real_dev_path)
+ local dev_type = fs.basename(fs.dirname(real_dev_path))
+ chip = dev_type .. "_" .. dev_name
+ end
+ metric_chip_names({chip=chip, chip_name=chip_name}, 1)
+
+ -- Produce node_hwmon_sensor_label
+ for sensor_path in fs.glob(hwmon_path .. "/*_label") do
+ local sensor = string.gsub(fs.basename(sensor_path), "_label$", "")
+ local sensor_label = rtrim(get_contents(sensor_path))
+ metric_sensor_label({chip=chip, sensor=sensor, label=sensor_label}, 1)
+ end
+
+ -- Produce node_hwmon_temp_celsius
+ for sensor_path in fs.glob(hwmon_path .. "/temp*_input") do
+ local sensor = string.gsub(fs.basename(sensor_path), "_input$", "")
+ local temp = get_contents(sensor_path) / 1000
+ metric_temp_celsius({chip=chip, sensor=sensor}, temp)
+ end
+
+ -- Produce node_hwmon_pwm
+ for sensor_path in fs.glob(hwmon_path .. "/pwm*") do
+ local sensor = fs.basename(sensor_path)
+ if string.match(sensor, "^pwm[0-9]+$") then
+ local pwm = rtrim(get_contents(sensor_path))
+ metric_pwm({chip=chip, sensor=sensor}, pwm)
+ end
+ end
+ end
+end
+
+return { scrape = scrape }
--- /dev/null
+-- thermal collector
+local function scrape()
+ local i = 0
+ local temp_metric = metric("node_thermal_zone_temp", "gauge")
+
+ while true do
+ local zonePath = "/sys/class/thermal/thermal_zone" .. i
+
+ -- required attributes
+
+ local typ = string.match(get_contents(zonePath .. "/type"), "^%s*(.-)%s*$")
+ if not typ then
+ break
+ end
+
+ local policy = string.match(get_contents(zonePath .. "/policy"), "^%s*(.-)%s*$")
+ if not policy then
+ break
+ end
+
+ local temp = string.match(get_contents(zonePath .. "/temp"), "(%d+)")
+ if not temp then
+ break
+ end
+
+ local labels = {zone = i, type = typ, policy = policy}
+
+ -- optional attributes
+
+ local mode = string.match(get_contents(zonePath .. "/mode"), "^%s*(.-)%s*$")
+ if mode then
+ labels.mode = mode
+ end
+
+ local passive = string.match(get_contents(zonePath .. "/passive"), "(%d+)")
+ if passive then
+ labels.passive = passive
+ end
+
+ temp_metric(labels, temp / 1000)
+
+ i = i + 1
+ end
+end
+
+return { scrape = scrape }
--- /dev/null
+# Copyright (C) 2013-2017 OpenWrt.org
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=prometheus-node-exporter-ucode
+PKG_VERSION:=2022.12.02
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Andre Heider <a.heider@gmail.com>
+PKG_LICENSE:=Apache-2.0
+
+include $(INCLUDE_DIR)/package.mk
+
+Build/Compile=
+
+define Package/$(PKG_NAME)/Default
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Prometheus node exporter
+ PKGARCH:=all
+endef
+
+define Package/$(PKG_NAME)
+ $(call Package/$(PKG_NAME)/Default)
+ DEPENDS:=+uhttpd +uhttpd-mod-ucode +rpcd +ucode-mod-fs +ucode-mod-ubus
+endef
+
+define Package/$(PKG_NAME)/install
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_CONF) ./files/config $(1)/etc/config/$(PKG_NAME)
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/init $(1)/etc/init.d/$(PKG_NAME)
+ $(INSTALL_DIR) $(1)/usr/share/ucode/node-exporter/lib
+ $(INSTALL_DATA) ./files/metrics.uc $(1)/usr/share/ucode/node-exporter/
+ $(INSTALL_DATA) ./files/base/*.uc $(1)/usr/share/ucode/node-exporter/lib/
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) ./files/run.sh $(1)/usr/bin/$(PKG_NAME)
+endef
+
+define Package/$(PKG_NAME)/conffiles
+/etc/config/$(PKG_NAME)
+endef
+
+define Package/$(PKG_NAME)/description
+ Provides node metrics as Prometheus scraping endpoint.
+
+ This service is a lightweight rewrite in ucode of the offical Prometheus node_exporter.
+endef
+
+$(eval $(call BuildPackage,prometheus-node-exporter-ucode))
+
+define Collector
+ define Package/$(PKG_NAME)-$(1)
+ $$(call Package/$(PKG_NAME)/Default)
+ TITLE+= ($(2))
+ DEPENDS:=$(PKG_NAME) $(3)
+ endef
+
+ define Package/$(PKG_NAME)-$(1)/install
+ $$(INSTALL_DIR) $$(1)/usr/share/ucode/node-exporter/lib
+ $$(INSTALL_DATA) ./files/extra/$(1).uc $$(1)/usr/share/ucode/node-exporter/lib/
+ endef
+
+ $$(eval $$(call BuildPackage,$(PKG_NAME)-$(1)))
+endef
+
+$(eval $(call Collector,dnsmasq,Dnsmasq collector,@dnsmasq))
+$(eval $(call Collector,ltq-dsl,Lantiq/Intel/MaxLinear DSL collector,@ltq-dsl-app))
+$(eval $(call Collector,netstat,netstat collector,))
+$(eval $(call Collector,openwrt,OpenWrt collector,))
+$(eval $(call Collector,snmp6,snmp6 collector,))
+$(eval $(call Collector,uci_dhcp_host,UCI DHCP host collector,))
+$(eval $(call Collector,wifi,Wi-Fi collector,+ucode-mod-nl80211))
+$(eval $(call Collector,wireguard,Wireguard collector,+rpcd-mod-wireguard))
--- /dev/null
+gauge("node_nf_conntrack_entries")
+ (null, oneline("/proc/sys/net/netfilter/nf_conntrack_count"));
+gauge("node_nf_conntrack_entries_limit")
+ (null, oneline("/proc/sys/net/netfilter/nf_conntrack_max"));
--- /dev/null
+let f = fs.open("/proc/stat");
+
+if (!f)
+ return false;
+
+const desc = [
+ null,
+ "user",
+ "nice",
+ "system",
+ "idle",
+ "iowait",
+ "irq",
+ "softirq",
+ "steal",
+ "guest",
+ "guest_nice",
+];
+const m_cpu = counter("node_cpu_seconds_total");
+
+let line;
+while (line = nextline(f)) {
+ const x = wsplit(line);
+
+ if (length(x) < 2)
+ continue;
+
+ if (match(x[0], /^cpu\d+/)) {
+ const count = min(length(x), length(desc));
+ for (let i = 1; i < count; i++)
+ m_cpu({ cpu: x[0], mode: desc[i] }, x[i] / 100.0);
+ } else if (x[0] == "intr")
+ counter("node_intr_total")(null, x[1]);
+ else if (x[0] == "ctxt")
+ counter("node_context_switches_total")(null, x[1]);
+ else if (x[0] == "btime")
+ gauge("node_boot_time_seconds")(null, x[1]);
+ else if (x[0] == "processes")
+ counter("node_forks_total")(null, x[1]);
+ else if (x[0] == "procs_running")
+ gauge("node_procs_running_total")(null, x[1]);
+ else if (x[0] == "procs_blocked")
+ gauge("node_procs_blocked_total")(null, x[1]);
+}
--- /dev/null
+gauge("node_entropy_available_bits")
+ (null, oneline("/proc/sys/kernel/random/entropy_avail"));
+gauge("node_entropy_pool_size_bits")
+ (null, oneline("/proc/sys/kernel/random/poolsize"));
--- /dev/null
+const x = wsplit(oneline("/proc/sys/fs/file-nr"));
+
+if (length(x) < 3)
+ return false;
+
+gauge("node_filefd_allocated")(null, x[0]);
+gauge("node_filefd_maximum")(null, x[2]);
--- /dev/null
+const x = wsplit(oneline("/proc/loadavg"));
+
+if (length(x) < 3)
+ return false;
+
+gauge("node_load1")(null, x[0]);
+gauge("node_load5")(null, x[1]);
+gauge("node_load15")(null, x[2]);
--- /dev/null
+let f = fs.open("/proc/meminfo");
+
+if (!f)
+ return false;
+
+let line;
+while (line = nextline(f)) {
+ const x = wsplit(line);
+
+ if (length(x) < 2)
+ continue;
+
+ if (substr(x[0], -1) != ":")
+ continue;
+
+ let name;
+ if (substr(x[0], -2) == "):")
+ name = replace(substr(x[0], 0, -2), "(", "_");
+ else
+ name = substr(x[0], 0, -1);
+
+ gauge(`node_memory_${name}_bytes`)
+ (null, x[2] == "kB" ? x[1] * 1024 : x[1]);
+}
--- /dev/null
+const root = "/sys/class/net/";
+const devices = fs.lsdir(root);
+
+if (length(devices) < 1)
+ return false;
+
+const m_info = gauge("node_network_info");
+const m_speed = gauge("node_network_speed_bytes");
+const metrics = {
+ addr_assign_type: gauge("node_network_address_assign_type"),
+ carrier: gauge("node_network_carrier"),
+ carrier_changes: counter("node_network_carrier_changes_total"),
+ carrier_down_count: counter("node_network_carrier_down_changes_total"),
+ carrier_up_count: counter("node_network_carrier_up_changes_total"),
+ dev_id: gauge("node_network_device_id"),
+ dormant: gauge("node_network_dormant"),
+ flags: gauge("node_network_flags"),
+ ifindex: gauge("node_network_iface_id"),
+ iflink: gauge("node_network_iface_link"),
+ link_mode: gauge("node_network_iface_link_mode"),
+ mtu: gauge("node_network_mtu_bytes"),
+ name_assign_type: gauge("node_network_name_assign_type"),
+ netdev_group: gauge("node_network_net_dev_group"),
+ type: gauge("node_network_protocol_type"),
+ tx_queue_len: gauge("node_network_transmit_queue_length"),
+};
+
+for (let device in devices) {
+ const devroot = root + device + "/";
+
+ m_info({
+ device,
+ address: oneline(devroot + "address"),
+ broadcast: oneline(devroot + "broadcast"),
+ duplex: oneline(devroot + "duplex"),
+ operstate: oneline(devroot + "operstate"),
+ ifalias: oneline(devroot + "ifalias"),
+ }, 1);
+
+ for (let m in metrics) {
+ let line = oneline(devroot + m);
+ metrics[m]({ device }, line);
+ }
+
+ const speed = int(oneline(devroot + "speed"));
+ if (speed > 0)
+ m_speed({ device }, speed * 1000 * 1000 / 8);
+}
--- /dev/null
+let f = fs.open("/proc/net/dev");
+
+if (!f)
+ return false;
+
+const m = [
+ null,
+ counter("node_network_receive_bytes_total"),
+ counter("node_network_receive_packets_total"),
+ counter("node_network_receive_errs_total"),
+ counter("node_network_receive_drop_total"),
+ counter("node_network_receive_fifo_total"),
+ counter("node_network_receive_frame_total"),
+ counter("node_network_receive_compressed_total"),
+ counter("node_network_receive_multicast_total"),
+ counter("node_network_transmit_bytes_total"),
+ counter("node_network_transmit_packets_total"),
+ counter("node_network_transmit_errs_total"),
+ counter("node_network_transmit_drop_total"),
+ counter("node_network_transmit_fifo_total"),
+ counter("node_network_transmit_colls_total"),
+ counter("node_network_transmit_carrier_total"),
+ counter("node_network_transmit_compressed_total"),
+];
+
+let line;
+while (line = nextline(f)) {
+ const x = wsplit(ltrim(line), " ");
+
+ if (length(x) < 2)
+ continue;
+
+ if (substr(x[0], -1) != ":")
+ continue;
+
+ const count = min(length(x), length(m));
+ const labels = { device: substr(x[0], 0, -1) };
+ for (let i = 1; i < count; i++)
+ m[i](labels, x[i]);
+}
--- /dev/null
+const mode = oneline("/sys/fs/selinux/enforce");
+const enabled = gauge("node_selinux_enabled");
+
+if (mode == null) {
+ enabled(null, 0);
+ return;
+}
+
+enabled(null, 1);
+gauge("node_selinux_current_mode")(null, mode);
--- /dev/null
+gauge("node_time_seconds")(null, time());
--- /dev/null
+gauge("node_uname_info")({
+ sysname: oneline("/proc/sys/kernel/ostype"),
+ nodename: oneline("/proc/sys/kernel/hostname"),
+ release: oneline("/proc/sys/kernel/osrelease"),
+ version: oneline("/proc/sys/kernel/version"),
+ machine: poneline("uname -m"), // TODO lame
+ domainname: oneline("/proc/sys/kernel/domainname"),
+}, 1);
--- /dev/null
+config prometheus-node-exporter-ucode 'main'
+ option listen_interface 'loopback'
+ option listen_port '9101'
+ option http_keepalive '70'
+
+config collector 'wifi'
+ option stations '1'
--- /dev/null
+const x = ubus.call("dnsmasq", "metrics");
+if (!x)
+ return false;
+
+for (let i in x)
+ gauge(`dnsmasq_${i}_total`)(null, x[i]);
--- /dev/null
+const x = ubus.call("dsl", "metrics");
+
+if (!x)
+ return false;
+
+gauge("dsl_info")({
+ atuc_vendor: x.atu_c.vendor,
+ atuc_system_vendor: x.atu_c.system_vendor,
+ chipset: x.chipset,
+ firmware_version: x.firmware_version,
+ api_version: x.api_version,
+ driver_version: x.driver_version,
+}, 1);
+
+gauge("dsl_line_info")({
+ annex: x.annex,
+ standard: x.standard,
+ mode: x.mode,
+ profile: x.profile,
+}, 1);
+
+gauge("dsl_up")({ detail: x.state }, x.up);
+gauge("dsl_uptime_seconds")(null, x.uptime);
+
+gauge("dsl_line_attenuation_db")
+ ({ direction: "down" }, x.downstream.latn)
+ ({ direction: "up" }, x.upstream.latn);
+gauge("dsl_signal_attenuation_db")
+ ({ direction: "down" }, x.downstream.satn)
+ ({ direction: "up" }, x.upstream.satn);
+gauge("dsl_signal_to_noise_margin_db")
+ ({ direction: "down" }, x.downstream.snr)
+ ({ direction: "up" }, x.upstream.snr);
+gauge("dsl_aggregated_transmit_power_db")
+ ({ direction: "down" }, x.downstream.actatp)
+ ({ direction: "up" }, x.upstream.actatp);
+
+if (x.downstream.interleave_delay)
+ gauge("dsl_latency_seconds")
+ ({ direction: "down" }, x.downstream.interleave_delay / 1000000.0)
+ ({ direction: "up" }, x.upstream.interleave_delay / 1000000.0);
+gauge("dsl_datarate")
+ ({ direction: "down" }, x.downstream.data_rate)
+ ({ direction: "up" }, x.upstream.data_rate);
+gauge("dsl_max_datarate")
+ ({ direction: "down" }, x.downstream.attndr)
+ ({ direction: "up" }, x.upstream.attndr);
+
+counter("dsl_error_seconds_total")
+ ({ err: "forward error correction", loc: "near" }, x.errors.near.fecs)
+ ({ err: "forward error correction", loc: "far" }, x.errors.far.fecs)
+ ({ err: "errored", loc: "near" }, x.errors.near.es)
+ ({ err: "errored", loc: "far" }, x.errors.far.es)
+ ({ err: "severely errored", loc: "near" }, x.errors.near.ses)
+ ({ err: "severely errored", loc: "far" }, x.errors.far.ses)
+ ({ err: "loss of signal", loc: "near" }, x.errors.near.loss)
+ ({ err: "loss of signal", loc: "far" }, x.errors.far.loss)
+ ({ err: "unavailable", loc: "near" }, x.errors.near.uas)
+ ({ err: "unavailable", loc: "far" }, x.errors.far.uas);
+
+counter("dsl_errors_total")
+ ({ err: "header error code error", loc: "near" }, x.errors.near.hec)
+ ({ err: "header error code error", loc: "far" }, x.errors.far.hec)
+ ({ err: "non pre-emptive crc error", loc: "near" }, x.errors.near.crc_p)
+ ({ err: "non pre-emptive crc error", loc: "far" }, x.errors.far.crc_p)
+ ({ err: "pre-emptive crc error", loc: "near" }, x.errors.near.crcp_p)
+ ({ err: "pre-emptive crc error", loc: "far" }, x.errors.far.crcp_p);
+
+if (x.erb)
+ counter("dsl_erb_total")
+ ({ counter: "sent" }, x.erb.sent)
+ ({ counter: "discarded" }, x.erb.discarded);
--- /dev/null
+function parse(fn) {
+ let f = fs.open(fn);
+
+ if (!f)
+ return false;
+
+ let names, values;
+ while (names = nextline(f), values = nextline(f)) {
+ const name = wsplit(names);
+ const value = wsplit(values);
+
+ if (name[0] != value[0])
+ continue;
+
+ if (length(name) != length(value))
+ continue;
+
+ let prefix = substr(name[0], 0, -1);
+ for (let i = 1; i < length(name); i++)
+ gauge(`node_netstat_${prefix}_${name[i]}`)(null, value[i]);
+ }
+
+ return true;
+}
+
+let n = parse("/proc/net/netstat");
+let s = parse("/proc/net/snmp");
+
+if (!n && !s)
+ return false;
--- /dev/null
+const x = ubus.call("system", "board");
+
+if (!x)
+ return false;
+
+gauge("node_openwrt_info")({
+ board_name: x.board_name,
+ id: x.release.distribution,
+ model: x.model,
+ release: x.release.version,
+ revision: x.release.revision,
+ system: x.system,
+ target: x.release.target,
+}, 1);
--- /dev/null
+function parse(fn, device, skipdecl) {
+ let f = fs.open(fn);
+
+ if (!f)
+ return false;
+
+ const labels = { device };
+ let line;
+ while (line = nextline(f)) {
+ const x = wsplit(line);
+
+ if (length(x) < 2)
+ continue;
+
+ counter(`snmp6_${x[0]}`, null, skipdecl)(labels, x[1]);
+ }
+}
+
+parse("/proc/net/snmp6", "all");
+
+const root = "/proc/net/dev_snmp6/";
+for (let device in fs.lsdir(root))
+ parse(root + device, device, true);
--- /dev/null
+import { cursor } from "uci";
+
+const uci = cursor();
+uci.load("dhcp");
+
+let m = gauge("dhcp_host_info");
+
+uci.foreach('dhcp', `host`, (s) => {
+ m({
+ name: s.name,
+ mac: s.mac,
+ ip: s.ip,
+ }, 1);
+});
--- /dev/null
+import { request, 'const' as wlconst } from 'nl80211';
+
+const x = ubus.call("network.wireless", "status");
+
+if (!x)
+ return false;
+
+const iftypes = [
+ "Unknown",
+ "Ad-Hoc",
+ "Client",
+ "Master",
+ "Master (VLAN)",
+ "WDS",
+ "Monitor",
+ "Mesh Point",
+ "P2P Client",
+ "P2P Go",
+ "P2P Device",
+ "OCB",
+];
+
+let m_radio_info = gauge("wifi_radio_info");
+let m_network_info = gauge("wifi_network_info");
+let m_network_quality = gauge("wifi_network_quality");
+let m_network_bitrate = gauge("wifi_network_bitrate");
+let m_network_noise = gauge("wifi_network_noise_dbm");
+let m_network_signal = gauge("wifi_network_signal_dbm");
+let m_stations_total = counter("wifi_stations_total");
+let m_station_inactive = gauge("wifi_station_inactive_milliseconds");
+let m_station_rx_bytes = counter("wifi_station_receive_bytes_total");
+let m_station_tx_bytes = counter("wifi_station_transmit_bytes_total");
+let m_station_rx_packets = counter("wifi_station_receive_packets_total");
+let m_station_tx_packets = counter("wifi_station_transmit_packets_total");
+let m_station_signal = gauge("wifi_station_signal_dbm");
+let m_station_rx_bitrate = gauge("wifi_station_receive_kilobits_per_second");
+let m_station_tx_bitrate = gauge("wifi_station_transmit_kilobits_per_second");
+let m_station_exp_tp = gauge("wifi_station_expected_throughput_kilobits_per_second");
+
+for (let radio in x) {
+ const rc = x[radio]["config"];
+
+ m_radio_info({
+ radio,
+ htmode: rc["htmode"],
+ channel: rc["channel"],
+ country: rc["country"],
+ } ,1);
+
+ for (let iface in x[radio]["interfaces"]) {
+ const ifname = iface["ifname"];
+ const nc = iface["config"];
+ const wif = request(wlconst.NL80211_CMD_GET_INTERFACE, 0, { dev: ifname });
+
+ if (!wif)
+ continue;
+
+ m_network_info({
+ radio,
+ ifname,
+ ssid: nc["ssid"] || nc["mesh_id"],
+ bssid: wif["mac"],
+ mode: iftypes[wif["iftype"]],
+ }, 1);
+
+ const wsta = request(wlconst.NL80211_CMD_GET_STATION, wlconst.NLM_F_DUMP, { dev: ifname });
+ let signal = 0;
+ let bitrate = 0;
+ const stations = length(wsta) || 0;
+ if (stations) {
+ for (let sta in wsta) {
+ signal += sta["sta_info"].signal;
+ bitrate += sta["sta_info"]["tx_bitrate"].bitrate32;
+ }
+ bitrate /= stations * 0.01;
+ signal /= stations;
+ }
+
+ let labels = { radio, ifname };
+ m_network_bitrate(labels, bitrate || NaN);
+ m_network_signal(labels, signal || NaN);
+ m_network_quality(labels, signal ? 100.0 / 70 * (signal + 110) : NaN);
+
+ const wsur = request(wlconst.NL80211_CMD_GET_SURVEY, wlconst.NLM_F_DUMP, { dev: ifname });
+ let noise = 0;
+ for (let i in wsur) {
+ if (i["survey_info"]["frequency"] != wif["wiphy_freq"])
+ continue;
+
+ noise = i["survey_info"]["noise"];
+ break;
+ }
+
+ m_network_noise(labels, noise || NaN);
+
+ if (config["stations"] != "1")
+ continue;
+
+ m_stations_total(labels, stations);
+ if (!stations)
+ continue;
+
+ for (let sta in wsta) {
+ labels["mac"] = sta["mac"];
+ const info = sta["sta_info"];
+
+ m_station_inactive(labels, info["inactive_time"]);
+ m_station_rx_bytes(labels, info["rx_bytes64"]);
+ m_station_tx_bytes(labels, info["tx_bytes64"]);
+ m_station_rx_packets(labels, info["rx_packets"]);
+ m_station_tx_packets(labels, info["tx_packets"]);
+ m_station_signal(labels, info["signal"]);
+ m_station_rx_bitrate(labels, info["rx_bitrate"]["bitrate32"] * 100);
+ m_station_tx_bitrate(labels, info["tx_bitrate"]["bitrate32"] * 100);
+ m_station_exp_tp(labels, info["expected_throughput"]);
+ }
+ }
+}
--- /dev/null
+import { cursor } from "uci";
+
+const x = ubus.call("wireguard", "status");
+if (!x)
+ return false;
+
+const uci = cursor();
+uci.load("network");
+
+let m_wg_iface_info = gauge("wireguard_interface_info");
+let m_wg_peer_info = gauge("wireguard_peer_info");
+let m_wg_handshake = gauge ("wireguard_latest_handshake_seconds");
+let m_wg_rx = gauge ("wireguard_received_bytes_total");
+let m_wg_tx = gauge ("wireguard_sent_bytes_total");
+
+for (let iface in x) {
+ const wc = x[iface];
+
+ m_wg_iface_info({
+ name: iface,
+ public_key: wc["public_key"],
+ listen_port: wc["listen_port"],
+ fwmark: wc["fwmark"] || NaN,
+ }, 1);
+
+ for (let peer in wc["peers"]) {
+ let description;
+ uci.foreach('network', `wireguard_${iface}`, (s) => {
+ if (s.public_key == peer)
+ description = s.description;
+ });
+
+ const pc = wc["peers"][peer];
+
+ m_wg_peer_info({
+ interface: iface,
+ public_key: peer,
+ description,
+ endpoint: pc["endpoint"],
+ persistent_keepalive_interval: pc["persistent_keepalive_interval"] || NaN,
+ }, 1);
+
+ const labels = { public_key: peer };
+
+ m_wg_handshake(labels, pc["last_handshake"]);
+ m_wg_rx(labels, pc["rx_bytes"]);
+ m_wg_tx(labels, pc["tx_bytes"]);
+ }
+}
--- /dev/null
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2013-2017 OpenWrt.org
+
+START=60
+USE_PROCD=1
+
+_log() {
+ logger -p daemon.info -t prometheus-node-exporter-ucode "$@"
+}
+
+start_service() {
+ . /lib/functions/network.sh
+
+ local interface port bind4 bind6
+
+ config_load prometheus-node-exporter-ucode.main
+ config_get interface "main" listen_interface "loopback"
+ config_get port "main" listen_port 9101
+ config_get keepalive "main" http_keepalive 70
+
+ [ "$interface" = "*" ] || {
+ network_get_ipaddr bind4 "$interface"
+ network_get_ipaddr6 bind6 "$interface"
+ [ -n "$bind4$bind6" ] || {
+ _log "defering start until listen interface $interface becomes ready"
+ return 0
+ }
+ }
+
+ procd_open_instance
+
+ procd_set_param command /usr/sbin/uhttpd -f -c /dev/null -h /dev/null -S -D -o /metrics -O /usr/share/ucode/node-exporter/metrics.uc
+
+ if [ "$interface" = "*" ]; then
+ procd_append_param command -p $port
+ else
+ [ -n "$bind4" ] && procd_append_param command -p $bind4:$port
+ [ -n "$bind6" ] && procd_append_param command -p [$bind6]:$port
+ fi
+ [ $keepalive -gt 0 ] && procd_append_param command -k $keepalive
+
+ procd_add_jail prometheus-node-exporter-ucode log procfs sysfs ubus
+ procd_add_jail_mount "/usr/lib/uhttpd_ucode.so"
+ procd_add_jail_mount "/lib/libubus.so*"
+ procd_add_jail_mount "/lib/libuci.so"
+ procd_add_jail_mount "/usr/lib/ucode"
+ procd_add_jail_mount "/usr/lib/libnl*.so*"
+ procd_add_jail_mount "/usr/share/ucode/node-exporter"
+ procd_add_jail_mount "/etc/config"
+
+ # TODO breaks the dsl collector?
+ #procd_set_param user nobody
+ #procd_set_param group nogroup
+ procd_set_param no_new_privs 1
+
+ procd_set_param stdout 1
+ procd_set_param stderr 1
+ procd_set_param respawn
+
+ procd_close_instance
+}
+
+service_triggers()
+{
+ local interface
+
+ procd_add_reload_trigger "prometheus-node-exporter-ucode"
+
+ config_load prometheus-node-exporter-ucode.main
+ config_get interface "main" listen_interface "loopback"
+
+ [ "$interface" = "*" ] || procd_add_reload_interface_trigger "$interface"
+}
--- /dev/null
+{%
+'use strict';
+
+import * as fs from "fs";
+import { connect } from "ubus";
+import { cursor } from "uci";
+
+function debug(...s) {
+ if (global.debug)
+ warn("DEBUG: ", ...s, "\n");
+}
+
+function puts(...s) {
+ return uhttpd.send(...s, "\n");
+}
+
+function govalue(value) {
+ if (value == Infinity)
+ return "+Inf";
+ else if (value == -Infinity)
+ return "-Inf";
+ else if (value != value)
+ return "NaN";
+ else if (type(value) in [ "int", "double" ])
+ return value;
+ else if (type(value) in [ "bool", "string" ])
+ return +value;
+
+ return null;
+}
+
+function metric(name, mtype, help, skipdecl) {
+ let func;
+ let decl = skipdecl == true ? false : true;
+
+ let yield = function(labels, value) {
+ let v = govalue(value);
+
+ if (v == null) {
+ debug(`skipping metric: unsupported value '${value}' (${name})`);
+ return func;
+ }
+
+ let labels_str = "";
+ if (length(labels)) {
+ let sep = "";
+ let s;
+ labels_str = "{";
+ for (let l in labels) {
+ if (labels[l] == null)
+ s = "";
+ else if (type(labels[l]) == "string") {
+ s = labels[l];
+ s = replace(labels[l], "\\", "\\\\");
+ s = replace(s, "\"", "\\\"");
+ s = replace(s, "\n", "\\n");
+ } else {
+ s = govalue(labels[l]);
+
+ if (!s)
+ continue;
+ }
+
+ labels_str += sep + l + "=\"" + s + "\"";
+ sep = ",";
+ }
+ labels_str += "}";
+ }
+
+ if (decl) {
+ if (help)
+ puts("# HELP ", name, " ", help);
+ puts("# TYPE ", name, " ", mtype);
+ decl = false;
+ }
+
+ puts(name, labels_str, " ", v);
+ return func;
+ };
+
+ func = yield;
+ return func;
+}
+
+function counter(name, help, skipdecl) {
+ return metric(name, "counter", help, skipdecl);
+}
+
+function gauge(name, help, skipdecl) {
+ return metric(name, "gauge", help, skipdecl);
+}
+
+function httpstatus(status) {
+ puts("Status: ", status, "\nContent-Type: text/plain; version=0.0.4; charset=utf-8\n");
+}
+
+function clockdiff(t1, t2) {
+ return (t2[0] - t1[0]) * 1000000000 + t2[1] - t1[1];
+}
+
+let collectors = {};
+
+global.handle_request = function(env) {
+ let scope = {
+ config: null,
+ fs,
+ ubus: connect(),
+ counter,
+ gauge,
+ wsplit: function(line) {
+ return split(line, /\s+/);
+ },
+ nextline: function(f) {
+ return rtrim(f.read("line"), "\n");
+ },
+ oneline: function(fn) {
+ let f = fs.open(fn);
+
+ if (!f)
+ return null;
+
+ return nextline(f);
+ },
+ poneline: function(cmd) {
+ let f = fs.popen(cmd);
+
+ if (!f)
+ return null;
+
+ return nextline(f);
+ },
+ };
+
+ if (length(collectors) < 1) {
+ httpstatus("404 No Collectors found");
+ return;
+ }
+
+ let cols = [];
+ for (let q in split(env.QUERY_STRING, "&")) {
+ let s = split(q, "=", 2);
+ if (length(s) == 2 && s[0] == "collect") {
+ if (!(s[1] in collectors)) {
+ httpstatus(`404 Collector ${s[1]} not found`);
+ return;
+ }
+
+ push(cols, s[1]);
+ }
+ }
+
+ if (length(cols) > 0)
+ cols = uniq(cols);
+ else
+ cols = keys(collectors);
+
+ httpstatus("200 OK");
+
+ let duration = gauge("node_scrape_collector_duration_seconds");
+ let success = gauge("node_scrape_collector_success");
+
+ for (let col in cols) {
+ let ok = false;
+ let t1, t2;
+
+ scope["config"] = collectors[col].config;
+ t1 = clock(true);
+ try {
+ ok = call(collectors[col].func, null, scope) != false;
+ } catch(e) {
+ warn(`error running collector '${col}':\n${e.message}\n`);
+ }
+ t2 = clock(true);
+
+ duration({ collector: col }, clockdiff(t1, t2) / 1000000000.0);
+ success({ collector: col }, ok);
+ }
+};
+
+const lib = "/usr/share/ucode/node-exporter/lib";
+const opts = {
+ strict_declarations: true,
+ raw_mode: true,
+};
+
+let cols = fs.lsdir(lib, "*.uc");
+for (let col in cols) {
+ let func;
+ let uci = cursor();
+
+ try {
+ func = loadfile(lib + "/" + col, opts);
+ } catch(e) {
+ warn(`error compiling collector '${col}':\n${e.message}\n`);
+ continue;
+ }
+
+ let name = substr(col, 0, -3);
+ let config = uci.get_all("prometheus-node-exporter-ucode", name);
+ if (!config || config[".type"] != "collector")
+ config = {};
+ else {
+ delete config[".anonymous"];
+ delete config[".type"];
+ delete config[".name"];
+ }
+
+ collectors[name] = {
+ func,
+ config,
+ };
+}
+
+warn(`prometheus-node-exporter-ucode now serving requests with ${length(collectors)} collectors\n`);
+
+if (!("uhttpd" in global)) {
+ global.debug = true;
+
+ puts = function(...s) {
+ return print(...s, "\n");
+ };
+
+ handle_request({
+ QUERY_STRING: join("&", map(ARGV, v => "collect=" + v)),
+ });
+}
+%}
--- /dev/null
+#!/bin/sh
+exec /usr/bin/ucode -T /usr/share/ucode/node-exporter/metrics.uc $*
--- /dev/null
+#!/bin/sh
+
+prometheus-node-exporter-ucode time
include $(TOPDIR)/rules.mk
PKG_NAME:=qemu
-PKG_VERSION:=8.0.2
+PKG_VERSION:=8.1.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_HASH:=f060abd435fbe6794125e2c398568ffc3cfa540042596907a8b18edca34cf6a5
+PKG_HASH:=541526a764576eb494d2ff5ec46aeb253e62ea29035d1c23c0a8af4e6cd4f087
PKG_SOURCE_URL:=http://download.qemu.org/
PKG_LICENSE:=GPL-2.0-only
PKG_LICENSE_FILES:=LICENSE tcg/LICENSE
--disable-docs \
--disable-fuse \
--disable-gcrypt \
- --with-git-submodules=ignore \
+ --disable-download \
--disable-glusterfs \
--disable-gnutls \
--disable-guest-agent-msi \
--- a/configure
+++ b/configure
-@@ -896,6 +896,8 @@ for opt do
+@@ -823,6 +823,8 @@ for opt do
;;
- --disable-vfio-user-server) vfio_user_server="disabled"
+ --gdb=*) gdb_bin="$optarg"
;;
+ --disable-fortify-source) fortify_source="no"
+ ;;
#endif /* CONFIG_LINUX */
#include "qemu/osdep.h"
-@@ -29,6 +26,13 @@
- #include <sys/vfs.h>
+@@ -57,6 +54,13 @@ QemuFsType qemu_fd_getfs(int fd)
#endif
+ }
+#ifndef MAP_SYNC
+#define MAP_SYNC 0x0
--- a/meson.build
+++ b/meson.build
-@@ -3192,10 +3192,6 @@ subdir('common-user')
+@@ -3451,10 +3451,6 @@ subdir('common-user')
subdir('bsd-user')
subdir('linux-user')
# accel modules
tcg_real_module_ss = ss.source_set()
tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
-@@ -3687,10 +3683,6 @@ subdir('scripts')
+@@ -3945,10 +3941,6 @@ subdir('scripts')
subdir('tools')
subdir('pc-bios')
subdir('docs')
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=quectel-timesync
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=https://github.com/freifunk-darmstadt/quectel-timesync.git
+PKG_SOURCE_DATE:=2023-10-08
+PKG_SOURCE_VERSION:=4333888cb8025b92511597a95859943fae0a0bc8
+PKG_MIRROR_HASH:=696b878891f884318847069b0590cbdbab2ff48461864ecb418e4575935a29e3
+
+PKG_MAINTAINER:=David Bauer <mail@david-bauer.net>
+PKG_LICENSE:=GPL-2.0-only
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/quectel-timesync
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Tool for configuring system clock using Quectel cellular modems
+ DEPENDS:=+kmod-usb-serial-option
+endef
+
+define Package/quectel-timesync/description
+This tool allows for acquiring the current time from
+the cellular network for configuring the local clock.
+Compared to NTP, this has the advantage of nut using up
+mobile traffic.
+
+It takes advantage of the AT+QLTS command found on Quectel
+modems. This functionality depends on support of the mobile
+network.
+endef
+
+define Package/quectel-timesync/conffiles
+/etc/config/quectel-timesync
+endef
+
+define Package/quectel-timesync/install
+ $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config
+
+ $(CP) $(PKG_BUILD_DIR)/openwrt/quectel-timesync/files/quectel-timesync.config $(1)/etc/config/quectel-timesync
+
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/openwrt/quectel-timesync/files/quectel-timesync.init $(1)/etc/init.d/quectel-timesync
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/quectel-timesync $(1)/usr/sbin/quectel-timesync
+endef
+
+$(eval $(call BuildPackage,quectel-timesync))
include $(TOPDIR)/rules.mk
PKG_NAME:=restic
-PKG_VERSION:=0.15.2
+PKG_VERSION:=0.16.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/restic/restic/tar.gz/v${PKG_VERSION}?
-PKG_HASH:=52aca841486eaf4fe6422b059aa05bbf20db94b957de1d3fca019ed2af8192b7
+PKG_HASH:=88165b5b89b6064df37a9964d660f40ac62db51d6536e459db9aaea6f2b2fc11
PKG_LICENSE:=BSD-2-Clause
PKG_LICENSE_FILES:=LICENSE
PKG_LICENSE_FILES:=LICENSE-MIT UNLICENSE
PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
RUST_PKG_FEATURES:=pcre2
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=rpcd-mod-wireguard
+PKG_RELEASE=1
+
+PKG_LICENSE:=LGPL-2.1+
+PKG_BUILD_FLAGS:=gc-sections
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/rpcd-mod-wireguard
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=WireGuard rpcd module
+ DEPENDS:=+rpcd +kmod-wireguard
+ MAINTAINER:=Andre Heider <a.heider@gmail.com>
+endef
+
+define Package/rpcd-mod-wireguard/install
+ $(INSTALL_DIR) $(1)/usr/lib/rpcd
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/rpcd/wireguard.so \
+ $(1)/usr/lib/rpcd/
+endef
+
+define Package/rpcd-mod-wireguard/postinst
+#!/bin/sh
+[ -n "$$IPKG_INSTROOT" ] || /etc/init.d/rpcd reload
+endef
+
+$(eval $(call BuildPackage,rpcd-mod-wireguard))
--- /dev/null
+cmake_minimum_required(VERSION 2.8.12)
+PROJECT(rpcd-mod-wireguard)
+ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -g3 -Wmissing-declarations)
+
+SET(SOURCES wireguard.c api.c)
+
+ADD_LIBRARY(rpcd-mod-wireguard SHARED ${SOURCES})
+
+SET_TARGET_PROPERTIES(rpcd-mod-wireguard PROPERTIES OUTPUT_NAME wireguard PREFIX "")
+INSTALL(TARGETS rpcd-mod-wireguard LIBRARY DESTINATION lib/rpcd)
--- /dev/null
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2023 Andre Heider <a.heider@gmail.com>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libubox/blobmsg.h>
+#include <libubox/blobmsg_json.h>
+
+#include <libubus.h>
+
+#include <rpcd/plugin.h>
+
+#include "wireguard.h"
+
+static struct blob_buf buf;
+
+enum {
+ RPC_PK_DEVICE,
+ __RPC_PK_MAX,
+};
+
+static const struct blobmsg_policy rpc_privatekey_policy[__RPC_PK_MAX] = {
+ [RPC_PK_DEVICE] = { .name = "private", .type = BLOBMSG_TYPE_STRING },
+};
+
+static void rpc_wireguard_add_endpoint(const wg_endpoint *endpoint)
+{
+ char host[1025]; // NI_MAXHOST
+ char serv[32]; // NI_MAXSERV
+ char res[sizeof(host) + sizeof(serv) + 4];
+ socklen_t addr_len;
+
+ memset(res, 0, sizeof(res));
+ if (endpoint->addr.sa_family == AF_INET)
+ addr_len = sizeof(struct sockaddr_in);
+ else if (endpoint->addr.sa_family == AF_INET6)
+ addr_len = sizeof(struct sockaddr_in6);
+ else
+ return;
+
+ if (getnameinfo(&endpoint->addr, addr_len, host, sizeof(host), serv, sizeof(serv),
+ NI_DGRAM | NI_NUMERICHOST | NI_NUMERICSERV))
+ return;
+
+ if (endpoint->addr.sa_family == AF_INET6 && strchr(host, ':'))
+ snprintf(res, sizeof(res), "[%s]:%s", host, serv);
+ else
+ snprintf(res, sizeof(res), "%s:%s", host, serv);
+ res[sizeof(res) - 1] = 0;
+
+ blobmsg_add_string(&buf, "endpoint", res);
+}
+
+static void rpc_wireguard_add_allowedip(const wg_allowedip *allowedip)
+{
+ char res[INET6_ADDRSTRLEN + 4 + 1];
+
+ memset(res, 0, sizeof(res));
+ if (allowedip->family == AF_INET)
+ inet_ntop(AF_INET, &allowedip->ip4, res, INET6_ADDRSTRLEN);
+ else if (allowedip->family == AF_INET6)
+ inet_ntop(AF_INET6, &allowedip->ip6, res, INET6_ADDRSTRLEN);
+ else
+ return;
+
+ if (!res[0])
+ return;
+
+ sprintf(res + strlen(res), "/%u", allowedip->cidr);
+ res[sizeof(res) - 1] = 0;
+
+ blobmsg_add_string(&buf, NULL, res);
+}
+
+static void rpc_wireguard_add_peer(const wg_peer *peer)
+{
+ void *c;
+ struct wg_allowedip *allowedip;
+
+ rpc_wireguard_add_endpoint(&peer->endpoint);
+
+ c = blobmsg_open_array(&buf, "allowed_ips");
+ wg_for_each_allowedip(peer, allowedip)
+ rpc_wireguard_add_allowedip(allowedip);
+ blobmsg_close_array(&buf, c);
+
+ blobmsg_add_u64(&buf, "last_handshake", peer->last_handshake_time.tv_sec);
+ blobmsg_add_u64(&buf, "rx_bytes", peer->rx_bytes);
+ blobmsg_add_u64(&buf, "tx_bytes", peer->tx_bytes);
+ if (peer->persistent_keepalive_interval)
+ blobmsg_add_u16(&buf, "persistent_keepalive_interval", peer->persistent_keepalive_interval);
+}
+
+static void rpc_wireguard_add_device(const wg_device *device)
+{
+ void *c, *d;
+ wg_peer *peer;
+ wg_key_b64_string key;
+
+ blobmsg_add_u32(&buf, "ifindex", device->ifindex);
+
+ if (device->flags & WGDEVICE_HAS_PUBLIC_KEY) {
+ wg_key_to_base64(key, device->public_key);
+ blobmsg_add_string(&buf, "public_key", key);
+ }
+
+ if (device->listen_port)
+ blobmsg_add_u16(&buf, "listen_port", device->listen_port);
+
+ if (device->fwmark)
+ blobmsg_add_u32(&buf, "fwmark", device->fwmark);
+
+ c = blobmsg_open_table(&buf, "peers");
+ wg_for_each_peer(device, peer) {
+ wg_key_to_base64(key, peer->public_key);
+ d = blobmsg_open_table(&buf, key);
+ rpc_wireguard_add_peer(peer);
+ blobmsg_close_table(&buf, d);
+ }
+ blobmsg_close_table(&buf, c);
+}
+
+static int rpc_wireguard_status(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method, struct blob_attr *msg)
+{
+ void *c;
+ char *device_names, *device_name;
+ size_t len;
+
+ device_names = wg_list_device_names();
+ if (!device_names)
+ return UBUS_STATUS_NOT_FOUND;
+
+ blob_buf_init(&buf, 0);
+
+ wg_for_each_device_name(device_names, device_name, len) {
+ wg_device *device;
+
+ if (wg_get_device(&device, device_name) < 0)
+ continue;
+
+ c = blobmsg_open_table(&buf, device_name);
+ rpc_wireguard_add_device(device);
+ blobmsg_close_table(&buf, c);
+
+ wg_free_device(device);
+ }
+
+ free(device_names);
+
+ ubus_send_reply(ctx, req, buf.head);
+
+ return UBUS_STATUS_OK;
+}
+
+static int rpc_wireguard_genkey(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method, struct blob_attr *msg)
+{
+ wg_key private_key, public_key;
+ wg_key_b64_string key;
+
+ wg_generate_private_key(private_key);
+ wg_generate_public_key(public_key, private_key);
+
+ blob_buf_init(&buf, 0);
+ wg_key_to_base64(key, private_key);
+ blobmsg_add_string(&buf, "private", key);
+ wg_key_to_base64(key, public_key);
+ blobmsg_add_string(&buf, "public", key);
+ ubus_send_reply(ctx, req, buf.head);
+
+ return UBUS_STATUS_OK;
+}
+
+static int rpc_wireguard_genpsk(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method, struct blob_attr *msg)
+{
+ wg_key preshared_key;
+ wg_key_b64_string key;
+
+ wg_generate_preshared_key(preshared_key);
+
+ blob_buf_init(&buf, 0);
+ wg_key_to_base64(key, preshared_key);
+ blobmsg_add_string(&buf, "preshared", key);
+ ubus_send_reply(ctx, req, buf.head);
+
+ return UBUS_STATUS_OK;
+}
+
+static int rpc_wireguard_pubkey(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method, struct blob_attr *msg)
+{
+ static struct blob_attr *tb[__RPC_PK_MAX];
+ wg_key_b64_string key;
+ wg_key private_key, public_key;
+
+ blobmsg_parse(rpc_privatekey_policy, __RPC_PK_MAX, tb, blob_data(msg), blob_len(msg));
+
+ if (!tb[RPC_PK_DEVICE])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ if (wg_key_from_base64(private_key, blobmsg_get_string(tb[RPC_PK_DEVICE])))
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ wg_generate_public_key(public_key, private_key);
+ blob_buf_init(&buf, 0);
+ wg_key_to_base64(key, public_key);
+ blobmsg_add_string(&buf, "public", key);
+ ubus_send_reply(ctx, req, buf.head);
+
+ return UBUS_STATUS_OK;
+}
+
+static int rpc_wireguard_api_init(const struct rpc_daemon_ops *ops, struct ubus_context *ctx)
+{
+ static const struct ubus_method wireguard_methods[] = {
+ UBUS_METHOD_NOARG("status", rpc_wireguard_status),
+ UBUS_METHOD_NOARG("genkey", rpc_wireguard_genkey),
+ UBUS_METHOD_NOARG("genpsk", rpc_wireguard_genpsk),
+ UBUS_METHOD("pubkey", rpc_wireguard_pubkey, rpc_privatekey_policy),
+ };
+
+ static struct ubus_object_type wireguard_type =
+ UBUS_OBJECT_TYPE("rpcd-plugin-wireguard", wireguard_methods);
+
+ static struct ubus_object obj = {
+ .name = "wireguard",
+ .type = &wireguard_type,
+ .methods = wireguard_methods,
+ .n_methods = ARRAY_SIZE(wireguard_methods),
+ };
+
+ return ubus_add_object(ctx, &obj);
+}
+
+struct rpc_plugin rpc_plugin = {
+ .init = rpc_wireguard_api_init
+};
--- /dev/null
+// SPDX-License-Identifier: LGPL-2.1+
+/*
+ * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ * Copyright (C) 2008-2012 Pablo Neira Ayuso <pablo@netfilter.org>.
+ */
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <linux/genetlink.h>
+#include <linux/if_link.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <netinet/in.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+
+#include "wireguard.h"
+
+/* wireguard.h netlink uapi: */
+
+#define WG_GENL_NAME "wireguard"
+#define WG_GENL_VERSION 1
+
+enum wg_cmd {
+ WG_CMD_GET_DEVICE,
+ WG_CMD_SET_DEVICE,
+ __WG_CMD_MAX
+};
+
+enum wgdevice_flag {
+ WGDEVICE_F_REPLACE_PEERS = 1U << 0
+};
+enum wgdevice_attribute {
+ WGDEVICE_A_UNSPEC,
+ WGDEVICE_A_IFINDEX,
+ WGDEVICE_A_IFNAME,
+ WGDEVICE_A_PRIVATE_KEY,
+ WGDEVICE_A_PUBLIC_KEY,
+ WGDEVICE_A_FLAGS,
+ WGDEVICE_A_LISTEN_PORT,
+ WGDEVICE_A_FWMARK,
+ WGDEVICE_A_PEERS,
+ __WGDEVICE_A_LAST
+};
+
+enum wgpeer_flag {
+ WGPEER_F_REMOVE_ME = 1U << 0,
+ WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1
+};
+enum wgpeer_attribute {
+ WGPEER_A_UNSPEC,
+ WGPEER_A_PUBLIC_KEY,
+ WGPEER_A_PRESHARED_KEY,
+ WGPEER_A_FLAGS,
+ WGPEER_A_ENDPOINT,
+ WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+ WGPEER_A_LAST_HANDSHAKE_TIME,
+ WGPEER_A_RX_BYTES,
+ WGPEER_A_TX_BYTES,
+ WGPEER_A_ALLOWEDIPS,
+ WGPEER_A_PROTOCOL_VERSION,
+ __WGPEER_A_LAST
+};
+
+enum wgallowedip_attribute {
+ WGALLOWEDIP_A_UNSPEC,
+ WGALLOWEDIP_A_FAMILY,
+ WGALLOWEDIP_A_IPADDR,
+ WGALLOWEDIP_A_CIDR_MASK,
+ __WGALLOWEDIP_A_LAST
+};
+
+/* libmnl mini library: */
+
+#define MNL_SOCKET_AUTOPID 0
+#define MNL_ALIGNTO 4
+#define MNL_ALIGN(len) (((len)+MNL_ALIGNTO-1) & ~(MNL_ALIGNTO-1))
+#define MNL_NLMSG_HDRLEN MNL_ALIGN(sizeof(struct nlmsghdr))
+#define MNL_ATTR_HDRLEN MNL_ALIGN(sizeof(struct nlattr))
+
+enum mnl_attr_data_type {
+ MNL_TYPE_UNSPEC,
+ MNL_TYPE_U8,
+ MNL_TYPE_U16,
+ MNL_TYPE_U32,
+ MNL_TYPE_U64,
+ MNL_TYPE_STRING,
+ MNL_TYPE_FLAG,
+ MNL_TYPE_MSECS,
+ MNL_TYPE_NESTED,
+ MNL_TYPE_NESTED_COMPAT,
+ MNL_TYPE_NUL_STRING,
+ MNL_TYPE_BINARY,
+ MNL_TYPE_MAX,
+};
+
+#define mnl_attr_for_each(attr, nlh, offset) \
+ for ((attr) = mnl_nlmsg_get_payload_offset((nlh), (offset)); \
+ mnl_attr_ok((attr), (char *)mnl_nlmsg_get_payload_tail(nlh) - (char *)(attr)); \
+ (attr) = mnl_attr_next(attr))
+
+#define mnl_attr_for_each_nested(attr, nest) \
+ for ((attr) = mnl_attr_get_payload(nest); \
+ mnl_attr_ok((attr), (char *)mnl_attr_get_payload(nest) + mnl_attr_get_payload_len(nest) - (char *)(attr)); \
+ (attr) = mnl_attr_next(attr))
+
+#define mnl_attr_for_each_payload(payload, payload_size) \
+ for ((attr) = (payload); \
+ mnl_attr_ok((attr), (char *)(payload) + payload_size - (char *)(attr)); \
+ (attr) = mnl_attr_next(attr))
+
+#define MNL_CB_ERROR -1
+#define MNL_CB_STOP 0
+#define MNL_CB_OK 1
+
+typedef int (*mnl_attr_cb_t)(const struct nlattr *attr, void *data);
+typedef int (*mnl_cb_t)(const struct nlmsghdr *nlh, void *data);
+
+#ifndef MNL_ARRAY_SIZE
+#define MNL_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+#endif
+
+static size_t mnl_ideal_socket_buffer_size(void)
+{
+ static size_t size = 0;
+
+ if (size)
+ return size;
+ size = (size_t)sysconf(_SC_PAGESIZE);
+ if (size > 8192)
+ size = 8192;
+ return size;
+}
+
+static size_t mnl_nlmsg_size(size_t len)
+{
+ return len + MNL_NLMSG_HDRLEN;
+}
+
+static struct nlmsghdr *mnl_nlmsg_put_header(void *buf)
+{
+ int len = MNL_ALIGN(sizeof(struct nlmsghdr));
+ struct nlmsghdr *nlh = buf;
+
+ memset(buf, 0, len);
+ nlh->nlmsg_len = len;
+ return nlh;
+}
+
+static void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
+{
+ char *ptr = (char *)nlh + nlh->nlmsg_len;
+ size_t len = MNL_ALIGN(size);
+ nlh->nlmsg_len += len;
+ memset(ptr, 0, len);
+ return ptr;
+}
+
+static void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh)
+{
+ return (void *)nlh + MNL_NLMSG_HDRLEN;
+}
+
+static void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset)
+{
+ return (void *)nlh + MNL_NLMSG_HDRLEN + MNL_ALIGN(offset);
+}
+
+static bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len)
+{
+ return len >= (int)sizeof(struct nlmsghdr) &&
+ nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
+ (int)nlh->nlmsg_len <= len;
+}
+
+static struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len)
+{
+ *len -= MNL_ALIGN(nlh->nlmsg_len);
+ return (struct nlmsghdr *)((void *)nlh + MNL_ALIGN(nlh->nlmsg_len));
+}
+
+static void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh)
+{
+ return (void *)nlh + MNL_ALIGN(nlh->nlmsg_len);
+}
+
+static bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq)
+{
+ return nlh->nlmsg_seq && seq ? nlh->nlmsg_seq == seq : true;
+}
+
+static bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid)
+{
+ return nlh->nlmsg_pid && portid ? nlh->nlmsg_pid == portid : true;
+}
+
+static uint16_t mnl_attr_get_type(const struct nlattr *attr)
+{
+ return attr->nla_type & NLA_TYPE_MASK;
+}
+
+static uint16_t mnl_attr_get_payload_len(const struct nlattr *attr)
+{
+ return attr->nla_len - MNL_ATTR_HDRLEN;
+}
+
+static void *mnl_attr_get_payload(const struct nlattr *attr)
+{
+ return (void *)attr + MNL_ATTR_HDRLEN;
+}
+
+static bool mnl_attr_ok(const struct nlattr *attr, int len)
+{
+ return len >= (int)sizeof(struct nlattr) &&
+ attr->nla_len >= sizeof(struct nlattr) &&
+ (int)attr->nla_len <= len;
+}
+
+static struct nlattr *mnl_attr_next(const struct nlattr *attr)
+{
+ return (struct nlattr *)((void *)attr + MNL_ALIGN(attr->nla_len));
+}
+
+static int mnl_attr_type_valid(const struct nlattr *attr, uint16_t max)
+{
+ if (mnl_attr_get_type(attr) > max) {
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+ return 1;
+}
+
+static int __mnl_attr_validate(const struct nlattr *attr,
+ enum mnl_attr_data_type type, size_t exp_len)
+{
+ uint16_t attr_len = mnl_attr_get_payload_len(attr);
+ const char *attr_data = mnl_attr_get_payload(attr);
+
+ if (attr_len < exp_len) {
+ errno = ERANGE;
+ return -1;
+ }
+ switch(type) {
+ case MNL_TYPE_FLAG:
+ if (attr_len > 0) {
+ errno = ERANGE;
+ return -1;
+ }
+ break;
+ case MNL_TYPE_NUL_STRING:
+ if (attr_len == 0) {
+ errno = ERANGE;
+ return -1;
+ }
+ if (attr_data[attr_len-1] != '\0') {
+ errno = EINVAL;
+ return -1;
+ }
+ break;
+ case MNL_TYPE_STRING:
+ if (attr_len == 0) {
+ errno = ERANGE;
+ return -1;
+ }
+ break;
+ case MNL_TYPE_NESTED:
+
+ if (attr_len == 0)
+ break;
+
+ if (attr_len < MNL_ATTR_HDRLEN) {
+ errno = ERANGE;
+ return -1;
+ }
+ break;
+ default:
+
+ break;
+ }
+ if (exp_len && attr_len > exp_len) {
+ errno = ERANGE;
+ return -1;
+ }
+ return 0;
+}
+
+static const size_t mnl_attr_data_type_len[MNL_TYPE_MAX] = {
+ [MNL_TYPE_U8] = sizeof(uint8_t),
+ [MNL_TYPE_U16] = sizeof(uint16_t),
+ [MNL_TYPE_U32] = sizeof(uint32_t),
+ [MNL_TYPE_U64] = sizeof(uint64_t),
+ [MNL_TYPE_MSECS] = sizeof(uint64_t),
+};
+
+static int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
+{
+ int exp_len;
+
+ if (type >= MNL_TYPE_MAX) {
+ errno = EINVAL;
+ return -1;
+ }
+ exp_len = mnl_attr_data_type_len[type];
+ return __mnl_attr_validate(attr, type, exp_len);
+}
+
+static int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset,
+ mnl_attr_cb_t cb, void *data)
+{
+ int ret = MNL_CB_OK;
+ const struct nlattr *attr;
+
+ mnl_attr_for_each(attr, nlh, offset)
+ if ((ret = cb(attr, data)) <= MNL_CB_STOP)
+ return ret;
+ return ret;
+}
+
+static int mnl_attr_parse_nested(const struct nlattr *nested, mnl_attr_cb_t cb,
+ void *data)
+{
+ int ret = MNL_CB_OK;
+ const struct nlattr *attr;
+
+ mnl_attr_for_each_nested(attr, nested)
+ if ((ret = cb(attr, data)) <= MNL_CB_STOP)
+ return ret;
+ return ret;
+}
+
+static uint8_t mnl_attr_get_u8(const struct nlattr *attr)
+{
+ return *((uint8_t *)mnl_attr_get_payload(attr));
+}
+
+static uint16_t mnl_attr_get_u16(const struct nlattr *attr)
+{
+ return *((uint16_t *)mnl_attr_get_payload(attr));
+}
+
+static uint32_t mnl_attr_get_u32(const struct nlattr *attr)
+{
+ return *((uint32_t *)mnl_attr_get_payload(attr));
+}
+
+static uint64_t mnl_attr_get_u64(const struct nlattr *attr)
+{
+ uint64_t tmp;
+ memcpy(&tmp, mnl_attr_get_payload(attr), sizeof(tmp));
+ return tmp;
+}
+
+static const char *mnl_attr_get_str(const struct nlattr *attr)
+{
+ return mnl_attr_get_payload(attr);
+}
+
+static void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len,
+ const void *data)
+{
+ struct nlattr *attr = mnl_nlmsg_get_payload_tail(nlh);
+ uint16_t payload_len = MNL_ALIGN(sizeof(struct nlattr)) + len;
+ int pad;
+
+ attr->nla_type = type;
+ attr->nla_len = payload_len;
+ memcpy(mnl_attr_get_payload(attr), data, len);
+ nlh->nlmsg_len += MNL_ALIGN(payload_len);
+ pad = MNL_ALIGN(len) - len;
+ if (pad > 0)
+ memset(mnl_attr_get_payload(attr) + len, 0, pad);
+}
+
+static void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data)
+{
+ mnl_attr_put(nlh, type, sizeof(uint16_t), &data);
+}
+
+static void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data)
+{
+ mnl_attr_put(nlh, type, sizeof(uint32_t), &data);
+}
+
+static void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data)
+{
+ mnl_attr_put(nlh, type, strlen(data)+1, data);
+}
+
+static struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type)
+{
+ struct nlattr *start = mnl_nlmsg_get_payload_tail(nlh);
+
+ start->nla_type = NLA_F_NESTED | type;
+ nlh->nlmsg_len += MNL_ALIGN(sizeof(struct nlattr));
+ return start;
+}
+
+static bool mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type, size_t len, const void *data)
+{
+ if (nlh->nlmsg_len + MNL_ATTR_HDRLEN + MNL_ALIGN(len) > buflen)
+ return false;
+ mnl_attr_put(nlh, type, len, data);
+ return true;
+}
+
+static bool mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type, uint8_t data)
+{
+ return mnl_attr_put_check(nlh, buflen, type, sizeof(uint8_t), &data);
+}
+
+static bool mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type, uint16_t data)
+{
+ return mnl_attr_put_check(nlh, buflen, type, sizeof(uint16_t), &data);
+}
+
+static bool mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type, uint32_t data)
+{
+ return mnl_attr_put_check(nlh, buflen, type, sizeof(uint32_t), &data);
+}
+
+static struct nlattr *mnl_attr_nest_start_check(struct nlmsghdr *nlh, size_t buflen,
+ uint16_t type)
+{
+ if (nlh->nlmsg_len + MNL_ATTR_HDRLEN > buflen)
+ return NULL;
+ return mnl_attr_nest_start(nlh, type);
+}
+
+static void mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start)
+{
+ start->nla_len = mnl_nlmsg_get_payload_tail(nlh) - (void *)start;
+}
+
+static void mnl_attr_nest_cancel(struct nlmsghdr *nlh, struct nlattr *start)
+{
+ nlh->nlmsg_len -= mnl_nlmsg_get_payload_tail(nlh) - (void *)start;
+}
+
+static int mnl_cb_noop(__attribute__((unused)) const struct nlmsghdr *nlh, __attribute__((unused)) void *data)
+{
+ return MNL_CB_OK;
+}
+
+static int mnl_cb_error(const struct nlmsghdr *nlh, __attribute__((unused)) void *data)
+{
+ const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
+
+ if (nlh->nlmsg_len < mnl_nlmsg_size(sizeof(struct nlmsgerr))) {
+ errno = EBADMSG;
+ return MNL_CB_ERROR;
+ }
+
+ if (err->error < 0)
+ errno = -err->error;
+ else
+ errno = err->error;
+
+ return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
+}
+
+static int mnl_cb_stop(__attribute__((unused)) const struct nlmsghdr *nlh, __attribute__((unused)) void *data)
+{
+ return MNL_CB_STOP;
+}
+
+static const mnl_cb_t default_cb_array[NLMSG_MIN_TYPE] = {
+ [NLMSG_NOOP] = mnl_cb_noop,
+ [NLMSG_ERROR] = mnl_cb_error,
+ [NLMSG_DONE] = mnl_cb_stop,
+ [NLMSG_OVERRUN] = mnl_cb_noop,
+};
+
+static int __mnl_cb_run(const void *buf, size_t numbytes,
+ unsigned int seq, unsigned int portid,
+ mnl_cb_t cb_data, void *data,
+ const mnl_cb_t *cb_ctl_array,
+ unsigned int cb_ctl_array_len)
+{
+ int ret = MNL_CB_OK, len = numbytes;
+ const struct nlmsghdr *nlh = buf;
+
+ while (mnl_nlmsg_ok(nlh, len)) {
+
+ if (!mnl_nlmsg_portid_ok(nlh, portid)) {
+ errno = ESRCH;
+ return -1;
+ }
+
+ if (!mnl_nlmsg_seq_ok(nlh, seq)) {
+ errno = EPROTO;
+ return -1;
+ }
+
+ if (nlh->nlmsg_flags & NLM_F_DUMP_INTR) {
+ errno = EINTR;
+ return -1;
+ }
+
+ if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) {
+ if (cb_data){
+ ret = cb_data(nlh, data);
+ if (ret <= MNL_CB_STOP)
+ goto out;
+ }
+ } else if (nlh->nlmsg_type < cb_ctl_array_len) {
+ if (cb_ctl_array && cb_ctl_array[nlh->nlmsg_type]) {
+ ret = cb_ctl_array[nlh->nlmsg_type](nlh, data);
+ if (ret <= MNL_CB_STOP)
+ goto out;
+ }
+ } else if (default_cb_array[nlh->nlmsg_type]) {
+ ret = default_cb_array[nlh->nlmsg_type](nlh, data);
+ if (ret <= MNL_CB_STOP)
+ goto out;
+ }
+ nlh = mnl_nlmsg_next(nlh, &len);
+ }
+out:
+ return ret;
+}
+
+static int mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq,
+ unsigned int portid, mnl_cb_t cb_data, void *data,
+ const mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len)
+{
+ return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data,
+ cb_ctl_array, cb_ctl_array_len);
+}
+
+static int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq,
+ unsigned int portid, mnl_cb_t cb_data, void *data)
+{
+ return __mnl_cb_run(buf, numbytes, seq, portid, cb_data, data, NULL, 0);
+}
+
+struct mnl_socket {
+ int fd;
+ struct sockaddr_nl addr;
+};
+
+static unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
+{
+ return nl->addr.nl_pid;
+}
+
+static struct mnl_socket *__mnl_socket_open(int bus, int flags)
+{
+ struct mnl_socket *nl;
+
+ nl = calloc(1, sizeof(struct mnl_socket));
+ if (nl == NULL)
+ return NULL;
+
+ nl->fd = socket(AF_NETLINK, SOCK_RAW | flags, bus);
+ if (nl->fd == -1) {
+ free(nl);
+ return NULL;
+ }
+
+ return nl;
+}
+
+static struct mnl_socket *mnl_socket_open(int bus)
+{
+ return __mnl_socket_open(bus, 0);
+}
+
+static int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
+{
+ int ret;
+ socklen_t addr_len;
+
+ nl->addr.nl_family = AF_NETLINK;
+ nl->addr.nl_groups = groups;
+ nl->addr.nl_pid = pid;
+
+ ret = bind(nl->fd, (struct sockaddr *) &nl->addr, sizeof (nl->addr));
+ if (ret < 0)
+ return ret;
+
+ addr_len = sizeof(nl->addr);
+ ret = getsockname(nl->fd, (struct sockaddr *) &nl->addr, &addr_len);
+ if (ret < 0)
+ return ret;
+
+ if (addr_len != sizeof(nl->addr)) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (nl->addr.nl_family != AF_NETLINK) {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+static ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *buf,
+ size_t len)
+{
+ static const struct sockaddr_nl snl = {
+ .nl_family = AF_NETLINK
+ };
+ return sendto(nl->fd, buf, len, 0,
+ (struct sockaddr *) &snl, sizeof(snl));
+}
+
+static ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf,
+ size_t bufsiz)
+{
+ ssize_t ret;
+ struct sockaddr_nl addr;
+ struct iovec iov = {
+ .iov_base = buf,
+ .iov_len = bufsiz,
+ };
+ struct msghdr msg = {
+ .msg_name = &addr,
+ .msg_namelen = sizeof(struct sockaddr_nl),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = NULL,
+ .msg_controllen = 0,
+ .msg_flags = 0,
+ };
+ ret = recvmsg(nl->fd, &msg, 0);
+ if (ret == -1)
+ return ret;
+
+ if (msg.msg_flags & MSG_TRUNC) {
+ errno = ENOSPC;
+ return -1;
+ }
+ if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
+ errno = EINVAL;
+ return -1;
+ }
+ return ret;
+}
+
+static int mnl_socket_close(struct mnl_socket *nl)
+{
+ int ret = close(nl->fd);
+ free(nl);
+ return ret;
+}
+
+/* mnlg mini library: */
+
+struct mnlg_socket {
+ struct mnl_socket *nl;
+ char *buf;
+ uint16_t id;
+ uint8_t version;
+ unsigned int seq;
+ unsigned int portid;
+};
+
+static struct nlmsghdr *__mnlg_msg_prepare(struct mnlg_socket *nlg, uint8_t cmd,
+ uint16_t flags, uint16_t id,
+ uint8_t version)
+{
+ struct nlmsghdr *nlh;
+ struct genlmsghdr *genl;
+
+ nlh = mnl_nlmsg_put_header(nlg->buf);
+ nlh->nlmsg_type = id;
+ nlh->nlmsg_flags = flags;
+ nlg->seq = time(NULL);
+ nlh->nlmsg_seq = nlg->seq;
+
+ genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));
+ genl->cmd = cmd;
+ genl->version = version;
+
+ return nlh;
+}
+
+static struct nlmsghdr *mnlg_msg_prepare(struct mnlg_socket *nlg, uint8_t cmd,
+ uint16_t flags)
+{
+ return __mnlg_msg_prepare(nlg, cmd, flags, nlg->id, nlg->version);
+}
+
+static int mnlg_socket_send(struct mnlg_socket *nlg, const struct nlmsghdr *nlh)
+{
+ return mnl_socket_sendto(nlg->nl, nlh, nlh->nlmsg_len);
+}
+
+static int mnlg_cb_noop(const struct nlmsghdr *nlh, void *data)
+{
+ (void)nlh;
+ (void)data;
+ return MNL_CB_OK;
+}
+
+static int mnlg_cb_error(const struct nlmsghdr *nlh, void *data)
+{
+ const struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
+ (void)data;
+
+ if (nlh->nlmsg_len < mnl_nlmsg_size(sizeof(struct nlmsgerr))) {
+ errno = EBADMSG;
+ return MNL_CB_ERROR;
+ }
+ /* Netlink subsystems returns the errno value with different signess */
+ if (err->error < 0)
+ errno = -err->error;
+ else
+ errno = err->error;
+
+ return err->error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
+}
+
+static int mnlg_cb_stop(const struct nlmsghdr *nlh, void *data)
+{
+ (void)data;
+ if (nlh->nlmsg_flags & NLM_F_MULTI && nlh->nlmsg_len == mnl_nlmsg_size(sizeof(int))) {
+ int error = *(int *)mnl_nlmsg_get_payload(nlh);
+ /* Netlink subsystems returns the errno value with different signess */
+ if (error < 0)
+ errno = -error;
+ else
+ errno = error;
+
+ return error == 0 ? MNL_CB_STOP : MNL_CB_ERROR;
+ }
+ return MNL_CB_STOP;
+}
+
+static const mnl_cb_t mnlg_cb_array[] = {
+ [NLMSG_NOOP] = mnlg_cb_noop,
+ [NLMSG_ERROR] = mnlg_cb_error,
+ [NLMSG_DONE] = mnlg_cb_stop,
+ [NLMSG_OVERRUN] = mnlg_cb_noop,
+};
+
+static int mnlg_socket_recv_run(struct mnlg_socket *nlg, mnl_cb_t data_cb, void *data)
+{
+ int err;
+
+ do {
+ err = mnl_socket_recvfrom(nlg->nl, nlg->buf,
+ mnl_ideal_socket_buffer_size());
+ if (err <= 0)
+ break;
+ err = mnl_cb_run2(nlg->buf, err, nlg->seq, nlg->portid,
+ data_cb, data, mnlg_cb_array, MNL_ARRAY_SIZE(mnlg_cb_array));
+ } while (err > 0);
+
+ return err;
+}
+
+static int get_family_id_attr_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_valid(attr, CTRL_ATTR_MAX) < 0)
+ return MNL_CB_ERROR;
+
+ if (type == CTRL_ATTR_FAMILY_ID &&
+ mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
+ return MNL_CB_ERROR;
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
+static int get_family_id_cb(const struct nlmsghdr *nlh, void *data)
+{
+ uint16_t *p_id = data;
+ struct nlattr *tb[CTRL_ATTR_MAX + 1] = { 0 };
+
+ mnl_attr_parse(nlh, sizeof(struct genlmsghdr), get_family_id_attr_cb, tb);
+ if (!tb[CTRL_ATTR_FAMILY_ID])
+ return MNL_CB_ERROR;
+ *p_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
+ return MNL_CB_OK;
+}
+
+static struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t version)
+{
+ struct mnlg_socket *nlg;
+ struct nlmsghdr *nlh;
+ int err;
+
+ nlg = malloc(sizeof(*nlg));
+ if (!nlg)
+ return NULL;
+ nlg->id = 0;
+
+ err = -ENOMEM;
+ nlg->buf = malloc(mnl_ideal_socket_buffer_size());
+ if (!nlg->buf)
+ goto err_buf_alloc;
+
+ nlg->nl = mnl_socket_open(NETLINK_GENERIC);
+ if (!nlg->nl) {
+ err = -errno;
+ goto err_mnl_socket_open;
+ }
+
+ if (mnl_socket_bind(nlg->nl, 0, MNL_SOCKET_AUTOPID) < 0) {
+ err = -errno;
+ goto err_mnl_socket_bind;
+ }
+
+ nlg->portid = mnl_socket_get_portid(nlg->nl);
+
+ nlh = __mnlg_msg_prepare(nlg, CTRL_CMD_GETFAMILY,
+ NLM_F_REQUEST | NLM_F_ACK, GENL_ID_CTRL, 1);
+ mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, family_name);
+
+ if (mnlg_socket_send(nlg, nlh) < 0) {
+ err = -errno;
+ goto err_mnlg_socket_send;
+ }
+
+ errno = 0;
+ if (mnlg_socket_recv_run(nlg, get_family_id_cb, &nlg->id) < 0) {
+ errno = errno == ENOENT ? EPROTONOSUPPORT : errno;
+ err = errno ? -errno : -ENOSYS;
+ goto err_mnlg_socket_recv_run;
+ }
+
+ nlg->version = version;
+ errno = 0;
+ return nlg;
+
+err_mnlg_socket_recv_run:
+err_mnlg_socket_send:
+err_mnl_socket_bind:
+ mnl_socket_close(nlg->nl);
+err_mnl_socket_open:
+ free(nlg->buf);
+err_buf_alloc:
+ free(nlg);
+ errno = -err;
+ return NULL;
+}
+
+static void mnlg_socket_close(struct mnlg_socket *nlg)
+{
+ mnl_socket_close(nlg->nl);
+ free(nlg->buf);
+ free(nlg);
+}
+
+/* wireguard-specific parts: */
+
+struct string_list {
+ char *buffer;
+ size_t len;
+ size_t cap;
+};
+
+static int string_list_add(struct string_list *list, const char *str)
+{
+ size_t len = strlen(str) + 1;
+
+ if (len == 1)
+ return 0;
+
+ if (len >= list->cap - list->len) {
+ char *new_buffer;
+ size_t new_cap = list->cap * 2;
+
+ if (new_cap < list->len +len + 1)
+ new_cap = list->len + len + 1;
+ new_buffer = realloc(list->buffer, new_cap);
+ if (!new_buffer)
+ return -errno;
+ list->buffer = new_buffer;
+ list->cap = new_cap;
+ }
+ memcpy(list->buffer + list->len, str, len);
+ list->len += len;
+ list->buffer[list->len] = '\0';
+ return 0;
+}
+
+struct interface {
+ const char *name;
+ bool is_wireguard;
+};
+
+static int parse_linkinfo(const struct nlattr *attr, void *data)
+{
+ struct interface *interface = data;
+
+ if (mnl_attr_get_type(attr) == IFLA_INFO_KIND && !strcmp(WG_GENL_NAME, mnl_attr_get_str(attr)))
+ interface->is_wireguard = true;
+ return MNL_CB_OK;
+}
+
+static int parse_infomsg(const struct nlattr *attr, void *data)
+{
+ struct interface *interface = data;
+
+ if (mnl_attr_get_type(attr) == IFLA_LINKINFO)
+ return mnl_attr_parse_nested(attr, parse_linkinfo, data);
+ else if (mnl_attr_get_type(attr) == IFLA_IFNAME)
+ interface->name = mnl_attr_get_str(attr);
+ return MNL_CB_OK;
+}
+
+static int read_devices_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct string_list *list = data;
+ struct interface interface = { 0 };
+ int ret;
+
+ ret = mnl_attr_parse(nlh, sizeof(struct ifinfomsg), parse_infomsg, &interface);
+ if (ret != MNL_CB_OK)
+ return ret;
+ if (interface.name && interface.is_wireguard)
+ ret = string_list_add(list, interface.name);
+ if (ret < 0)
+ return ret;
+ if (nlh->nlmsg_type != NLMSG_DONE)
+ return MNL_CB_OK + 1;
+ return MNL_CB_OK;
+}
+
+static int fetch_device_names(struct string_list *list)
+{
+ struct mnl_socket *nl = NULL;
+ char *rtnl_buffer = NULL;
+ size_t message_len;
+ unsigned int portid, seq;
+ ssize_t len;
+ int ret = 0;
+ struct nlmsghdr *nlh;
+ struct ifinfomsg *ifm;
+
+ ret = -ENOMEM;
+ rtnl_buffer = calloc(mnl_ideal_socket_buffer_size(), 1);
+ if (!rtnl_buffer)
+ goto cleanup;
+
+ nl = mnl_socket_open(NETLINK_ROUTE);
+ if (!nl) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ seq = time(NULL);
+ portid = mnl_socket_get_portid(nl);
+ nlh = mnl_nlmsg_put_header(rtnl_buffer);
+ nlh->nlmsg_type = RTM_GETLINK;
+ nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP;
+ nlh->nlmsg_seq = seq;
+ ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
+ ifm->ifi_family = AF_UNSPEC;
+ message_len = nlh->nlmsg_len;
+
+ if (mnl_socket_sendto(nl, rtnl_buffer, message_len) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+another:
+ if ((len = mnl_socket_recvfrom(nl, rtnl_buffer, mnl_ideal_socket_buffer_size())) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+ if ((len = mnl_cb_run(rtnl_buffer, len, seq, portid, read_devices_cb, list)) < 0) {
+ /* Netlink returns NLM_F_DUMP_INTR if the set of all tunnels changed
+ * during the dump. That's unfortunate, but is pretty common on busy
+ * systems that are adding and removing tunnels all the time. Rather
+ * than retrying, potentially indefinitely, we just work with the
+ * partial results. */
+ if (errno != EINTR) {
+ ret = -errno;
+ goto cleanup;
+ }
+ }
+ if (len == MNL_CB_OK + 1)
+ goto another;
+ ret = 0;
+
+cleanup:
+ free(rtnl_buffer);
+ if (nl)
+ mnl_socket_close(nl);
+ return ret;
+}
+
+static int add_del_iface(const char *ifname, bool add)
+{
+ struct mnl_socket *nl = NULL;
+ char *rtnl_buffer;
+ ssize_t len;
+ int ret;
+ struct nlmsghdr *nlh;
+ struct ifinfomsg *ifm;
+ struct nlattr *nest;
+
+ rtnl_buffer = calloc(mnl_ideal_socket_buffer_size(), 1);
+ if (!rtnl_buffer) {
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+
+ nl = mnl_socket_open(NETLINK_ROUTE);
+ if (!nl) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ nlh = mnl_nlmsg_put_header(rtnl_buffer);
+ nlh->nlmsg_type = add ? RTM_NEWLINK : RTM_DELLINK;
+ nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | (add ? NLM_F_CREATE | NLM_F_EXCL : 0);
+ nlh->nlmsg_seq = time(NULL);
+ ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
+ ifm->ifi_family = AF_UNSPEC;
+ mnl_attr_put_strz(nlh, IFLA_IFNAME, ifname);
+ nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
+ mnl_attr_put_strz(nlh, IFLA_INFO_KIND, WG_GENL_NAME);
+ mnl_attr_nest_end(nlh, nest);
+
+ if (mnl_socket_sendto(nl, rtnl_buffer, nlh->nlmsg_len) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+ if ((len = mnl_socket_recvfrom(nl, rtnl_buffer, mnl_ideal_socket_buffer_size())) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+ if (mnl_cb_run(rtnl_buffer, len, nlh->nlmsg_seq, mnl_socket_get_portid(nl), NULL, NULL) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+ ret = 0;
+
+cleanup:
+ free(rtnl_buffer);
+ if (nl)
+ mnl_socket_close(nl);
+ return ret;
+}
+
+int wg_set_device(wg_device *dev)
+{
+ int ret = 0;
+ wg_peer *peer = NULL;
+ wg_allowedip *allowedip = NULL;
+ struct nlattr *peers_nest, *peer_nest, *allowedips_nest, *allowedip_nest;
+ struct nlmsghdr *nlh;
+ struct mnlg_socket *nlg;
+
+ nlg = mnlg_socket_open(WG_GENL_NAME, WG_GENL_VERSION);
+ if (!nlg)
+ return -errno;
+
+again:
+ nlh = mnlg_msg_prepare(nlg, WG_CMD_SET_DEVICE, NLM_F_REQUEST | NLM_F_ACK);
+ mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, dev->name);
+
+ if (!peer) {
+ uint32_t flags = 0;
+
+ if (dev->flags & WGDEVICE_HAS_PRIVATE_KEY)
+ mnl_attr_put(nlh, WGDEVICE_A_PRIVATE_KEY, sizeof(dev->private_key), dev->private_key);
+ if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
+ mnl_attr_put_u16(nlh, WGDEVICE_A_LISTEN_PORT, dev->listen_port);
+ if (dev->flags & WGDEVICE_HAS_FWMARK)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_FWMARK, dev->fwmark);
+ if (dev->flags & WGDEVICE_REPLACE_PEERS)
+ flags |= WGDEVICE_F_REPLACE_PEERS;
+ if (flags)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_FLAGS, flags);
+ }
+ if (!dev->first_peer)
+ goto send;
+ peers_nest = peer_nest = allowedips_nest = allowedip_nest = NULL;
+ peers_nest = mnl_attr_nest_start(nlh, WGDEVICE_A_PEERS);
+ for (peer = peer ? peer : dev->first_peer; peer; peer = peer->next_peer) {
+ uint32_t flags = 0;
+
+ peer_nest = mnl_attr_nest_start_check(nlh, mnl_ideal_socket_buffer_size(), 0);
+ if (!peer_nest)
+ goto toobig_peers;
+ if (!mnl_attr_put_check(nlh, mnl_ideal_socket_buffer_size(), WGPEER_A_PUBLIC_KEY, sizeof(peer->public_key), peer->public_key))
+ goto toobig_peers;
+ if (peer->flags & WGPEER_REMOVE_ME)
+ flags |= WGPEER_F_REMOVE_ME;
+ if (!allowedip) {
+ if (peer->flags & WGPEER_REPLACE_ALLOWEDIPS)
+ flags |= WGPEER_F_REPLACE_ALLOWEDIPS;
+ if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
+ if (!mnl_attr_put_check(nlh, mnl_ideal_socket_buffer_size(), WGPEER_A_PRESHARED_KEY, sizeof(peer->preshared_key), peer->preshared_key))
+ goto toobig_peers;
+ }
+ if (peer->endpoint.addr.sa_family == AF_INET) {
+ if (!mnl_attr_put_check(nlh, mnl_ideal_socket_buffer_size(), WGPEER_A_ENDPOINT, sizeof(peer->endpoint.addr4), &peer->endpoint.addr4))
+ goto toobig_peers;
+ } else if (peer->endpoint.addr.sa_family == AF_INET6) {
+ if (!mnl_attr_put_check(nlh, mnl_ideal_socket_buffer_size(), WGPEER_A_ENDPOINT, sizeof(peer->endpoint.addr6), &peer->endpoint.addr6))
+ goto toobig_peers;
+ }
+ if (peer->flags & WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL) {
+ if (!mnl_attr_put_u16_check(nlh, mnl_ideal_socket_buffer_size(), WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, peer->persistent_keepalive_interval))
+ goto toobig_peers;
+ }
+ }
+ if (flags) {
+ if (!mnl_attr_put_u32_check(nlh, mnl_ideal_socket_buffer_size(), WGPEER_A_FLAGS, flags))
+ goto toobig_peers;
+ }
+ if (peer->first_allowedip) {
+ if (!allowedip)
+ allowedip = peer->first_allowedip;
+ allowedips_nest = mnl_attr_nest_start_check(nlh, mnl_ideal_socket_buffer_size(), WGPEER_A_ALLOWEDIPS);
+ if (!allowedips_nest)
+ goto toobig_allowedips;
+ for (; allowedip; allowedip = allowedip->next_allowedip) {
+ allowedip_nest = mnl_attr_nest_start_check(nlh, mnl_ideal_socket_buffer_size(), 0);
+ if (!allowedip_nest)
+ goto toobig_allowedips;
+ if (!mnl_attr_put_u16_check(nlh, mnl_ideal_socket_buffer_size(), WGALLOWEDIP_A_FAMILY, allowedip->family))
+ goto toobig_allowedips;
+ if (allowedip->family == AF_INET) {
+ if (!mnl_attr_put_check(nlh, mnl_ideal_socket_buffer_size(), WGALLOWEDIP_A_IPADDR, sizeof(allowedip->ip4), &allowedip->ip4))
+ goto toobig_allowedips;
+ } else if (allowedip->family == AF_INET6) {
+ if (!mnl_attr_put_check(nlh, mnl_ideal_socket_buffer_size(), WGALLOWEDIP_A_IPADDR, sizeof(allowedip->ip6), &allowedip->ip6))
+ goto toobig_allowedips;
+ }
+ if (!mnl_attr_put_u8_check(nlh, mnl_ideal_socket_buffer_size(), WGALLOWEDIP_A_CIDR_MASK, allowedip->cidr))
+ goto toobig_allowedips;
+ mnl_attr_nest_end(nlh, allowedip_nest);
+ allowedip_nest = NULL;
+ }
+ mnl_attr_nest_end(nlh, allowedips_nest);
+ allowedips_nest = NULL;
+ }
+
+ mnl_attr_nest_end(nlh, peer_nest);
+ peer_nest = NULL;
+ }
+ mnl_attr_nest_end(nlh, peers_nest);
+ peers_nest = NULL;
+ goto send;
+toobig_allowedips:
+ if (allowedip_nest)
+ mnl_attr_nest_cancel(nlh, allowedip_nest);
+ if (allowedips_nest)
+ mnl_attr_nest_end(nlh, allowedips_nest);
+ mnl_attr_nest_end(nlh, peer_nest);
+ mnl_attr_nest_end(nlh, peers_nest);
+ goto send;
+toobig_peers:
+ if (peer_nest)
+ mnl_attr_nest_cancel(nlh, peer_nest);
+ mnl_attr_nest_end(nlh, peers_nest);
+ goto send;
+send:
+ if (mnlg_socket_send(nlg, nlh) < 0) {
+ ret = -errno;
+ goto out;
+ }
+ errno = 0;
+ if (mnlg_socket_recv_run(nlg, NULL, NULL) < 0) {
+ ret = errno ? -errno : -EINVAL;
+ goto out;
+ }
+ if (peer)
+ goto again;
+
+out:
+ mnlg_socket_close(nlg);
+ errno = -ret;
+ return ret;
+}
+
+static int parse_allowedip(const struct nlattr *attr, void *data)
+{
+ wg_allowedip *allowedip = data;
+
+ switch (mnl_attr_get_type(attr)) {
+ case WGALLOWEDIP_A_UNSPEC:
+ break;
+ case WGALLOWEDIP_A_FAMILY:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16))
+ allowedip->family = mnl_attr_get_u16(attr);
+ break;
+ case WGALLOWEDIP_A_IPADDR:
+ if (mnl_attr_get_payload_len(attr) == sizeof(allowedip->ip4))
+ memcpy(&allowedip->ip4, mnl_attr_get_payload(attr), sizeof(allowedip->ip4));
+ else if (mnl_attr_get_payload_len(attr) == sizeof(allowedip->ip6))
+ memcpy(&allowedip->ip6, mnl_attr_get_payload(attr), sizeof(allowedip->ip6));
+ break;
+ case WGALLOWEDIP_A_CIDR_MASK:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U8))
+ allowedip->cidr = mnl_attr_get_u8(attr);
+ break;
+ }
+
+ return MNL_CB_OK;
+}
+
+static int parse_allowedips(const struct nlattr *attr, void *data)
+{
+ wg_peer *peer = data;
+ wg_allowedip *new_allowedip = calloc(1, sizeof(wg_allowedip));
+ int ret;
+
+ if (!new_allowedip)
+ return MNL_CB_ERROR;
+ if (!peer->first_allowedip)
+ peer->first_allowedip = peer->last_allowedip = new_allowedip;
+ else {
+ peer->last_allowedip->next_allowedip = new_allowedip;
+ peer->last_allowedip = new_allowedip;
+ }
+ ret = mnl_attr_parse_nested(attr, parse_allowedip, new_allowedip);
+ if (!ret)
+ return ret;
+ if (!((new_allowedip->family == AF_INET && new_allowedip->cidr <= 32) || (new_allowedip->family == AF_INET6 && new_allowedip->cidr <= 128))) {
+ errno = EAFNOSUPPORT;
+ return MNL_CB_ERROR;
+ }
+ return MNL_CB_OK;
+}
+
+bool wg_key_is_zero(const wg_key key)
+{
+ volatile uint8_t acc = 0;
+ unsigned int i;
+
+ for (i = 0; i < sizeof(wg_key); ++i) {
+ acc |= key[i];
+ __asm__ ("" : "=r" (acc) : "0" (acc));
+ }
+ return 1 & ((acc - 1) >> 8);
+}
+
+static int parse_peer(const struct nlattr *attr, void *data)
+{
+ wg_peer *peer = data;
+
+ switch (mnl_attr_get_type(attr)) {
+ case WGPEER_A_UNSPEC:
+ break;
+ case WGPEER_A_PUBLIC_KEY:
+ if (mnl_attr_get_payload_len(attr) == sizeof(peer->public_key)) {
+ memcpy(peer->public_key, mnl_attr_get_payload(attr), sizeof(peer->public_key));
+ peer->flags |= WGPEER_HAS_PUBLIC_KEY;
+ }
+ break;
+ case WGPEER_A_PRESHARED_KEY:
+ if (mnl_attr_get_payload_len(attr) == sizeof(peer->preshared_key)) {
+ memcpy(peer->preshared_key, mnl_attr_get_payload(attr), sizeof(peer->preshared_key));
+ if (!wg_key_is_zero(peer->preshared_key))
+ peer->flags |= WGPEER_HAS_PRESHARED_KEY;
+ }
+ break;
+ case WGPEER_A_ENDPOINT: {
+ struct sockaddr *addr;
+
+ if (mnl_attr_get_payload_len(attr) < sizeof(*addr))
+ break;
+ addr = mnl_attr_get_payload(attr);
+ if (addr->sa_family == AF_INET && mnl_attr_get_payload_len(attr) == sizeof(peer->endpoint.addr4))
+ memcpy(&peer->endpoint.addr4, addr, sizeof(peer->endpoint.addr4));
+ else if (addr->sa_family == AF_INET6 && mnl_attr_get_payload_len(attr) == sizeof(peer->endpoint.addr6))
+ memcpy(&peer->endpoint.addr6, addr, sizeof(peer->endpoint.addr6));
+ break;
+ }
+ case WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16))
+ peer->persistent_keepalive_interval = mnl_attr_get_u16(attr);
+ break;
+ case WGPEER_A_LAST_HANDSHAKE_TIME:
+ if (mnl_attr_get_payload_len(attr) == sizeof(peer->last_handshake_time))
+ memcpy(&peer->last_handshake_time, mnl_attr_get_payload(attr), sizeof(peer->last_handshake_time));
+ break;
+ case WGPEER_A_RX_BYTES:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U64))
+ peer->rx_bytes = mnl_attr_get_u64(attr);
+ break;
+ case WGPEER_A_TX_BYTES:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U64))
+ peer->tx_bytes = mnl_attr_get_u64(attr);
+ break;
+ case WGPEER_A_ALLOWEDIPS:
+ return mnl_attr_parse_nested(attr, parse_allowedips, peer);
+ }
+
+ return MNL_CB_OK;
+}
+
+static int parse_peers(const struct nlattr *attr, void *data)
+{
+ wg_device *device = data;
+ wg_peer *new_peer = calloc(1, sizeof(wg_peer));
+ int ret;
+
+ if (!new_peer)
+ return MNL_CB_ERROR;
+ if (!device->first_peer)
+ device->first_peer = device->last_peer = new_peer;
+ else {
+ device->last_peer->next_peer = new_peer;
+ device->last_peer = new_peer;
+ }
+ ret = mnl_attr_parse_nested(attr, parse_peer, new_peer);
+ if (!ret)
+ return ret;
+ if (!(new_peer->flags & WGPEER_HAS_PUBLIC_KEY)) {
+ errno = ENXIO;
+ return MNL_CB_ERROR;
+ }
+ return MNL_CB_OK;
+}
+
+static int parse_device(const struct nlattr *attr, void *data)
+{
+ wg_device *device = data;
+
+ switch (mnl_attr_get_type(attr)) {
+ case WGDEVICE_A_UNSPEC:
+ break;
+ case WGDEVICE_A_IFINDEX:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U32))
+ device->ifindex = mnl_attr_get_u32(attr);
+ break;
+ case WGDEVICE_A_IFNAME:
+ if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) {
+ strncpy(device->name, mnl_attr_get_str(attr), sizeof(device->name) - 1);
+ device->name[sizeof(device->name) - 1] = '\0';
+ }
+ break;
+ case WGDEVICE_A_PRIVATE_KEY:
+ if (mnl_attr_get_payload_len(attr) == sizeof(device->private_key)) {
+ memcpy(device->private_key, mnl_attr_get_payload(attr), sizeof(device->private_key));
+ device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
+ }
+ break;
+ case WGDEVICE_A_PUBLIC_KEY:
+ if (mnl_attr_get_payload_len(attr) == sizeof(device->public_key)) {
+ memcpy(device->public_key, mnl_attr_get_payload(attr), sizeof(device->public_key));
+ device->flags |= WGDEVICE_HAS_PUBLIC_KEY;
+ }
+ break;
+ case WGDEVICE_A_LISTEN_PORT:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U16))
+ device->listen_port = mnl_attr_get_u16(attr);
+ break;
+ case WGDEVICE_A_FWMARK:
+ if (!mnl_attr_validate(attr, MNL_TYPE_U32))
+ device->fwmark = mnl_attr_get_u32(attr);
+ break;
+ case WGDEVICE_A_PEERS:
+ return mnl_attr_parse_nested(attr, parse_peers, device);
+ }
+
+ return MNL_CB_OK;
+}
+
+static int read_device_cb(const struct nlmsghdr *nlh, void *data)
+{
+ return mnl_attr_parse(nlh, sizeof(struct genlmsghdr), parse_device, data);
+}
+
+static void coalesce_peers(wg_device *device)
+{
+ wg_peer *old_next_peer, *peer = device->first_peer;
+
+ while (peer && peer->next_peer) {
+ if (memcmp(peer->public_key, peer->next_peer->public_key, sizeof(wg_key))) {
+ peer = peer->next_peer;
+ continue;
+ }
+ if (!peer->first_allowedip) {
+ peer->first_allowedip = peer->next_peer->first_allowedip;
+ peer->last_allowedip = peer->next_peer->last_allowedip;
+ } else {
+ peer->last_allowedip->next_allowedip = peer->next_peer->first_allowedip;
+ peer->last_allowedip = peer->next_peer->last_allowedip;
+ }
+ old_next_peer = peer->next_peer;
+ peer->next_peer = old_next_peer->next_peer;
+ free(old_next_peer);
+ }
+}
+
+int wg_get_device(wg_device **device, const char *device_name)
+{
+ int ret = 0;
+ struct nlmsghdr *nlh;
+ struct mnlg_socket *nlg;
+
+try_again:
+ *device = calloc(1, sizeof(wg_device));
+ if (!*device)
+ return -errno;
+
+ nlg = mnlg_socket_open(WG_GENL_NAME, WG_GENL_VERSION);
+ if (!nlg) {
+ wg_free_device(*device);
+ *device = NULL;
+ return -errno;
+ }
+
+ nlh = mnlg_msg_prepare(nlg, WG_CMD_GET_DEVICE, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP);
+ mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, device_name);
+ if (mnlg_socket_send(nlg, nlh) < 0) {
+ ret = -errno;
+ goto out;
+ }
+ errno = 0;
+ if (mnlg_socket_recv_run(nlg, read_device_cb, *device) < 0) {
+ ret = errno ? -errno : -EINVAL;
+ goto out;
+ }
+ coalesce_peers(*device);
+
+out:
+ if (nlg)
+ mnlg_socket_close(nlg);
+ if (ret) {
+ wg_free_device(*device);
+ if (ret == -EINTR)
+ goto try_again;
+ *device = NULL;
+ }
+ errno = -ret;
+ return ret;
+}
+
+/* first\0second\0third\0forth\0last\0\0 */
+char *wg_list_device_names(void)
+{
+ struct string_list list = { 0 };
+ int ret = fetch_device_names(&list);
+
+ errno = -ret;
+ if (errno) {
+ free(list.buffer);
+ return NULL;
+ }
+ return list.buffer ?: strdup("\0");
+}
+
+int wg_add_device(const char *device_name)
+{
+ return add_del_iface(device_name, true);
+}
+
+int wg_del_device(const char *device_name)
+{
+ return add_del_iface(device_name, false);
+}
+
+void wg_free_device(wg_device *dev)
+{
+ wg_peer *peer, *np;
+ wg_allowedip *allowedip, *na;
+
+ if (!dev)
+ return;
+ for (peer = dev->first_peer, np = peer ? peer->next_peer : NULL; peer; peer = np, np = peer ? peer->next_peer : NULL) {
+ for (allowedip = peer->first_allowedip, na = allowedip ? allowedip->next_allowedip : NULL; allowedip; allowedip = na, na = allowedip ? allowedip->next_allowedip : NULL)
+ free(allowedip);
+ free(peer);
+ }
+ free(dev);
+}
+
+static void encode_base64(char dest[static 4], const uint8_t src[static 3])
+{
+ const uint8_t input[] = { (src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63 };
+ unsigned int i;
+
+ for (i = 0; i < 4; ++i)
+ dest[i] = input[i] + 'A'
+ + (((25 - input[i]) >> 8) & 6)
+ - (((51 - input[i]) >> 8) & 75)
+ - (((61 - input[i]) >> 8) & 15)
+ + (((62 - input[i]) >> 8) & 3);
+
+}
+
+void wg_key_to_base64(wg_key_b64_string base64, const wg_key key)
+{
+ unsigned int i;
+
+ for (i = 0; i < 32 / 3; ++i)
+ encode_base64(&base64[i * 4], &key[i * 3]);
+ encode_base64(&base64[i * 4], (const uint8_t[]){ key[i * 3 + 0], key[i * 3 + 1], 0 });
+ base64[sizeof(wg_key_b64_string) - 2] = '=';
+ base64[sizeof(wg_key_b64_string) - 1] = '\0';
+}
+
+static int decode_base64(const char src[static 4])
+{
+ int val = 0;
+ unsigned int i;
+
+ for (i = 0; i < 4; ++i)
+ val |= (-1
+ + ((((('A' - 1) - src[i]) & (src[i] - ('Z' + 1))) >> 8) & (src[i] - 64))
+ + ((((('a' - 1) - src[i]) & (src[i] - ('z' + 1))) >> 8) & (src[i] - 70))
+ + ((((('0' - 1) - src[i]) & (src[i] - ('9' + 1))) >> 8) & (src[i] + 5))
+ + ((((('+' - 1) - src[i]) & (src[i] - ('+' + 1))) >> 8) & 63)
+ + ((((('/' - 1) - src[i]) & (src[i] - ('/' + 1))) >> 8) & 64)
+ ) << (18 - 6 * i);
+ return val;
+}
+
+int wg_key_from_base64(wg_key key, const wg_key_b64_string base64)
+{
+ unsigned int i;
+ int val;
+ volatile uint8_t ret = 0;
+
+ if (strlen(base64) != sizeof(wg_key_b64_string) - 1 || base64[sizeof(wg_key_b64_string) - 2] != '=') {
+ errno = EINVAL;
+ goto out;
+ }
+
+ for (i = 0; i < 32 / 3; ++i) {
+ val = decode_base64(&base64[i * 4]);
+ ret |= (uint32_t)val >> 31;
+ key[i * 3 + 0] = (val >> 16) & 0xff;
+ key[i * 3 + 1] = (val >> 8) & 0xff;
+ key[i * 3 + 2] = val & 0xff;
+ }
+ val = decode_base64((const char[]){ base64[i * 4 + 0], base64[i * 4 + 1], base64[i * 4 + 2], 'A' });
+ ret |= ((uint32_t)val >> 31) | (val & 0xff);
+ key[i * 3 + 0] = (val >> 16) & 0xff;
+ key[i * 3 + 1] = (val >> 8) & 0xff;
+ errno = EINVAL & ~((ret - 1) >> 8);
+out:
+ return -errno;
+}
+
+typedef int64_t fe[16];
+
+static __attribute__((noinline)) void memzero_explicit(void *s, size_t count)
+{
+ memset(s, 0, count);
+ __asm__ __volatile__("": :"r"(s) :"memory");
+}
+
+static void carry(fe o)
+{
+ int i;
+
+ for (i = 0; i < 16; ++i) {
+ o[(i + 1) % 16] += (i == 15 ? 38 : 1) * (o[i] >> 16);
+ o[i] &= 0xffff;
+ }
+}
+
+static void cswap(fe p, fe q, int b)
+{
+ int i;
+ int64_t t, c = ~(b - 1);
+
+ for (i = 0; i < 16; ++i) {
+ t = c & (p[i] ^ q[i]);
+ p[i] ^= t;
+ q[i] ^= t;
+ }
+
+ memzero_explicit(&t, sizeof(t));
+ memzero_explicit(&c, sizeof(c));
+ memzero_explicit(&b, sizeof(b));
+}
+
+static void pack(uint8_t *o, const fe n)
+{
+ int i, j, b;
+ fe m, t;
+
+ memcpy(t, n, sizeof(t));
+ carry(t);
+ carry(t);
+ carry(t);
+ for (j = 0; j < 2; ++j) {
+ m[0] = t[0] - 0xffed;
+ for (i = 1; i < 15; ++i) {
+ m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
+ m[i - 1] &= 0xffff;
+ }
+ m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
+ b = (m[15] >> 16) & 1;
+ m[14] &= 0xffff;
+ cswap(t, m, 1 - b);
+ }
+ for (i = 0; i < 16; ++i) {
+ o[2 * i] = t[i] & 0xff;
+ o[2 * i + 1] = t[i] >> 8;
+ }
+
+ memzero_explicit(m, sizeof(m));
+ memzero_explicit(t, sizeof(t));
+ memzero_explicit(&b, sizeof(b));
+}
+
+static void add(fe o, const fe a, const fe b)
+{
+ int i;
+
+ for (i = 0; i < 16; ++i)
+ o[i] = a[i] + b[i];
+}
+
+static void subtract(fe o, const fe a, const fe b)
+{
+ int i;
+
+ for (i = 0; i < 16; ++i)
+ o[i] = a[i] - b[i];
+}
+
+static void multmod(fe o, const fe a, const fe b)
+{
+ int i, j;
+ int64_t t[31] = { 0 };
+
+ for (i = 0; i < 16; ++i) {
+ for (j = 0; j < 16; ++j)
+ t[i + j] += a[i] * b[j];
+ }
+ for (i = 0; i < 15; ++i)
+ t[i] += 38 * t[i + 16];
+ memcpy(o, t, sizeof(fe));
+ carry(o);
+ carry(o);
+
+ memzero_explicit(t, sizeof(t));
+}
+
+static void invert(fe o, const fe i)
+{
+ fe c;
+ int a;
+
+ memcpy(c, i, sizeof(c));
+ for (a = 253; a >= 0; --a) {
+ multmod(c, c, c);
+ if (a != 2 && a != 4)
+ multmod(c, c, i);
+ }
+ memcpy(o, c, sizeof(fe));
+
+ memzero_explicit(c, sizeof(c));
+}
+
+static void clamp_key(uint8_t *z)
+{
+ z[31] = (z[31] & 127) | 64;
+ z[0] &= 248;
+}
+
+void wg_generate_public_key(wg_key public_key, const wg_key private_key)
+{
+ int i, r;
+ uint8_t z[32];
+ fe a = { 1 }, b = { 9 }, c = { 0 }, d = { 1 }, e, f;
+
+ memcpy(z, private_key, sizeof(z));
+ clamp_key(z);
+
+ for (i = 254; i >= 0; --i) {
+ r = (z[i >> 3] >> (i & 7)) & 1;
+ cswap(a, b, r);
+ cswap(c, d, r);
+ add(e, a, c);
+ subtract(a, a, c);
+ add(c, b, d);
+ subtract(b, b, d);
+ multmod(d, e, e);
+ multmod(f, a, a);
+ multmod(a, c, a);
+ multmod(c, b, e);
+ add(e, a, c);
+ subtract(a, a, c);
+ multmod(b, a, a);
+ subtract(c, d, f);
+ multmod(a, c, (const fe){ 0xdb41, 1 });
+ add(a, a, d);
+ multmod(c, c, a);
+ multmod(a, d, f);
+ multmod(d, b, (const fe){ 9 });
+ multmod(b, e, e);
+ cswap(a, b, r);
+ cswap(c, d, r);
+ }
+ invert(c, c);
+ multmod(a, a, c);
+ pack(public_key, a);
+
+ memzero_explicit(&r, sizeof(r));
+ memzero_explicit(z, sizeof(z));
+ memzero_explicit(a, sizeof(a));
+ memzero_explicit(b, sizeof(b));
+ memzero_explicit(c, sizeof(c));
+ memzero_explicit(d, sizeof(d));
+ memzero_explicit(e, sizeof(e));
+ memzero_explicit(f, sizeof(f));
+}
+
+void wg_generate_private_key(wg_key private_key)
+{
+ wg_generate_preshared_key(private_key);
+ clamp_key(private_key);
+}
+
+void wg_generate_preshared_key(wg_key preshared_key)
+{
+ ssize_t ret;
+ size_t i;
+ int fd;
+#if defined(__OpenBSD__) || (defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) || (defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)))
+ if (!getentropy(preshared_key, sizeof(wg_key)))
+ return;
+#endif
+#if defined(__NR_getrandom) && defined(__linux__)
+ if (syscall(__NR_getrandom, preshared_key, sizeof(wg_key), 0) == sizeof(wg_key))
+ return;
+#endif
+ fd = open("/dev/urandom", O_RDONLY);
+ assert(fd >= 0);
+ for (i = 0; i < sizeof(wg_key); i += ret) {
+ ret = read(fd, preshared_key + i, sizeof(wg_key) - i);
+ assert(ret > 0);
+ }
+ close(fd);
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/*
+ * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+#ifndef WIREGUARD_H
+#define WIREGUARD_H
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef uint8_t wg_key[32];
+typedef char wg_key_b64_string[((sizeof(wg_key) + 2) / 3) * 4 + 1];
+
+/* Cross platform __kernel_timespec */
+struct timespec64 {
+ int64_t tv_sec;
+ int64_t tv_nsec;
+};
+
+typedef struct wg_allowedip {
+ uint16_t family;
+ union {
+ struct in_addr ip4;
+ struct in6_addr ip6;
+ };
+ uint8_t cidr;
+ struct wg_allowedip *next_allowedip;
+} wg_allowedip;
+
+enum wg_peer_flags {
+ WGPEER_REMOVE_ME = 1U << 0,
+ WGPEER_REPLACE_ALLOWEDIPS = 1U << 1,
+ WGPEER_HAS_PUBLIC_KEY = 1U << 2,
+ WGPEER_HAS_PRESHARED_KEY = 1U << 3,
+ WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4
+};
+
+typedef union wg_endpoint {
+ struct sockaddr addr;
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+} wg_endpoint;
+
+typedef struct wg_peer {
+ enum wg_peer_flags flags;
+
+ wg_key public_key;
+ wg_key preshared_key;
+
+ wg_endpoint endpoint;
+
+ struct timespec64 last_handshake_time;
+ uint64_t rx_bytes, tx_bytes;
+ uint16_t persistent_keepalive_interval;
+
+ struct wg_allowedip *first_allowedip, *last_allowedip;
+ struct wg_peer *next_peer;
+} wg_peer;
+
+enum wg_device_flags {
+ WGDEVICE_REPLACE_PEERS = 1U << 0,
+ WGDEVICE_HAS_PRIVATE_KEY = 1U << 1,
+ WGDEVICE_HAS_PUBLIC_KEY = 1U << 2,
+ WGDEVICE_HAS_LISTEN_PORT = 1U << 3,
+ WGDEVICE_HAS_FWMARK = 1U << 4
+};
+
+typedef struct wg_device {
+ char name[IFNAMSIZ];
+ uint32_t ifindex;
+
+ enum wg_device_flags flags;
+
+ wg_key public_key;
+ wg_key private_key;
+
+ uint32_t fwmark;
+ uint16_t listen_port;
+
+ struct wg_peer *first_peer, *last_peer;
+} wg_device;
+
+#define wg_for_each_device_name(__names, __name, __len) for ((__name) = (__names), (__len) = 0; ((__len) = strlen(__name)); (__name) += (__len) + 1)
+#define wg_for_each_peer(__dev, __peer) for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer)
+#define wg_for_each_allowedip(__peer, __allowedip) for ((__allowedip) = (__peer)->first_allowedip; (__allowedip); (__allowedip) = (__allowedip)->next_allowedip)
+
+int wg_set_device(wg_device *dev);
+int wg_get_device(wg_device **dev, const char *device_name);
+int wg_add_device(const char *device_name);
+int wg_del_device(const char *device_name);
+void wg_free_device(wg_device *dev);
+char *wg_list_device_names(void); /* first\0second\0third\0forth\0last\0\0 */
+void wg_key_to_base64(wg_key_b64_string base64, const wg_key key);
+int wg_key_from_base64(wg_key key, const wg_key_b64_string base64);
+bool wg_key_is_zero(const wg_key key);
+void wg_generate_public_key(wg_key public_key, const wg_key private_key);
+void wg_generate_private_key(wg_key private_key);
+void wg_generate_preshared_key(wg_key preshared_key);
+
+#endif
include $(TOPDIR)/rules.mk
PKG_NAME:=sockread
-PKG_VERSION:=1.0
-PKG_RELEASE:=2
+PKG_VERSION:=1.1
+PKG_RELEASE:=1
PKG_LICENSE:=CC0-1.0
include $(INCLUDE_DIR)/package.mk
define Package/sockread
SECTION:=utils
CATEGORY:=Utilities
- TITLE:=sockread
+ TITLE:=Unix domain sockets utility
MAINTAINER:=Moritz Warning <moritzwarning@web.de>
endef
define Package/sockread/description
- sockread writes and reads data from a Unix domain socket
- represented as a special file on the file system.
+ Command line utility to read and write to Unix domain sockets.
endef
define Build/Prepare
#include <sys/socket.h>
#include <sys/un.h>
-int main(int argc, char *argv[]) {
- char buf[1024];
- ssize_t r;
-
- if (argc != 2) {
- fprintf(stderr, "Write to and read from a Unix domain socket.\n\nUsage: %s <socket>\n", argv[0]);
- return 1;
- }
-
- size_t addrlen = strlen(argv[1]);
-
- /* Allocate enough space for arbitrary-length paths */
- char addrbuf[offsetof(struct sockaddr_un, sun_path) + addrlen + 1];
- memset(addrbuf, 0, sizeof(addrbuf));
-
- struct sockaddr_un *addr = (struct sockaddr_un *)addrbuf;
- addr->sun_family = AF_UNIX;
- memcpy(addr->sun_path, argv[1], addrlen+1);
-
- int fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (fd < 0) {
- fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
- return 1;
- }
-
- if (connect(fd, (struct sockaddr*)addr, sizeof(addrbuf)) < 0) {
- fprintf(stderr, "Can't connect to `%s': %s\n", argv[1], strerror(errno));
- return 1;
- }
-
- /* Check if stdin refers to a terminal */
- if (!isatty(fileno(stdin))) {
- /* Read from stdin and write to socket */
- while (0 < (r = fread(buf, 1, sizeof(buf), stdin))) {
- send(fd, buf, r, 0);
- }
- }
-
- /* Read from socket and write to stdout */
- while (1) {
- r = recv(fd, buf, sizeof(buf), 0);
- if (r < 0) {
- fprintf(stderr, "read: %s\n", strerror(errno));
- return 1;
- }
-
- if (r == 0)
- return 0;
-
- fwrite(buf, r, 1, stdout);
- }
-
- return 0;
+const char *usage =
+ "Write to and read from a Unix domain socket.\n"
+ "Add commands to send as arguments or pass by pipe.\n"
+ "\n"
+ "Usage: sockread <path> [<commands>]\n";
+
+int main(int argc, char *argv[])
+{
+ char buffer[1024];
+ ssize_t r;
+
+ if (argc < 2) {
+ fprintf(stderr, "%s", usage);
+ return EXIT_FAILURE;
+ }
+
+ struct sockaddr_un address = {0};
+ address.sun_family = AF_UNIX;
+ strcpy((char*) &address.sun_path, argv[1]);
+
+ int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ fprintf(stderr, "socket() %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ if (connect(sock, (struct sockaddr*)&address, sizeof(address)) < 0) {
+ fprintf(stderr, "connect() %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ /* Check if stdin refers to a terminal */
+ if (!isatty(fileno(stdin))) {
+ /* Read from stdin and write to socket */
+ while (0 < (r = fread(buffer, 1, sizeof(buffer), stdin))) {
+ send(sock, buffer, r, 0);
+ }
+ } else {
+ for (size_t i = 2; i < argc; i++) {
+ if (i > 2) {
+ send(sock, " ", 1, 0);
+ }
+ send(sock, argv[i], strlen(argv[i]), 0);
+ }
+ }
+
+ /* Read from socket and write to stdout */
+ while (1) {
+ r = recv(sock, buffer, sizeof(buffer), 0);
+ if (r < 0) {
+ fprintf(stderr, "recv() %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ if (r == 0)
+ break;
+
+ fwrite(buffer, r, 1, stdout);
+ }
+
+ return EXIT_SUCCESS;
}
include $(TOPDIR)/rules.mk
PKG_NAME:=stress-ng
-PKG_VERSION:=0.15.10
-PKG_RELEASE:=1
+PKG_VERSION:=0.17.00
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/ColinIanKing/stress-ng/tar.gz/refs/tags/V$(PKG_VERSION)?
-PKG_HASH:=fcd86e1b8db5b2c22182cefbf4b3131a8599bff5bdd85edf776ec15c2d80e8f1
+PKG_HASH:=eca62128f4918edc6d1e309f426a223968f44b304b737275443ec9e62855d42e
PKG_MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>
PKG_LICENSE:=GPL-2.0-only
--- a/Makefile.config
+++ b/Makefile.config
-@@ -319,9 +319,9 @@ compiler: configdir
+@@ -326,9 +326,9 @@ clean:
libraries: \
- compiler \
+ configdir \
LIB_AIO LIB_APPARMOR LIB_BSD LIB_CRYPT LIB_DL \
- LIB_EGL LIB_GBM LIB_GLES2 LIB_IPSEC_MB LIB_JPEG \
- LIB_JUDY LIB_KMOD LIB_MD LIB_MPFR LIB_PTHREAD LIB_PTHREAD_SPINLOCK \
+ LIB_JUDY LIB_KMOD LIB_MD LIB_PTHREAD LIB_PTHREAD_SPINLOCK \
+ LIB_RT LIB_SCTP LIB_Z
- LIB_AIO: compiler
+ LIB_AIO:
$(call check,test-libaio,HAVE_LIB_AIO,$(LIB_AIO),$(LIB_AIO))
--- /dev/null
+From cd84c46ce780242879e8aaa7d698b9cd87996dbd Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.i.king@gmail.com>
+Date: Sun, 15 Oct 2023 15:50:07 +0100
+Subject: [PATCH] core-*, stress-*: Add musl-gcc detection and
+ HAVE_COMPILER_MUSL
+
+Detect for musl-gcc and define HAVE_COMPILER_MUSL and also define
+HAVE_COMPILER_GCC_OR_MUSL for GCC or MUSL compilers. Allows one
+to differentiate between gcc tool chains with and without glibc/musl
+libc.
+
+Fixes https://github.com/ColinIanKing/stress-ng/issues/325
+
+Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
+---
+ core-attribute.h | 56 ++++++++++++++++++++++----------------------
+ core-helper.c | 4 ++--
+ core-pragma.h | 18 +++++++-------
+ core-shim.c | 2 +-
+ core-target-clones.h | 2 +-
+ core-vecmath.h | 4 ++--
+ stress-atomic.c | 4 ++--
+ stress-flushcache.c | 2 +-
+ stress-lockbus.c | 4 ++--
+ stress-malloc.c | 4 ++--
+ stress-memthrash.c | 12 +++++-----
+ stress-ng.h | 32 ++++++++++++++++---------
+ stress-regs.c | 8 +++----
+ stress-rseq.c | 14 +++++------
+ stress-vnni.c | 4 ++++
+ 15 files changed, 92 insertions(+), 78 deletions(-)
+
+--- a/core-attribute.h
++++ b/core-attribute.h
+@@ -20,7 +20,7 @@
+ #define CORE_ATTRIBUTE_H
+
+ /* warn unused attribute */
+-#if (defined(HAVE_COMPILER_GCC) && NEED_GNUC(4, 2, 0)) || \
++#if (defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(4, 2, 0)) || \
+ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0))
+ #define WARN_UNUSED __attribute__((warn_unused_result))
+ #else
+@@ -36,7 +36,7 @@
+
+ #if defined(HAVE_ATTRIBUTE_FAST_MATH) && \
+ !defined(HAVE_COMPILER_ICC) && \
+- defined(HAVE_COMPILER_GCC) && \
++ defined(HAVE_COMPILER_GCC_OR_MUSL) && \
+ NEED_GNUC(10, 0, 0)
+ #define OPTIMIZE_FAST_MATH __attribute__((optimize("fast-math")))
+ #else
+@@ -44,7 +44,7 @@
+ #endif
+
+ /* no return hint */
+-#if (defined(HAVE_COMPILER_GCC) && NEED_GNUC(2, 5, 0)) || \
++#if (defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(2, 5, 0)) || \
+ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0))
+ #define NORETURN __attribute__((noreturn))
+ #else
+@@ -52,7 +52,7 @@
+ #endif
+
+ /* weak attribute */
+-#if (defined(HAVE_COMPILER_GCC) && NEED_GNUC(4, 0, 0)) || \
++#if (defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(4, 0, 0)) || \
+ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 4, 0))
+ #define WEAK __attribute__((weak))
+ #define HAVE_WEAK_ATTRIBUTE
+@@ -64,7 +64,7 @@
+ #undef ALWAYS_INLINE
+ #endif
+ /* force inlining hint */
+-#if (defined(HAVE_COMPILER_GCC) && NEED_GNUC(3, 4, 0) \
++#if (defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(3, 4, 0) \
+ && ((!defined(__s390__) && !defined(__s390x__)) || NEED_GNUC(6, 0, 1))) || \
+ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0))
+ #define ALWAYS_INLINE __attribute__((always_inline))
+@@ -73,7 +73,7 @@
+ #endif
+
+ /* force no inlining hint */
+-#if (defined(HAVE_COMPILER_GCC) && NEED_GNUC(3, 4, 0)) || \
++#if (defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(3, 4, 0)) || \
+ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0))
+ #define NOINLINE __attribute__((noinline))
+ #else
+@@ -81,9 +81,9 @@
+ #endif
+
+ /* -O3 attribute support */
+-#if defined(HAVE_COMPILER_GCC) && \
+- !defined(HAVE_COMPILER_CLANG) && \
+- !defined(HAVE_COMPILER_ICC) && \
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ !defined(HAVE_COMPILER_CLANG) && \
++ !defined(HAVE_COMPILER_ICC) && \
+ NEED_GNUC(4, 6, 0)
+ #define OPTIMIZE3 __attribute__((optimize("-O3")))
+ #else
+@@ -91,9 +91,9 @@
+ #endif
+
+ /* -O2 attribute support */
+-#if defined(HAVE_COMPILER_GCC) && \
+- !defined(HAVE_COMPILER_CLANG) && \
+- !defined(HAVE_COMPILER_ICC) && \
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ !defined(HAVE_COMPILER_CLANG) && \
++ !defined(HAVE_COMPILER_ICC) && \
+ NEED_GNUC(4, 6, 0)
+ #define OPTIMIZE2 __attribute__((optimize("-O2")))
+ #else
+@@ -101,9 +101,9 @@
+ #endif
+
+ /* -O1 attribute support */
+-#if defined(HAVE_COMPILER_GCC) && \
+- !defined(HAVE_COMPILER_CLANG) && \
+- !defined(HAVE_COMPILER_ICC) && \
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ !defined(HAVE_COMPILER_CLANG) && \
++ !defined(HAVE_COMPILER_ICC) && \
+ NEED_GNUC(4, 6, 0)
+ #define OPTIMIZE1 __attribute__((optimize("-O1")))
+ #else
+@@ -111,8 +111,8 @@
+ #endif
+
+ /* -O0 attribute support */
+-#if defined(HAVE_COMPILER_GCC) && \
+- !defined(HAVE_COMPILER_ICC) && \
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ !defined(HAVE_COMPILER_ICC) && \
+ NEED_GNUC(4, 6, 0)
+ #define OPTIMIZE0 __attribute__((optimize("-O0")))
+ #elif (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(10, 0, 0))
+@@ -121,10 +121,10 @@
+ #define OPTIMIZE0
+ #endif
+
+-#if ((defined(HAVE_COMPILER_GCC) && NEED_GNUC(3, 3, 0)) || \
+- (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0)) || \
+- (defined(HAVE_COMPILER_ICC) && NEED_ICC(2021, 0, 0))) && \
+- !defined(HAVE_COMPILER_PCC) && \
++#if ((defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(3, 3, 0)) || \
++ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0)) || \
++ (defined(HAVE_COMPILER_ICC) && NEED_ICC(2021, 0, 0))) && \
++ !defined(HAVE_COMPILER_PCC) && \
+ !defined(__minix__)
+ #define ALIGNED(a) __attribute__((aligned(a)))
+ #else
+@@ -136,7 +136,7 @@
+ #define ALIGN64 ALIGNED(64)
+
+
+-#if (defined(HAVE_COMPILER_GCC) && NEED_GNUC(4, 6, 0)) || \
++#if (defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(4, 6, 0)) || \
+ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0))
+ #if (defined(__APPLE__) && defined(__MACH__))
+ #define SECTION(s) __attribute__((__section__(# s "," # s)))
+@@ -148,7 +148,7 @@
+ #endif
+
+ /* GCC hot attribute */
+-#if (defined(HAVE_COMPILER_GCC) && NEED_GNUC(4, 6, 0)) || \
++#if (defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(4, 6, 0)) || \
+ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 3, 0))
+ #define HOT __attribute__((hot))
+ #else
+@@ -156,10 +156,10 @@
+ #endif
+
+ /* GCC mlocked data and data section attribute */
+-#if ((defined(HAVE_COMPILER_GCC) && NEED_GNUC(4, 6, 0) || \
+- (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0)))) && \
+- !defined(__sun__) && \
+- !defined(__APPLE__) && \
++#if ((defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(4, 6, 0) || \
++ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0)))) && \
++ !defined(__sun__) && \
++ !defined(__APPLE__) && \
+ !defined(BUILD_STATIC)
+ #define MLOCKED_TEXT __attribute__((__section__("mlocked_text")))
+ #define MLOCKED_SECTION (1)
+@@ -168,7 +168,7 @@
+ #endif
+
+ /* print format attribute */
+-#if ((defined(HAVE_COMPILER_GCC) && NEED_GNUC(3, 2, 0)) || \
++#if ((defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(3, 2, 0)) || \
+ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(3, 0, 0)))
+ #define FORMAT(func, a, b) __attribute__((format(func, a, b)))
+ #else
+--- a/core-helper.c
++++ b/core-helper.c
+@@ -3486,8 +3486,8 @@ void NORETURN MLOCKED_TEXT stress_sig_ha
+ * __stack_chk_fail()
+ * override stack smashing callback
+ */
+-#if defined(HAVE_COMPILER_GCC) && \
+- !defined(HAVE_COMPILER_CLANG) && \
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ !defined(HAVE_COMPILER_CLANG) && \
+ defined(HAVE_WEAK_ATTRIBUTE)
+ extern void __stack_chk_fail(void);
+
+--- a/core-pragma.h
++++ b/core-pragma.h
+@@ -22,8 +22,8 @@
+ #define STRESS_PRAGMA_(x) _Pragma (#x)
+ #define STRESS_PRAGMA(x) STRESS_PRAGMA_(x)
+
+-#if defined(HAVE_PRAGMA_NO_HARD_DFP) && \
+- defined(HAVE_COMPILER_GCC) && \
++#if defined(HAVE_PRAGMA_NO_HARD_DFP) && \
++ defined(HAVE_COMPILER_GCC_OR_MUSL) && \
+ defined(HAVE_PRAGMA)
+ #define STRESS_PRAGMA_NO_HARD_DFP _Pragma("GCC target (\"no-hard-dfp\")")
+ #endif
+@@ -34,8 +34,8 @@
+ #define STRESS_PRAGMA_PUSH _Pragma("GCC diagnostic push")
+ #define STRESS_PRAGMA_POP _Pragma("GCC diagnostic pop")
+ #define STRESS_PRAGMA_WARN_OFF _Pragma("GCC diagnostic ignored \"-Weverything\"")
+-#elif defined(HAVE_COMPILER_GCC) && \
+- defined(HAVE_PRAGMA) && \
++#elif defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ defined(HAVE_PRAGMA) && \
+ NEED_GNUC(7, 5, 0)
+ #define STRESS_PRAGMA_PUSH _Pragma("GCC diagnostic push")
+ #define STRESS_PRAGMA_POP _Pragma("GCC diagnostic pop")
+@@ -45,8 +45,8 @@
+ _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") \
+ _Pragma("GCC diagnostic ignored \"-Wnonnull\"") \
+ _Pragma("GCC diagnostic ignored \"-Wstringop-overflow\"")
+-#elif defined(HAVE_COMPILER_GCC) && \
+- defined(HAVE_PRAGMA) && \
++#elif defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ defined(HAVE_PRAGMA) && \
+ NEED_GNUC(4, 6, 0)
+ #define STRESS_PRAGMA_PUSH _Pragma("GCC diagnostic push")
+ #define STRESS_PRAGMA_POP _Pragma("GCC diagnostic pop")
+@@ -65,8 +65,8 @@
+ NEED_CLANG(8, 0, 0) && \
+ defined(HAVE_PRAGMA)
+ #define STRESS_PRAGMA_WARN_CPP_OFF _Pragma("GCC diagnostic ignored \"-Wcpp\"")
+-#elif defined(HAVE_COMPILER_GCC) && \
+- defined(HAVE_PRAGMA) && \
++#elif defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ defined(HAVE_PRAGMA) && \
+ NEED_GNUC(10, 0, 0)
+ #define STRESS_PRAGMA_WARN_CPP_OFF _Pragma("GCC diagnostic ignored \"-Wcpp\"")
+ #else
+@@ -80,7 +80,7 @@
+ NEED_CLANG(9, 0, 0)
+ #define PRAGMA_UNROLL_N(n) STRESS_PRAGMA(unroll n)
+ #define PRAGMA_UNROLL STRESS_PRAGMA(unroll)
+-#elif defined(HAVE_COMPILER_GCC) && \
++#elif defined(HAVE_COMPILER_GCC_OR_MUSL) && \
+ NEED_GNUC(10, 0, 0)
+ #define PRAGMA_UNROLL_N(n) STRESS_PRAGMA(GCC unroll n)
+ #define PRAGMA_UNROLL STRESS_PRAGMA(GCC unroll 8)
+--- a/core-shim.c
++++ b/core-shim.c
+@@ -494,7 +494,7 @@ int shim_getrandom(void *buff, size_t bu
+ */
+ void shim_flush_icache(void *begin, void *end)
+ {
+-#if defined(HAVE_COMPILER_GCC) && \
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && \
+ defined(STRESS_ARCH_ARM)
+ __clear_cache(begin, end);
+ #elif defined(STRESS_ARCH_RISCV) && \
+--- a/core-target-clones.h
++++ b/core-target-clones.h
+@@ -138,7 +138,7 @@
+ #endif
+
+ #if defined(HAVE_TARGET_CLONES_GRANITERAPIDS) && \
+- defined(HAVE_COMPILER_GCC)
++ defined(HAVE_COMPILER_GCC_OR_MUSL)
+ #define TARGET_CLONE_GRANITERAPIDS "arch=graniterapids",
+ #define TARGET_CLONE_USE
+ #else
+--- a/core-vecmath.h
++++ b/core-vecmath.h
+@@ -38,8 +38,8 @@
+ * PPC64 for some reason with some flavours of the toolchain
+ * so disable this test for now
+ */
+-#if defined(STRESS_ARCH_PPC64) && \
+- defined(HAVE_COMPILER_GCC) && \
++#if defined(STRESS_ARCH_PPC64) && \
++ defined(HAVE_COMPILER_GCC_OR_MUSL) && \
+ __GNUC__ < 6
+ #undef HAVE_VECMATH
+ #endif
+--- a/stress-atomic.c
++++ b/stress-atomic.c
+@@ -71,7 +71,7 @@ typedef int (*atomic_func_t)(const stres
+
+ #if defined(HAVE_ATOMIC_FETCH_NAND)
+ #define HAVE_ATOMIC_OPS
+-#if defined(HAVE_COMPILER_GCC) && __GNUC__ != 11
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && __GNUC__ != 11
+ #define SHIM_ATOMIC_FETCH_NAND(ptr, val, memorder) \
+ do { __atomic_fetch_nand(ptr, val, memorder); } while (0)
+ #else
+@@ -121,7 +121,7 @@ typedef int (*atomic_func_t)(const stres
+
+ #if defined(HAVE_ATOMIC_NAND_FETCH)
+ #define HAVE_ATOMIC_OPS
+-#if defined(HAVE_COMPILER_GCC) && __GNUC__ != 11
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && __GNUC__ != 11
+ #define SHIM_ATOMIC_NAND_FETCH(ptr, val, memorder) \
+ do { __atomic_nand_fetch(ptr, val, memorder); } while (0)
+ #else
+--- a/stress-flushcache.c
++++ b/stress-flushcache.c
+@@ -37,7 +37,7 @@ static const stress_help_t help[] = {
+ defined(STRESS_ARCH_S390) || \
+ defined(STRESS_ARCH_PPC64)) && \
+ defined(HAVE_MPROTECT) && \
+- ((defined(HAVE_COMPILER_GCC) && NEED_GNUC(4,6,0)) || \
++ ((defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(4,6,0)) || \
+ (defined(HAVE_COMPILER_CLANG) && NEED_CLANG(9,0,0)) || \
+ (defined(HAVE_COMPILER_ICX) && NEED_ICX(2023,2,0)) || \
+ (defined(HAVE_COMPILER_ICC) && NEED_ICC(2021,0,0)))
+--- a/stress-lockbus.c
++++ b/stress-lockbus.c
+@@ -37,14 +37,14 @@ static const stress_opt_set_func_t opt_s
+ { 0, NULL },
+ };
+
+-#if (((defined(HAVE_COMPILER_GCC) || \
++#if (((defined(HAVE_COMPILER_GCC_OR_MUSL) || \
+ defined(HAVE_COMPILER_CLANG) || \
+ defined(HAVE_COMPILER_ICC) || \
+ defined(HAVE_COMPILER_ICX) || \
+ defined(HAVE_COMPILER_TCC) || \
+ defined(HAVE_COMPILER_PCC)) && \
+ defined(STRESS_ARCH_X86)) || \
+- (defined(HAVE_COMPILER_GCC) && \
++ (defined(HAVE_COMPILER_GCC_OR_MUSL) && \
+ (defined(HAVE_ATOMIC_ADD_FETCH) || \
+ defined(HAVE_ATOMIC_FETCH_ADD)) && \
+ defined(__ATOMIC_SEQ_CST) && \
+--- a/stress-malloc.c
++++ b/stress-malloc.c
+@@ -453,8 +453,8 @@ static int stress_malloc(const stress_ar
+ malloc_max = MIN_MALLOC_MAX;
+ }
+
+-#if defined(HAVE_COMPILER_GCC) && \
+- defined(HAVE_MALLOPT) && \
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ defined(HAVE_MALLOPT) && \
+ defined(M_MMAP_THRESHOLD)
+ {
+ size_t malloc_threshold = DEFAULT_MALLOC_THRESHOLD;
+--- a/stress-memthrash.c
++++ b/stress-memthrash.c
+@@ -94,12 +94,12 @@ static sigset_t set;
+
+ static stress_memthrash_primes_t stress_memthrash_primes[MEM_SIZE_PRIMES];
+
+-#if (((defined(HAVE_COMPILER_GCC) || defined(HAVE_COMPILER_CLANG)) && \
+- defined(STRESS_ARCH_X86)) || \
+- (defined(HAVE_COMPILER_GCC) && \
+- defined(HAVE_ATOMIC_ADD_FETCH) && \
+- defined(__ATOMIC_SEQ_CST) && \
+- NEED_GNUC(4,7,0) && \
++#if (((defined(HAVE_COMPILER_GCC_OR_MUSL) || defined(HAVE_COMPILER_CLANG)) && \
++ defined(STRESS_ARCH_X86)) || \
++ (defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ defined(HAVE_ATOMIC_ADD_FETCH) && \
++ defined(__ATOMIC_SEQ_CST) && \
++ NEED_GNUC(4,7,0) && \
+ defined(STRESS_ARCH_ARM)))
+ #if defined(HAVE_ATOMIC_ADD_FETCH)
+ #define MEM_LOCK(ptr, inc) __atomic_add_fetch(ptr, inc, __ATOMIC_SEQ_CST)
+--- a/stress-ng.h
++++ b/stress-ng.h
+@@ -22,6 +22,14 @@
+
+ #include "config.h"
+
++#ifndef _GNU_SOURCE
++#define _GNU_SOURCE
++#endif
++
++#if defined(HAVE_FEATURES_H)
++#include <features.h>
++#endif
++
+ #if defined(__ICC) && \
+ defined(__INTEL_COMPILER)
+ /* Intel ICC compiler */
+@@ -41,15 +49,20 @@
+ #elif defined(__clang__)
+ /* clang */
+ #define HAVE_COMPILER_CLANG
++#elif defined(__GNUC__) && \
++ !defined(__USE_GNU)
++/* musl gcc */
++#define HAVE_COMPILER_MUSL
++#define HAVE_COMPILER_GCC_OR_MUSL
+ #elif defined(__GNUC__)
+ /* GNU C compiler */
+ #define HAVE_COMPILER_GCC
++#define HAVE_COMPILER_GCC_OR_MUSL
+ #endif
+
+-#ifndef _GNU_SOURCE
+-#define _GNU_SOURCE
+-#endif
++#ifndef _ATFILE_SOURCE
+ #define _ATFILE_SOURCE
++#endif
+ #ifndef _LARGEFILE_SOURCE
+ #define _LARGEFILE_SOURCE
+ #endif
+@@ -101,9 +114,6 @@
+ #include <string.h>
+ #include <time.h>
+ #include <unistd.h>
+-#if defined(HAVE_FEATURES_H)
+-#include <features.h>
+-#endif
+ #if defined(HAVE_LIB_PTHREAD)
+ #include <pthread.h>
+ #endif
+@@ -144,7 +154,7 @@
+ #endif
+ #if defined(HAVE_SYS_SYSINFO_H)
+ #include <sys/sysinfo.h>
+-#if defined(HAVE_COMPILER_GCC) && \
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && \
+ !defined(__GLIBC__)
+ /* Suppress kernel sysinfo to avoid collision with musl */
+ #define _LINUX_SYSINFO_H
+@@ -237,7 +247,7 @@ typedef struct stress_stressor_info {
+
+ #if defined(CHECK_UNEXPECTED) && \
+ defined(HAVE_PRAGMA) && \
+- defined(HAVE_COMPILER_GCC)
++ defined(HAVE_COMPILER_GCC_OR_MUSL)
+ #define UNEXPECTED_PRAGMA(x) _Pragma (#x)
+ #define UNEXPECTED_XSTR(x) UNEXPECTED_STR(x)
+ #define UNEXPECTED_STR(x) # x
+@@ -427,7 +437,7 @@ typedef struct stressor_info {
+ } stressor_info_t;
+
+ /* gcc 4.7 and later support vector ops */
+-#if defined(HAVE_COMPILER_GCC) && \
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) && \
+ NEED_GNUC(4, 7, 0)
+ #define STRESS_VECTOR (1)
+ #endif
+@@ -508,7 +518,7 @@ extern const char stress_config[];
+ #define PAGE_MAPPED (0x01)
+ #define PAGE_MAPPED_FAIL (0x02)
+
+-#if defined(HAVE_COMPILER_GCC) || defined(HAVE_COMPILER_CLANG)
++#if defined(HAVE_COMPILER_GCC_OR_MUSL) || defined(HAVE_COMPILER_CLANG)
+ #define TYPEOF_CAST(a) (typeof(a))
+ #else
+ #define TYPEOF_CAST(a)
+@@ -839,7 +849,7 @@ extern void stress_metrics_set_const_che
+
+ #if !defined(STRESS_CORE_SHIM) && \
+ !defined(HAVE_PEDANTIC) && \
+- (defined(HAVE_COMPILER_GCC) && defined(HAVE_COMPILER_CLANG))
++ (defined(HAVE_COMPILER_GCC_OR_MUSL) && defined(HAVE_COMPILER_CLANG))
+ int unlink(const char *pathname) __attribute__((deprecated("use shim_unlink")));
+ int unlinkat(int dirfd, const char *pathname, int flags) __attribute__((deprecated("use shim_unlinkat")));
+ int rmdir(const char *pathname) __attribute__((deprecated("use shim_rmdir")));
+--- a/stress-regs.c
++++ b/stress-regs.c
+@@ -33,10 +33,10 @@ static const stress_help_t help[] = {
+ { NULL, NULL, NULL }
+ };
+
+-#if (defined(HAVE_COMPILER_GCC) && NEED_GNUC(8, 0, 0)) && \
+- !defined(HAVE_COMPILER_CLANG) && \
+- !defined(HAVE_COMPILER_ICC) && \
+- !defined(HAVE_COMPILER_PCC) && \
++#if (defined(HAVE_COMPILER_GCC_OR_MUSL) && NEED_GNUC(8, 0, 0)) && \
++ !defined(HAVE_COMPILER_CLANG) && \
++ !defined(HAVE_COMPILER_ICC) && \
++ !defined(HAVE_COMPILER_PCC) && \
+ !defined(HAVE_COMPILER_TCC)
+
+ static volatile uint32_t stash32;
+--- a/stress-rseq.c
++++ b/stress-rseq.c
+@@ -32,13 +32,13 @@ static const stress_help_t help[] = {
+ { NULL, NULL, NULL }
+ };
+
+-#if defined(HAVE_LINUX_RSEQ_H) && \
+- defined(HAVE_ASM_NOP) && \
+- defined(__NR_rseq) && \
+- defined(HAVE_SYSCALL) && \
+- defined(HAVE_COMPILER_GCC) && \
+- !defined(HAVE_COMPILER_CLANG) && \
+- !defined(HAVE_COMPILER_ICC) && \
++#if defined(HAVE_LINUX_RSEQ_H) && \
++ defined(HAVE_ASM_NOP) && \
++ defined(__NR_rseq) && \
++ defined(HAVE_SYSCALL) && \
++ defined(HAVE_COMPILER_GCC_OR_MUSL) && \
++ !defined(HAVE_COMPILER_CLANG) && \
++ !defined(HAVE_COMPILER_ICC) && \
+ !defined(HAVE_COMPILER_ICX)
+
+ #define STRESS_ACCESS_ONCE(x) (*(__volatile__ __typeof__(x) *)&(x))
+--- a/stress-vnni.c
++++ b/stress-vnni.c
+@@ -25,6 +25,10 @@
+ #include "core-pragma.h"
+ #include "core-target-clones.h"
+
++#if defined(HAVE_COMPILER_MUSL)
++#undef HAVE_IMMINTRIN_H
++#endif
++
+ #if defined(HAVE_IMMINTRIN_H)
+ #include <immintrin.h>
+ #endif
+++ /dev/null
---- a/Makefile.config
-+++ b/Makefile.config
-@@ -309,10 +309,6 @@ clean:
- @rm -rf $(CONFIGS) config config.h
-
- compiler: configdir
-- @echo "checking compiler ..."
-- @$(CC) test/test-compiler.c -o test/test-compiler
-- @echo "" > $(CONFIGS)/$$(./test/test-compiler)
-- @rm -f test/test-compiler
- $(call check,test-glibc,HAVE_GLIBC,using glibc)
-
- .PHONY: libraries
--- /dev/null
+#!/bin/sh -e
+
+stress-ng --version | grep "$2"
PKG_NAME:=syncthing
PKG_VERSION:=1.24.0
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=syncthing-source-v$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/syncthing/syncthing/releases/download/v$(PKG_VERSION)
local option="$1"
local value="$2"
case $option in
- enabled|macprocs|nice|user|logfile)
+ enabled|gui_address|home|logfile|macprocs|nice|user)
eval $option=$value
;;
debug)
PKG_NAME:=tang
PKG_VERSION:=14
-PKG_RELEASE:=3
+PKG_RELEASE:=4
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://github.com/latchset/$(PKG_NAME)/releases/download/v$(PKG_VERSION)/
PKG_HASH:=04263ed1cc98d60cab29fe47f908921b7b1aa4d6da5f9de2fcbe543773b75886
-PKG_MAINTAINER:=Tibor Dudlák <tibor.dudlak@gmail.com>
+PKG_MAINTAINER:=Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
PKG_LICENSE:=GPL-3.0-or-later
PKG_LICENSE_FILES:=COPYING
if [ -z "${KEYS}" ] || [ "${KEYS}" = "0" ]; then # if db is empty generate new key pair
mkdir -p /usr/share/tang/db
/usr/sbin/tangd-keygen /usr/share/tang/db
+ chown -R tang /usr/share/tang/db
fi
config_load "tang"
include $(TOPDIR)/rules.mk
PKG_NAME:=tesseract
-PKG_VERSION:=4.1.1
-PKG_RELEASE:=3
+PKG_VERSION:=5.3.3
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/tesseract-ocr/tesseract/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=2a66ff0d8595bff8f04032165e6c936389b1e5727c3ce5a27b3e059d218db1cb
+PKG_HASH:=dc4329f85f41191b2d813b71b528ba6047745813474e583ccce8795ff2ff5681
PKG_MAINTAINER:=Valentin Kivachuk <vk18496@gmail.com>
PKG_LICENSE:=Apache-2.0
CMAKE_OPTIONS += \
-DAUTO_OPTIMIZE=OFF \
- -DBUILD_TRAINING_TOOLS=OFF
+ -DBUILD_SHARED_LIBS=ON \
+ -DBUILD_TRAINING_TOOLS=OFF \
+ -DDISABLE_CURL=ON
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(CP) $(PKG_INSTALL_DIR)/usr/include/tesseract $(1)/usr/include/
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtesseract.so* $(1)/usr/lib/
- $(INSTALL_DIR) $(1)/usr/lib/cmake
- $(CP) $(PKG_INSTALL_DIR)/usr/cmake/*.cmake $(1)/usr/lib/cmake/
+ $(INSTALL_DIR) $(1)/usr/lib/cmake/tesseract
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/cmake/tesseract/*.cmake $(1)/usr/lib/cmake/tesseract
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/tesseract.pc $(1)/usr/lib/pkgconfig/
endef
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -252,15 +252,6 @@ set(AVX2_OPT OFF)
- set(FMA_OPT OFF)
- set(SSE41_OPT OFF)
- set(MARCH_NATIVE_OPT OFF)
--foreach(flag ${_enable_vector_unit_list}) # from OptimizeForArchitecture()
-- string(TOUPPER "${flag}" flag)
-- string(REPLACE "\." "_" flag "${flag}")
-- set(simd_flags "${simd_flags} -D${flag}")
-- string(REPLACE "_" "" flag "${flag}")
-- if("${flag}" MATCHES "AVX|AVX2|FMA|SSE41")
-- set("${flag}_OPT" ON)
+--- a/cmake/CheckFunctions.cmake
++++ b/cmake/CheckFunctions.cmake
+@@ -29,24 +29,6 @@ function(check_leptonica_tiff_support)
+ " return ret_val;}\n")
+ if(${CMAKE_VERSION} VERSION_LESS "3.25")
+ message(STATUS "Testing TIFF support in Leptonica is available with CMake >= 3.25 (you have ${CMAKE_VERSION}))")
+- else()
+- set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
+- try_run(
+- LEPT_TIFF_RESULT
+- LEPT_TIFF_COMPILE_SUCCESS
+- SOURCE_FROM_CONTENT tiff_test.cpp "${TIFF_TEST}"
+- CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${Leptonica_INCLUDE_DIRS}"
+- LINK_LIBRARIES ${Leptonica_LIBRARIES}
+- COMPILE_OUTPUT_VARIABLE
+- COMPILE_OUTPUT)
+- if(NOT LEPT_TIFF_COMPILE_SUCCESS)
+- message(STATUS "COMPILE_OUTPUT: ${COMPILE_OUTPUT}")
+- message(STATUS "Leptonica_INCLUDE_DIRS: ${Leptonica_INCLUDE_DIRS}")
+- message(STATUS "Leptonica_LIBRARIES: ${Leptonica_LIBRARIES}")
+- message(STATUS "LEPT_TIFF_RESULT: ${LEPT_TIFF_RESULT}")
+- message(STATUS "LEPT_TIFF_COMPILE: ${LEPT_TIFF_COMPILE}")
+- message(WARNING "Failed to compile test")
- endif()
--endforeach(flag)
- if (NOT MSVC)
- set(MARCH_NATIVE_FLAGS "${MARCH_NATIVE_FLAGS} -O3 -ffast-math")
- endif()
+ endif()
+ endfunction(check_leptonica_tiff_support)
+
+++ /dev/null
---- a/src/ccutil/ocrclass.h
-+++ b/src/ccutil/ocrclass.h
-@@ -28,6 +28,7 @@
-
- #include <chrono>
- #include <ctime>
-+#include <sys/time.h>
- #ifdef _WIN32
- #include <winsock2.h> // for timeval
- #endif
include $(TOPDIR)/rules.mk
PKG_NAME:=yq
-PKG_VERSION:=4.35.2
+PKG_VERSION:=4.40.5
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/mikefarah/yq/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=8b17d710c56f764e9beff06d7a7b1c77d87c4ba4219ce4ce67e7ee29670f4f13
+PKG_HASH:=6ab08e0332697cf6a95383a38fd70c5162d00c0e28ea4b2311e9646b664aabe3
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
PKG_LICENSE:=MIT
PKG_NAME:=zsh
PKG_VERSION:=5.9
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@SF/zsh
PKG_LICENSE_FILES:=LICENCE
PKG_CPE_ID:=cpe:/a:zsh_project:zsh
+PKG_FIXUP:=autoreconf
PKG_BUILD_PARALLEL:=1
PKG_INSTALL:=1
PKG_BUILD_FLAGS:=gc-sections lto
+# zsh include custom macro in the default aclocal.m4
+# When autoreconf PKG_FIXUP is used, if PKG_REMOVE_FILES
+# is not defined, it's set to remove the file aclocak.m4
+# by default resulting in problem with the custom macro
+# AC_PROG_LN
+# To prevent this, declare empty PKG_REMOVE_FILES
+PKG_REMOVE_FILES:=
+
include $(INCLUDE_DIR)/package.mk
define Package/zsh
CATEGORY:=Utilities
SUBMENU:=Shells
TITLE:=The Z shell
- DEPENDS:=+libcap +libncurses +libncursesw +libpcre +librt
+ DEPENDS:=+libcap +libncurses +libncursesw +libpcre2 +librt
URL:=https://www.zsh.org/
endef
--- /dev/null
+From 1b421e4978440234fb73117c8505dad1ccc68d46 Mon Sep 17 00:00:00 2001
+From: Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
+Date: Mon, 26 Sep 2022 10:52:50 +0900
+Subject: [PATCH] 50658 + test: Enable to switch between C/UTF-8 locales in
+ PCRE
+
+---
+ ChangeLog | 5 +++++
+ Src/Modules/pcre.c | 10 ++--------
+ Test/V07pcre.ztst | 11 +++++++++++
+ 3 files changed, 18 insertions(+), 8 deletions(-)
+
+# diff --git a/ChangeLog b/ChangeLog
+# index 48c65d01b..77345c050 100644
+# --- a/ChangeLog
+# +++ b/ChangeLog
+# @@ -1,3 +1,8 @@
+# +2022-09-26 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
+# +
+# + * 50658 + test: Src/Modules/pcre.c, Test/V07pcre.ztst: Enable to
+# + switch between C/UTF-8 locales in PCRE
+# +
+# 2022-09-25 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+# * 50648: Functions/Misc/zcalc: Julian Prein: Use ZCALC_HISTFILE
+--- a/Src/Modules/pcre.c
++++ b/Src/Modules/pcre.c
+@@ -47,8 +47,6 @@ zpcre_utf8_enabled(void)
+ #if defined(MULTIBYTE_SUPPORT) && defined(HAVE_NL_LANGINFO) && defined(CODESET)
+ static int have_utf8_pcre = -1;
+
+- /* value can toggle based on MULTIBYTE, so don't
+- * be too eager with caching */
+ if (have_utf8_pcre < -1)
+ return 0;
+
+@@ -56,15 +54,11 @@ zpcre_utf8_enabled(void)
+ return 0;
+
+ if ((have_utf8_pcre == -1) &&
+- (!strcmp(nl_langinfo(CODESET), "UTF-8"))) {
+-
+- if (pcre_config(PCRE_CONFIG_UTF8, &have_utf8_pcre))
++ (pcre_config(PCRE_CONFIG_UTF8, &have_utf8_pcre))) {
+ have_utf8_pcre = -2; /* erk, failed to ask */
+ }
+
+- if (have_utf8_pcre < 0)
+- return 0;
+- return have_utf8_pcre;
++ return (have_utf8_pcre == 1) && (!strcmp(nl_langinfo(CODESET), "UTF-8"));
+
+ #else
+ return 0;
+--- a/Test/V07pcre.ztst
++++ b/Test/V07pcre.ztst
+@@ -174,3 +174,14 @@
+ echo $match[2] )
+ 0:regression for segmentation fault, workers/38307
+ >test
++
++ LANG_SAVE=$LANG
++ [[ é =~ '^.\z' ]]; echo $?
++ LANG=C
++ [[ é =~ '^..\z' ]]; echo $?
++ LANG=$LANG_SAVE
++ [[ é =~ '^.\z' ]]; echo $?
++0:swich between C/UTF-8 locales
++>0
++>0
++>0
--- /dev/null
+From b62e911341c8ec7446378b477c47da4256053dc0 Mon Sep 17 00:00:00 2001
+From: Oliver Kiddle <opk@zsh.org>
+Date: Sat, 13 May 2023 00:53:32 +0200
+Subject: [PATCH] 51723: migrate pcre module to pcre2
+
+---
+ ChangeLog | 3 +
+ Src/Modules/pcre.c | 223 ++++++++++++++++++---------------------------
+ Test/V07pcre.ztst | 13 ++-
+ configure.ac | 20 ++--
+ 4 files changed, 110 insertions(+), 149 deletions(-)
+
+# diff --git a/ChangeLog b/ChangeLog
+# index f5c77f801..285b73b2c 100644
+# --- a/ChangeLog
+# +++ b/ChangeLog
+# @@ -1,5 +1,8 @@
+# 2023-05-13 Oliver Kiddle <opk@zsh.org>
+
+# + * 51723: Src/Modules/pcre.c, Test/V07pcre.ztst, configure.ac:
+# + migrate pcre module to pcre2
+# +
+# * Felipe Contreras: 50612: Misc/vcs_info-examples: fix typo
+
+# * github #98: Vidhan Bhatt: Completion/Darwin/Command/_shortcuts:
+--- a/Src/Modules/pcre.c
++++ b/Src/Modules/pcre.c
+@@ -34,11 +34,11 @@
+ #define CPCRE_PLAIN 0
+
+ /**/
+-#if defined(HAVE_PCRE_COMPILE) && defined(HAVE_PCRE_EXEC)
+-#include <pcre.h>
++#if defined(HAVE_PCRE2_COMPILE_8) && defined(HAVE_PCRE2_H)
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+
+-static pcre *pcre_pattern;
+-static pcre_extra *pcre_hints;
++static pcre2_code *pcre_pattern;
+
+ /**/
+ static int
+@@ -54,8 +54,8 @@ zpcre_utf8_enabled(void)
+ return 0;
+
+ if ((have_utf8_pcre == -1) &&
+- (pcre_config(PCRE_CONFIG_UTF8, &have_utf8_pcre))) {
+- have_utf8_pcre = -2; /* erk, failed to ask */
++ (pcre2_config(PCRE2_CONFIG_UNICODE, &have_utf8_pcre))) {
++ have_utf8_pcre = -2; /* erk, failed to ask */
+ }
+
+ return (have_utf8_pcre == 1) && (!strcmp(nl_langinfo(CODESET), "UTF-8"));
+@@ -69,47 +69,38 @@ zpcre_utf8_enabled(void)
+ static int
+ bin_pcre_compile(char *nam, char **args, Options ops, UNUSED(int func))
+ {
+- int pcre_opts = 0, pcre_errptr, target_len;
+- const char *pcre_error;
++ uint32_t pcre_opts = 0;
++ int target_len;
++ int pcre_error;
++ PCRE2_SIZE pcre_offset;
+ char *target;
+
+- if(OPT_ISSET(ops,'a')) pcre_opts |= PCRE_ANCHORED;
+- if(OPT_ISSET(ops,'i')) pcre_opts |= PCRE_CASELESS;
+- if(OPT_ISSET(ops,'m')) pcre_opts |= PCRE_MULTILINE;
+- if(OPT_ISSET(ops,'x')) pcre_opts |= PCRE_EXTENDED;
+- if(OPT_ISSET(ops,'s')) pcre_opts |= PCRE_DOTALL;
++ if (OPT_ISSET(ops, 'a')) pcre_opts |= PCRE2_ANCHORED;
++ if (OPT_ISSET(ops, 'i')) pcre_opts |= PCRE2_CASELESS;
++ if (OPT_ISSET(ops, 'm')) pcre_opts |= PCRE2_MULTILINE;
++ if (OPT_ISSET(ops, 'x')) pcre_opts |= PCRE2_EXTENDED;
++ if (OPT_ISSET(ops, 's')) pcre_opts |= PCRE2_DOTALL;
+
+ if (zpcre_utf8_enabled())
+- pcre_opts |= PCRE_UTF8;
+-
+-#ifdef HAVE_PCRE_STUDY
+- if (pcre_hints)
+-#ifdef PCRE_CONFIG_JIT
+- pcre_free_study(pcre_hints);
+-#else
+- pcre_free(pcre_hints);
+-#endif
+- pcre_hints = NULL;
+-#endif
++ pcre_opts |= PCRE2_UTF;
+
+ if (pcre_pattern)
+- pcre_free(pcre_pattern);
++ pcre2_code_free(pcre_pattern);
+ pcre_pattern = NULL;
+
+ target = ztrdup(*args);
+ unmetafy(target, &target_len);
+
+- if ((int)strlen(target) != target_len) {
+- zwarnnam(nam, "embedded NULs in PCRE pattern terminate pattern");
+- }
+-
+- pcre_pattern = pcre_compile(target, pcre_opts, &pcre_error, &pcre_errptr, NULL);
++ pcre_pattern = pcre2_compile((PCRE2_SPTR) target, (PCRE2_SIZE) target_len,
++ pcre_opts, &pcre_error, &pcre_offset, NULL);
+
+ free(target);
+
+ if (pcre_pattern == NULL)
+ {
+- zwarnnam(nam, "error in regex: %s", pcre_error);
++ PCRE2_UCHAR buffer[256];
++ pcre2_get_error_message(pcre_error, buffer, sizeof(buffer));
++ zwarnnam(nam, "error in regex: %s", buffer);
+ return 1;
+ }
+
+@@ -117,67 +108,48 @@ bin_pcre_compile(char *nam, char **args,
+ }
+
+ /**/
+-#ifdef HAVE_PCRE_STUDY
+-
+-/**/
+ static int
+ bin_pcre_study(char *nam, UNUSED(char **args), UNUSED(Options ops), UNUSED(int func))
+ {
+- const char *pcre_error;
+-
+ if (pcre_pattern == NULL)
+ {
+ zwarnnam(nam, "no pattern has been compiled for study");
+ return 1;
+ }
+-
+- if (pcre_hints)
+-#ifdef PCRE_CONFIG_JIT
+- pcre_free_study(pcre_hints);
+-#else
+- pcre_free(pcre_hints);
+-#endif
+- pcre_hints = NULL;
+
+- pcre_hints = pcre_study(pcre_pattern, 0, &pcre_error);
+- if (pcre_error != NULL)
+- {
+- zwarnnam(nam, "error while studying regex: %s", pcre_error);
+- return 1;
++ int jit = 0;
++ if (!pcre2_config(PCRE2_CONFIG_JIT, &jit) && jit) {
++ if (pcre2_jit_compile(pcre_pattern, PCRE2_JIT_COMPLETE) < 0) {
++ zwarnnam(nam, "error while studying regex");
++ return 1;
++ }
+ }
+
+ return 0;
+ }
+
+-/**/
+-#else /* !HAVE_PCRE_STUDY */
+-
+-# define bin_pcre_study bin_notavail
+-
+-/**/
+-#endif /* !HAVE_PCRE_STUDY */
+-
+-/**/
+ static int
+-zpcre_get_substrings(char *arg, int *ovec, int captured_count, char *matchvar,
+- char *substravar, int want_offset_pair, int matchedinarr,
+- int want_begin_end)
++zpcre_get_substrings(char *arg, pcre2_match_data *mdata, int captured_count,
++ char *matchvar, char *substravar, int want_offset_pair,
++ int matchedinarr, int want_begin_end)
+ {
+- char **captures, *match_all, **matches;
++ PCRE2_SIZE *ovec;
++ char *match_all, **matches;
+ char offset_all[50];
+ int capture_start = 1;
+
+ if (matchedinarr) {
+- /* bash-style captures[0] entire-matched string in the array */
++ /* bash-style ovec[0] entire-matched string in the array */
+ capture_start = 0;
+ }
+
+- /* captures[0] will be entire matched string, [1] first substring */
+- if (!pcre_get_substring_list(arg, ovec, captured_count, (const char ***)&captures)) {
+- int nelem = arrlen(captures)-1;
++ /* ovec[0] will be entire matched string, [1] first substring */
++ ovec = pcre2_get_ovector_pointer(mdata);
++ if (ovec) {
++ int nelem = captured_count - 1;
+ /* Set to the offsets of the complete match */
+ if (want_offset_pair) {
+- sprintf(offset_all, "%d %d", ovec[0], ovec[1]);
++ sprintf(offset_all, "%ld %ld", ovec[0], ovec[1]);
+ setsparam("ZPCRE_OP", ztrdup(offset_all));
+ }
+ /*
+@@ -186,7 +158,7 @@ zpcre_get_substrings(char *arg, int *ove
+ * ovec is length 2*(1+capture_list_length)
+ */
+ if (matchvar) {
+- match_all = metafy(captures[0], ovec[1] - ovec[0], META_DUP);
++ match_all = metafy(arg + ovec[0], ovec[1] - ovec[0], META_DUP);
+ setsparam(matchvar, match_all);
+ }
+ /*
+@@ -201,16 +173,12 @@ zpcre_get_substrings(char *arg, int *ove
+ */
+ if (substravar &&
+ (!want_begin_end || nelem)) {
+- char **x, **y;
++ char **x;
+ int vec_off, i;
+- y = &captures[capture_start];
+ matches = x = (char **) zalloc(sizeof(char *) * (captured_count+1-capture_start));
+- for (i = capture_start; i < captured_count; i++, y++) {
++ for (i = capture_start; i < captured_count; i++) {
+ vec_off = 2*i;
+- if (*y)
+- *x++ = metafy(*y, ovec[vec_off+1]-ovec[vec_off], META_DUP);
+- else
+- *x++ = NULL;
++ *x++ = metafy(arg + ovec[vec_off], ovec[vec_off+1]-ovec[vec_off], META_DUP);
+ }
+ *x = NULL;
+ setaparam(substravar, matches);
+@@ -247,7 +215,8 @@ zpcre_get_substrings(char *arg, int *ove
+ setiparam("MEND", offs + !isset(KSHARRAYS) - 1);
+ if (nelem) {
+ char **mbegin, **mend, **bptr, **eptr;
+- int i, *ipair;
++ int i;
++ size_t *ipair;
+
+ bptr = mbegin = zalloc(sizeof(char*)*(nelem+1));
+ eptr = mend = zalloc(sizeof(char*)*(nelem+1));
+@@ -287,8 +256,6 @@ zpcre_get_substrings(char *arg, int *ove
+ setaparam("mend", mend);
+ }
+ }
+-
+- pcre_free_substring_list((const char **)captures);
+ }
+
+ return 0;
+@@ -314,7 +281,8 @@ getposint(char *instr, char *nam)
+ static int
+ bin_pcre_match(char *nam, char **args, Options ops, UNUSED(int func))
+ {
+- int ret, capcount, *ovec, ovecsize, c;
++ int ret, c;
++ pcre2_match_data *pcre_mdata = NULL;
+ char *matched_portion = NULL;
+ char *plaintext = NULL;
+ char *receptacle = NULL;
+@@ -344,36 +312,30 @@ bin_pcre_match(char *nam, char **args, O
+ /* For the entire match, 'Return' the offset byte positions instead of the matched string */
+ if(OPT_ISSET(ops,'b')) want_offset_pair = 1;
+
+- if ((ret = pcre_fullinfo(pcre_pattern, pcre_hints, PCRE_INFO_CAPTURECOUNT, &capcount)))
+- {
+- zwarnnam(nam, "error %d in fullinfo", ret);
+- return 1;
+- }
+-
+- ovecsize = (capcount+1)*3;
+- ovec = zalloc(ovecsize*sizeof(int));
+-
+ plaintext = ztrdup(*args);
+ unmetafy(plaintext, &subject_len);
+
+ if (offset_start > 0 && offset_start >= subject_len)
+- ret = PCRE_ERROR_NOMATCH;
+- else
+- ret = pcre_exec(pcre_pattern, pcre_hints, plaintext, subject_len, offset_start, 0, ovec, ovecsize);
++ ret = PCRE2_ERROR_NOMATCH;
++ else {
++ pcre_mdata = pcre2_match_data_create_from_pattern(pcre_pattern, NULL);
++ ret = pcre2_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len,
++ offset_start, 0, pcre_mdata, NULL);
++ }
+
+ if (ret==0) return_value = 0;
+- else if (ret==PCRE_ERROR_NOMATCH) /* no match */;
++ else if (ret == PCRE2_ERROR_NOMATCH) /* no match */;
+ else if (ret>0) {
+- zpcre_get_substrings(plaintext, ovec, ret, matched_portion, receptacle,
++ zpcre_get_substrings(plaintext, pcre_mdata, ret, matched_portion, receptacle,
+ want_offset_pair, 0, 0);
+ return_value = 0;
+ }
+ else {
+- zwarnnam(nam, "error in pcre_exec [%d]", ret);
++ zwarnnam(nam, "error in pcre2_match [%d]", ret);
+ }
+
+- if (ovec)
+- zfree(ovec, ovecsize*sizeof(int));
++ if (pcre_mdata)
++ pcre2_match_data_free(pcre_mdata);
+ zsfree(plaintext);
+
+ return return_value;
+@@ -383,17 +345,19 @@ bin_pcre_match(char *nam, char **args, O
+ static int
+ cond_pcre_match(char **a, int id)
+ {
+- pcre *pcre_pat;
+- const char *pcre_err;
++ pcre2_code *pcre_pat = NULL;
++ int pcre_err;
++ PCRE2_SIZE pcre_erroff;
+ char *lhstr, *rhre, *lhstr_plain, *rhre_plain, *avar, *svar;
+- int r = 0, pcre_opts = 0, pcre_errptr, capcnt, *ov, ovsize;
++ int r = 0, pcre_opts = 0;
++ pcre2_match_data *pcre_mdata = NULL;
+ int lhstr_plain_len, rhre_plain_len;
+ int return_value = 0;
+
+ if (zpcre_utf8_enabled())
+- pcre_opts |= PCRE_UTF8;
++ pcre_opts |= PCRE2_UTF;
+ if (isset(REMATCHPCRE) && !isset(CASEMATCH))
+- pcre_opts |= PCRE_CASELESS;
++ pcre_opts |= PCRE2_CASELESS;
+
+ lhstr = cond_str(a,0,0);
+ rhre = cond_str(a,1,0);
+@@ -401,9 +365,6 @@ cond_pcre_match(char **a, int id)
+ rhre_plain = ztrdup(rhre);
+ unmetafy(lhstr_plain, &lhstr_plain_len);
+ unmetafy(rhre_plain, &rhre_plain_len);
+- pcre_pat = NULL;
+- ov = NULL;
+- ovsize = 0;
+
+ if (isset(BASHREMATCH)) {
+ svar = NULL;
+@@ -415,27 +376,27 @@ cond_pcre_match(char **a, int id)
+
+ switch(id) {
+ case CPCRE_PLAIN:
+- if ((int)strlen(rhre_plain) != rhre_plain_len) {
+- zwarn("embedded NULs in PCRE pattern terminate pattern");
+- }
+- pcre_pat = pcre_compile(rhre_plain, pcre_opts, &pcre_err, &pcre_errptr, NULL);
+- if (pcre_pat == NULL) {
+- zwarn("failed to compile regexp /%s/: %s", rhre, pcre_err);
++ if (!(pcre_pat = pcre2_compile((PCRE2_SPTR) rhre_plain,
++ (PCRE2_SIZE) rhre_plain_len, pcre_opts,
++ &pcre_err, &pcre_erroff, NULL)))
++ {
++ PCRE2_UCHAR buffer[256];
++ pcre2_get_error_message(pcre_err, buffer, sizeof(buffer));
++ zwarn("failed to compile regexp /%s/: %s", rhre, buffer);
+ break;
+ }
+- pcre_fullinfo(pcre_pat, NULL, PCRE_INFO_CAPTURECOUNT, &capcnt);
+- ovsize = (capcnt+1)*3;
+- ov = zalloc(ovsize*sizeof(int));
+- r = pcre_exec(pcre_pat, NULL, lhstr_plain, lhstr_plain_len, 0, 0, ov, ovsize);
+- /* r < 0 => error; r==0 match but not enough size in ov
++ pcre_mdata = pcre2_match_data_create_from_pattern(pcre_pat, NULL);
++ r = pcre2_match(pcre_pat, (PCRE2_SPTR8) lhstr_plain, lhstr_plain_len,
++ 0, 0, pcre_mdata, NULL);
++ /* r < 0 => error; r==0 match but not enough size in match data
+ * r > 0 => (r-1) substrings found; r==1 => no substrings
+ */
+ if (r==0) {
+- zwarn("reportable zsh problem: pcre_exec() returned 0");
++ zwarn("reportable zsh problem: pcre2_match() returned 0");
+ return_value = 1;
+ break;
+ }
+- else if (r==PCRE_ERROR_NOMATCH) {
++ else if (r == PCRE2_ERROR_NOMATCH) {
+ return_value = 0; /* no match */
+ break;
+ }
+@@ -444,7 +405,7 @@ cond_pcre_match(char **a, int id)
+ break;
+ }
+ else if (r>0) {
+- zpcre_get_substrings(lhstr_plain, ov, r, svar, avar, 0,
++ zpcre_get_substrings(lhstr_plain, pcre_mdata, r, svar, avar, 0,
+ isset(BASHREMATCH),
+ !isset(BASHREMATCH));
+ return_value = 1;
+@@ -457,10 +418,10 @@ cond_pcre_match(char **a, int id)
+ free(lhstr_plain);
+ if(rhre_plain)
+ free(rhre_plain);
++ if (pcre_mdata)
++ pcre2_match_data_free(pcre_mdata);
+ if (pcre_pat)
+- pcre_free(pcre_pat);
+- if (ov)
+- zfree(ov, ovsize*sizeof(int));
++ pcre2_code_free(pcre_pat);
+
+ return return_value;
+ }
+@@ -489,11 +450,11 @@ static struct builtin bintab[] = {
+
+ static struct features module_features = {
+ bintab, sizeof(bintab)/sizeof(*bintab),
+-#if defined(HAVE_PCRE_COMPILE) && defined(HAVE_PCRE_EXEC)
++#if defined(HAVE_PCRE2_COMPILE_8) && defined(HAVE_PCRE2_H)
+ cotab, sizeof(cotab)/sizeof(*cotab),
+-#else /* !(HAVE_PCRE_COMPILE && HAVE_PCRE_EXEC) */
++#else /* !(HAVE_PCRE2_COMPILE_8 && HAVE_PCRE2_H) */
+ NULL, 0,
+-#endif /* !(HAVE_PCRE_COMPILE && HAVE_PCRE_EXEC) */
++#endif /* !(HAVE_PCRE2_COMPILE_8 && HAVE_PCRE2_H) */
+ NULL, 0,
+ NULL, 0,
+ 0
+@@ -540,19 +501,9 @@ cleanup_(Module m)
+ int
+ finish_(UNUSED(Module m))
+ {
+-#if defined(HAVE_PCRE_COMPILE) && defined(HAVE_PCRE_EXEC)
+-#ifdef HAVE_PCRE_STUDY
+- if (pcre_hints)
+-#ifdef PCRE_CONFIG_JIT
+- pcre_free_study(pcre_hints);
+-#else
+- pcre_free(pcre_hints);
+-#endif
+- pcre_hints = NULL;
+-#endif
+-
++#if defined(HAVE_PCRE2_COMPILE_8) && defined(HAVE_PCRE2_H)
+ if (pcre_pattern)
+- pcre_free(pcre_pattern);
++ pcre2_code_free(pcre_pattern);
+ pcre_pattern = NULL;
+ #endif
+
+--- a/Test/V07pcre.ztst
++++ b/Test/V07pcre.ztst
+@@ -129,12 +129,17 @@
+ >78884; ZPCRE_OP: 25 30
+ >90210; ZPCRE_OP: 31 36
+
+-# Embedded NULs allowed in plaintext, but not in RE (although \0 as two-chars allowed)
++# Embedded NULs allowed in plaintext, in RE, pcre supports \0 as two-chars
+ [[ $'a\0bc\0d' =~ '^(a\0.)(.+)$' ]]
+ print "${#MATCH}; ${#match[1]}; ${#match[2]}"
+ 0:ensure ASCII NUL passes in and out of matched plaintext
+ >6; 3; 3
+
++# PCRE2 supports NULs also in the RE
++ [[ $'a\0b\0c' =~ $'^(.\0)+' ]] && print "${#MATCH}; ${#match[1]}"
++0:ensure ASCII NUL works also in the regex
++>4; 2
++
+ # Ensure the long-form infix operator works
+ [[ foo -pcre-match ^f..$ ]]
+ print $?
+@@ -181,7 +186,11 @@
+ [[ é =~ '^..\z' ]]; echo $?
+ LANG=$LANG_SAVE
+ [[ é =~ '^.\z' ]]; echo $?
+-0:swich between C/UTF-8 locales
++0:switch between C/UTF-8 locales
+ >0
+ >0
+ >0
++
++ [[ abc =~ 'a(d*)bc' ]] && print "$#MATCH; $#match; ${#match[1]}"
++0:empty capture
++>3; 1; 0
+--- a/configure.ac
++++ b/configure.ac
+@@ -438,7 +438,7 @@ fi],
+
+ dnl Do you want to look for pcre support?
+ AC_ARG_ENABLE(pcre,
+-AS_HELP_STRING([--enable-pcre],[enable the search for the pcre library (may create run-time library dependencies)]))
++AS_HELP_STRING([--enable-pcre],[enable the search for the pcre2 library (may create run-time library dependencies)]))
+
+ dnl Do you want to look for capability support?
+ AC_ARG_ENABLE(cap,
+@@ -662,13 +662,12 @@ AC_HEADER_SYS_WAIT
+
+ oldcflags="$CFLAGS"
+ if test x$enable_pcre = xyes; then
+-AC_CHECK_PROG([PCRECONF], pcre-config, pcre-config)
+-dnl Typically (meaning on this single RedHat 9 box in front of me)
+-dnl pcre-config --cflags produces a -I output which needs to go into
++AC_CHECK_PROG([PCRECONF], pcre2-config, pcre2-config)
++dnl pcre2-config --cflags may produce a -I output which needs to go into
+ dnl CPPFLAGS else configure's preprocessor tests don't pick it up,
+ dnl producing a warning.
+-if test "x$ac_cv_prog_PCRECONF" = xpcre-config; then
+- CPPFLAGS="$CPPFLAGS `pcre-config --cflags`"
++if test "x$ac_cv_prog_PCRECONF" = xpcre2-config; then
++ CPPFLAGS="$CPPFLAGS `pcre2-config --cflags`"
+ fi
+ fi
+
+@@ -678,9 +677,10 @@ AC_CHECK_HEADERS(sys/time.h sys/times.h
+ locale.h errno.h stdio.h stdarg.h varargs.h stdlib.h \
+ unistd.h sys/capability.h \
+ utmp.h utmpx.h sys/types.h pwd.h grp.h poll.h sys/mman.h \
+- netinet/in_systm.h pcre.h langinfo.h wchar.h stddef.h \
++ netinet/in_systm.h langinfo.h wchar.h stddef.h \
+ sys/stropts.h iconv.h ncurses.h ncursesw/ncurses.h \
+ ncurses/ncurses.h)
++AC_CHECK_HEADERS([pcre2.h],,,[#define PCRE2_CODE_UNIT_WIDTH 8])
+ if test x$dynamic = xyes; then
+ AC_CHECK_HEADERS(dlfcn.h)
+ AC_CHECK_HEADERS(dl.h)
+@@ -958,9 +958,7 @@ if test "x$ac_found_iconv" = "xyes"; the
+ fi
+
+ if test x$enable_pcre = xyes; then
+-dnl pcre-config should probably be employed here
+-dnl AC_SEARCH_LIBS(pcre_compile, pcre)
+- LIBS="`$ac_cv_prog_PCRECONF --libs` $LIBS"
++ LIBS="`$ac_cv_prog_PCRECONF --libs8` $LIBS"
+ fi
+
+ dnl ---------------------
+@@ -1323,7 +1321,7 @@ AC_CHECK_FUNCS(strftime strptime mktime
+ pathconf sysconf \
+ tgetent tigetflag tigetnum tigetstr setupterm initscr resize_term \
+ getcchar setcchar waddwstr wget_wch win_wch use_default_colors \
+- pcre_compile pcre_study pcre_exec \
++ pcre2_compile_8 \
+ nl_langinfo \
+ erand48 open_memstream \
+ posix_openpt \
--- /dev/null
+From f3f371deb376478176866fd770fbcf9bc0d0609f Mon Sep 17 00:00:00 2001
+From: Oliver Kiddle <opk@zsh.org>
+Date: Sat, 13 May 2023 00:56:48 +0200
+Subject: [PATCH] 51728: assign pcre named capture groups to a hash
+
+---
+ ChangeLog | 3 +++
+ Doc/Zsh/mod_pcre.yo | 10 ++++++----
+ Src/Modules/pcre.c | 43 +++++++++++++++++++++++++++++++++----------
+ Test/V07pcre.ztst | 14 ++++++++++++++
+ 4 files changed, 56 insertions(+), 14 deletions(-)
+
+# diff --git a/ChangeLog b/ChangeLog
+# index 285b73b2c..2835a9405 100644
+# --- a/ChangeLog
+# +++ b/ChangeLog
+# @@ -1,5 +1,8 @@
+# 2023-05-13 Oliver Kiddle <opk@zsh.org>
+
+# + * 51728: Doc/Zsh/mod_pcre.yo, Src/Modules/pcre.c,
+# + Test/V07pcre.ztst: assign pcre named capture groups to a hash
+# +
+# * 51723: Src/Modules/pcre.c, Test/V07pcre.ztst, configure.ac:
+# migrate pcre module to pcre2
+
+--- a/Doc/Zsh/mod_pcre.yo
++++ b/Doc/Zsh/mod_pcre.yo
+@@ -20,12 +20,12 @@ including those that indicate newline.
+ )
+ findex(pcre_study)
+ item(tt(pcre_study))(
+-Studies the previously-compiled PCRE which may result in faster
+-matching.
++Requests JIT compilation for the previously-compiled PCRE which
++may result in faster matching.
+ )
+ findex(pcre_match)
+ item(tt(pcre_match) [ tt(-v) var(var) ] [ tt(-a) var(arr) ] \
+-[ tt(-n) var(offset) ] [ tt(-b) ] var(string))(
++[ tt(-A) var(assoc) ] [ tt(-n) var(offset) ] [ tt(-b) ] var(string))(
+ Returns successfully if tt(string) matches the previously-compiled
+ PCRE.
+
+@@ -36,7 +36,9 @@ substrings, unless the tt(-a) option is
+ case it will set the array var(arr). Similarly, the variable
+ tt(MATCH) will be set to the entire matched portion of the
+ string, unless the tt(-v) option is given, in which case the variable
+-var(var) will be set.
++var(var) will be set. Furthermore, any named captures will
++be stored in the associative array tt(.pcre.match) unless an
++alternative is given with tt(-A).
+ No variables are altered if there is no successful match.
+ A tt(-n) option starts searching for a match from the
+ byte var(offset) position in var(string). If the tt(-b) option is given,
+--- a/Src/Modules/pcre.c
++++ b/Src/Modules/pcre.c
+@@ -129,14 +129,17 @@ bin_pcre_study(char *nam, UNUSED(char **
+ }
+
+ static int
+-zpcre_get_substrings(char *arg, pcre2_match_data *mdata, int captured_count,
+- char *matchvar, char *substravar, int want_offset_pair,
+- int matchedinarr, int want_begin_end)
++zpcre_get_substrings(pcre2_code *pat, char *arg, pcre2_match_data *mdata,
++ int captured_count, char *matchvar, char *substravar, char *namedassoc,
++ int want_offset_pair, int matchedinarr, int want_begin_end)
+ {
+ PCRE2_SIZE *ovec;
+ char *match_all, **matches;
+ char offset_all[50];
+ int capture_start = 1;
++ int vec_off;
++ PCRE2_SPTR ntable; /* table of named captures */
++ uint32_t ncount, nsize;
+
+ if (matchedinarr) {
+ /* bash-style ovec[0] entire-matched string in the array */
+@@ -174,7 +177,7 @@ zpcre_get_substrings(char *arg, pcre2_ma
+ if (substravar &&
+ (!want_begin_end || nelem)) {
+ char **x;
+- int vec_off, i;
++ int i;
+ matches = x = (char **) zalloc(sizeof(char *) * (captured_count+1-capture_start));
+ for (i = capture_start; i < captured_count; i++) {
+ vec_off = 2*i;
+@@ -184,6 +187,23 @@ zpcre_get_substrings(char *arg, pcre2_ma
+ setaparam(substravar, matches);
+ }
+
++ if (!pcre2_pattern_info(pat, PCRE2_INFO_NAMECOUNT, &ncount) && ncount
++ && !pcre2_pattern_info(pat, PCRE2_INFO_NAMEENTRYSIZE, &nsize)
++ && !pcre2_pattern_info(pat, PCRE2_INFO_NAMETABLE, &ntable))
++ {
++ char **hash, **hashptr;
++ uint32_t nidx;
++ hashptr = hash = (char **)zshcalloc((ncount+1)*2*sizeof(char *));
++ for (nidx = 0; nidx < ncount; nidx++) {
++ vec_off = (ntable[nsize * nidx] << 9) + 2 * ntable[nsize * nidx + 1];
++ /* would metafy the key but pcre limits characters in the name */
++ *hashptr++ = ztrdup((char *) ntable + nsize * nidx + 2);
++ *hashptr++ = metafy(arg + ovec[vec_off],
++ ovec[vec_off+1]-ovec[vec_off], META_DUP);
++ }
++ sethparam(namedassoc, hash);
++ }
++
+ if (want_begin_end) {
+ /*
+ * cond-infix rather than builtin; also not bash; so we set a bunch
+@@ -286,6 +306,7 @@ bin_pcre_match(char *nam, char **args, O
+ char *matched_portion = NULL;
+ char *plaintext = NULL;
+ char *receptacle = NULL;
++ char *named = ".pcre.match";
+ int return_value = 1;
+ /* The subject length and offset start are both int values in pcre_exec */
+ int subject_len;
+@@ -305,6 +326,9 @@ bin_pcre_match(char *nam, char **args, O
+ if(OPT_HASARG(ops,c='v')) {
+ matched_portion = OPT_ARG(ops,c);
+ }
++ if (OPT_HASARG(ops, c='A')) {
++ named = OPT_ARG(ops, c);
++ }
+ if(OPT_HASARG(ops,c='n')) { /* The offset position to start the search, in bytes. */
+ if ((offset_start = getposint(OPT_ARG(ops,c), nam)) < 0)
+ return 1;
+@@ -326,8 +350,8 @@ bin_pcre_match(char *nam, char **args, O
+ if (ret==0) return_value = 0;
+ else if (ret == PCRE2_ERROR_NOMATCH) /* no match */;
+ else if (ret>0) {
+- zpcre_get_substrings(plaintext, pcre_mdata, ret, matched_portion, receptacle,
+- want_offset_pair, 0, 0);
++ zpcre_get_substrings(pcre_pattern, plaintext, pcre_mdata, ret, matched_portion,
++ receptacle, named, want_offset_pair, 0, 0);
+ return_value = 0;
+ }
+ else {
+@@ -405,9 +429,8 @@ cond_pcre_match(char **a, int id)
+ break;
+ }
+ else if (r>0) {
+- zpcre_get_substrings(lhstr_plain, pcre_mdata, r, svar, avar, 0,
+- isset(BASHREMATCH),
+- !isset(BASHREMATCH));
++ zpcre_get_substrings(pcre_pat, lhstr_plain, pcre_mdata, r, svar, avar,
++ ".pcre.match", 0, isset(BASHREMATCH), !isset(BASHREMATCH));
+ return_value = 1;
+ break;
+ }
+@@ -443,7 +466,7 @@ static struct conddef cotab[] = {
+
+ static struct builtin bintab[] = {
+ BUILTIN("pcre_compile", 0, bin_pcre_compile, 1, 1, 0, "aimxs", NULL),
+- BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "a:v:n:b", NULL),
++ BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "A:a:v:n:b", NULL),
+ BUILTIN("pcre_study", 0, bin_pcre_study, 0, 0, 0, NULL, NULL)
+ };
+
+--- a/Test/V07pcre.ztst
++++ b/Test/V07pcre.ztst
+@@ -194,3 +194,17 @@
+ [[ abc =~ 'a(d*)bc' ]] && print "$#MATCH; $#match; ${#match[1]}"
+ 0:empty capture
+ >3; 1; 0
++
++ [[ category/name-12345 =~ '(?x)^
++ (?<category> [^/]* ) /
++ (?<package>
++ (?<name> \w+ ) -
++ (?<version> \d+ ))$' ]]
++ typeset -p1 .pcre.match
++0:named captures
++>typeset -g -A .pcre.match=(
++> [category]=category
++> [name]=name
++> [package]=name-12345
++> [version]=12345
++>)
--- /dev/null
+From b4d1c756f50909b4a13e5c8fe5f26f71e9d54f63 Mon Sep 17 00:00:00 2001
+From: Oliver Kiddle <opk@zsh.org>
+Date: Sat, 13 May 2023 00:59:00 +0200
+Subject: [PATCH] 51738: support pcre's alternative DFA matching algorithm
+
+---
+ ChangeLog | 3 +++
+ Doc/Zsh/mod_pcre.yo | 6 ++++-
+ Src/Modules/pcre.c | 53 ++++++++++++++++++++++++++++++---------------
+ Test/V07pcre.ztst | 5 +++++
+ 4 files changed, 49 insertions(+), 18 deletions(-)
+
+# diff --git a/ChangeLog b/ChangeLog
+# index 2835a9405..18bc4a698 100644
+# --- a/ChangeLog
+# +++ b/ChangeLog
+# @@ -1,5 +1,8 @@
+# 2023-05-13 Oliver Kiddle <opk@zsh.org>
+
+# + * 51738: Doc/Zsh/mod_pcre.yo, Src/Modules/pcre.c,
+# + Test/V07pcre.ztst: support pcre's DFA matching algorithm
+# +
+# * 51728: Doc/Zsh/mod_pcre.yo, Src/Modules/pcre.c,
+# Test/V07pcre.ztst: assign pcre named capture groups to a hash
+
+--- a/Doc/Zsh/mod_pcre.yo
++++ b/Doc/Zsh/mod_pcre.yo
+@@ -25,7 +25,7 @@ may result in faster matching.
+ )
+ findex(pcre_match)
+ item(tt(pcre_match) [ tt(-v) var(var) ] [ tt(-a) var(arr) ] \
+-[ tt(-A) var(assoc) ] [ tt(-n) var(offset) ] [ tt(-b) ] var(string))(
++[ tt(-A) var(assoc) ] [ tt(-n) var(offset) ] [ tt(-bd) ] var(string))(
+ Returns successfully if tt(string) matches the previously-compiled
+ PCRE.
+
+@@ -69,6 +69,10 @@ print -l $accum)
+ )
+ enditem()
+
++The option tt(-d) uses the alternative breadth-first DFA search algorithm of
++pcre. This sets tt(match), or the array given with tt(-a), to all the matches
++found from the same start point in the subject.
++
+ The tt(zsh/pcre) module makes available the following test condition:
+
+ startitem()
+--- a/Src/Modules/pcre.c
++++ b/Src/Modules/pcre.c
+@@ -305,30 +305,29 @@ bin_pcre_match(char *nam, char **args, O
+ pcre2_match_data *pcre_mdata = NULL;
+ char *matched_portion = NULL;
+ char *plaintext = NULL;
+- char *receptacle = NULL;
+- char *named = ".pcre.match";
++ char *receptacle;
++ char *named = NULL;
+ int return_value = 1;
+ /* The subject length and offset start are both int values in pcre_exec */
+ int subject_len;
+ int offset_start = 0;
+ int want_offset_pair = 0;
++ int use_dfa = 0;
+
+ if (pcre_pattern == NULL) {
+ zwarnnam(nam, "no pattern has been compiled");
+ return 1;
+ }
+
+- matched_portion = "MATCH";
+- receptacle = "match";
+- if(OPT_HASARG(ops,c='a')) {
+- receptacle = OPT_ARG(ops,c);
+- }
+- if(OPT_HASARG(ops,c='v')) {
+- matched_portion = OPT_ARG(ops,c);
+- }
+- if (OPT_HASARG(ops, c='A')) {
+- named = OPT_ARG(ops, c);
++ if (!(use_dfa = OPT_ISSET(ops, 'd'))) {
++ matched_portion = OPT_HASARG(ops, c='v') ? OPT_ARG(ops, c) : "MATCH";
++ named = OPT_HASARG(ops, c='A') ? OPT_ARG(ops, c) : ".pcre.match";
++ } else if (OPT_HASARG(ops, c='v') || OPT_HASARG(ops, c='A')) {
++ zwarnnam(nam, "-d cannot be combined with -%c", c);
++ return 1;
+ }
++ receptacle = OPT_HASARG(ops, 'a') ? OPT_ARG(ops, 'a') : "match";
++
+ if(OPT_HASARG(ops,c='n')) { /* The offset position to start the search, in bytes. */
+ if ((offset_start = getposint(OPT_ARG(ops,c), nam)) < 0)
+ return 1;
+@@ -341,7 +340,25 @@ bin_pcre_match(char *nam, char **args, O
+
+ if (offset_start > 0 && offset_start >= subject_len)
+ ret = PCRE2_ERROR_NOMATCH;
+- else {
++ else if (use_dfa) {
++ PCRE2_SIZE old, wscount = 128, capcount = 128;
++ void *workspace = zhalloc(sizeof(int) * wscount);
++ pcre_mdata = pcre2_match_data_create(capcount, NULL);
++ do {
++ ret = pcre2_dfa_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len,
++ offset_start, 0, pcre_mdata, NULL, (int *) workspace, wscount);
++ if (ret == PCRE2_ERROR_DFA_WSSIZE) {
++ old = wscount;
++ wscount += wscount / 2;
++ workspace = hrealloc(workspace, sizeof(int) * old, sizeof(int) * wscount);
++ } else if (ret == 0) {
++ capcount += capcount / 2;
++ pcre2_match_data_free(pcre_mdata);
++ pcre_mdata = pcre2_match_data_create(capcount, NULL);
++ } else
++ break;
++ } while(1);
++ } else {
+ pcre_mdata = pcre2_match_data_create_from_pattern(pcre_pattern, NULL);
+ ret = pcre2_match(pcre_pattern, (PCRE2_SPTR) plaintext, subject_len,
+ offset_start, 0, pcre_mdata, NULL);
+@@ -350,12 +367,14 @@ bin_pcre_match(char *nam, char **args, O
+ if (ret==0) return_value = 0;
+ else if (ret == PCRE2_ERROR_NOMATCH) /* no match */;
+ else if (ret>0) {
+- zpcre_get_substrings(pcre_pattern, plaintext, pcre_mdata, ret, matched_portion,
+- receptacle, named, want_offset_pair, 0, 0);
++ zpcre_get_substrings(pcre_pattern, plaintext, pcre_mdata, ret,
++ matched_portion, receptacle, named, want_offset_pair, use_dfa, 0);
+ return_value = 0;
+ }
+ else {
+- zwarnnam(nam, "error in pcre2_match [%d]", ret);
++ PCRE2_UCHAR buffer[256];
++ pcre2_get_error_message(ret, buffer, sizeof(buffer));
++ zwarnnam(nam, "error in pcre matching for /%s/: %s", plaintext, buffer);
+ }
+
+ if (pcre_mdata)
+@@ -466,7 +485,7 @@ static struct conddef cotab[] = {
+
+ static struct builtin bintab[] = {
+ BUILTIN("pcre_compile", 0, bin_pcre_compile, 1, 1, 0, "aimxs", NULL),
+- BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "A:a:v:n:b", NULL),
++ BUILTIN("pcre_match", 0, bin_pcre_match, 1, 1, 0, "A:a:v:n:bd", NULL),
+ BUILTIN("pcre_study", 0, bin_pcre_study, 0, 0, 0, NULL, NULL)
+ };
+
+--- a/Test/V07pcre.ztst
++++ b/Test/V07pcre.ztst
+@@ -208,3 +208,8 @@
+ > [package]=name-12345
+ > [version]=12345
+ >)
++
++ pcre_compile 'cat(er(pillar)?)?'
++ pcre_match -d 'the caterpillar catchment' && print $match
++0:pcre_match -d
++>caterpillar cater cat
--- /dev/null
+From 10bdbd8b5b0b43445aff23dcd412f25cf6aa328a Mon Sep 17 00:00:00 2001
+From: Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
+Date: Tue, 20 Jun 2023 18:14:27 +0900
+Subject: [PATCH] 51877: do not build pcre module if pcre2-config is not found
+
+---
+ ChangeLog | 5 +++++
+ Src/Modules/pcre.mdd | 2 +-
+ configure.ac | 31 +++++++++++++++++++------------
+ 3 files changed, 25 insertions(+), 13 deletions(-)
+
+# diff --git a/ChangeLog b/ChangeLog
+# index 14349dcf2..e89ffee1b 100644
+# --- a/ChangeLog
+# +++ b/ChangeLog
+# @@ -1,3 +1,8 @@
+# +2023-06-20 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
+# +
+# + * 51877: Src/Modules/pcre.mdd, configure.ac: do not build pcre
+# + module if pcre2-config is not available.
+# +
+# 2023-06-19 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
+
+# * 51862: Doc/Makefile.in, configure.ac: support texinfo-7.0
+--- a/Src/Modules/pcre.mdd
++++ b/Src/Modules/pcre.mdd
+@@ -1,5 +1,5 @@
+ name=zsh/pcre
+-link=`if test x$enable_pcre = xyes && (pcre-config --version >/dev/null 2>/dev/null); then echo dynamic; else echo no; fi`
++link=`if test x$enable_pcre = xyes; then echo dynamic; else echo no; fi`
+ load=no
+
+ autofeatures="b:pcre_compile b:pcre_study b:pcre_match"
+--- a/configure.ac
++++ b/configure.ac
+@@ -440,6 +440,17 @@ dnl Do you want to look for pcre support
+ AC_ARG_ENABLE(pcre,
+ AS_HELP_STRING([--enable-pcre],[enable the search for the pcre2 library (may create run-time library dependencies)]))
+
++AC_ARG_VAR(PCRE_CONFIG, [pathname of pcre2-config if it is not in PATH])
++if test "x$enable_pcre" = xyes; then
++ AC_CHECK_PROG([PCRE_CONFIG], pcre2-config, pcre2-config)
++ if test "x$PCRE_CONFIG" = x; then
++ enable_pcre=no
++ AC_MSG_WARN([pcre2-config not found: pcre module is disabled.])
++ AC_MSG_NOTICE(
++ [Set PCRE_CONFIG to pathname of pcre2-config if it is not in PATH.])
++ fi
++fi
++
+ dnl Do you want to look for capability support?
+ AC_ARG_ENABLE(cap,
+ AS_HELP_STRING([--enable-cap],[enable the search for POSIX capabilities (may require additional headers to be added by hand)]))
+@@ -660,15 +671,12 @@ AC_HEADER_DIRENT
+ AC_HEADER_STAT
+ AC_HEADER_SYS_WAIT
+
+-oldcflags="$CFLAGS"
+-if test x$enable_pcre = xyes; then
+-AC_CHECK_PROG([PCRECONF], pcre2-config, pcre2-config)
+ dnl pcre2-config --cflags may produce a -I output which needs to go into
+ dnl CPPFLAGS else configure's preprocessor tests don't pick it up,
+ dnl producing a warning.
+-if test "x$ac_cv_prog_PCRECONF" = xpcre2-config; then
+- CPPFLAGS="$CPPFLAGS `pcre2-config --cflags`"
+-fi
++if test "x$enable_pcre" = xyes; then
++ CPPFLAGS="`$PCRE_CONFIG --cflags` $CPPFLAGS"
++ AC_CHECK_HEADERS([pcre2.h],,,[#define PCRE2_CODE_UNIT_WIDTH 8])
+ fi
+
+ AC_CHECK_HEADERS(sys/time.h sys/times.h sys/select.h termcap.h termio.h \
+@@ -680,7 +688,6 @@ AC_CHECK_HEADERS(sys/time.h sys/times.h
+ netinet/in_systm.h langinfo.h wchar.h stddef.h \
+ sys/stropts.h iconv.h ncurses.h ncursesw/ncurses.h \
+ ncurses/ncurses.h)
+-AC_CHECK_HEADERS([pcre2.h],,,[#define PCRE2_CODE_UNIT_WIDTH 8])
+ if test x$dynamic = xyes; then
+ AC_CHECK_HEADERS(dlfcn.h)
+ AC_CHECK_HEADERS(dl.h)
+@@ -957,10 +964,6 @@ if test "x$ac_found_iconv" = "xyes"; the
+ [Define as const if the declaration of iconv() needs const.])
+ fi
+
+-if test x$enable_pcre = xyes; then
+- LIBS="`$ac_cv_prog_PCRECONF --libs8` $LIBS"
+-fi
+-
+ dnl ---------------------
+ dnl CHECK TERMCAP LIBRARY
+ dnl ---------------------
+@@ -1321,7 +1324,6 @@ AC_CHECK_FUNCS(strftime strptime mktime
+ pathconf sysconf \
+ tgetent tigetflag tigetnum tigetstr setupterm initscr resize_term \
+ getcchar setcchar waddwstr wget_wch win_wch use_default_colors \
+- pcre2_compile_8 \
+ nl_langinfo \
+ erand48 open_memstream \
+ posix_openpt \
+@@ -1376,6 +1378,11 @@ if test x$zsh_cv_func_realpath_accepts_n
+ AC_DEFINE(REALPATH_ACCEPTS_NULL)
+ fi
+
++if test x$enable_pcre = xyes; then
++ LIBS="`$PCRE_CONFIG --libs8` $LIBS"
++ AC_CHECK_FUNCS(pcre2_compile_8)
++fi
++
+ if test x$enable_cap = xyes; then
+ AC_CHECK_FUNCS(cap_get_proc)
+ fi