Merge pull request #22354 from lvoegl/pr/20230910-swanmon
authorFlorian Eckert <fe@dev.tdt.de>
Thu, 14 Dec 2023 11:26:38 +0000 (12:26 +0100)
committerGitHub <noreply@github.com>
Thu, 14 Dec 2023 11:26:38 +0000 (12:26 +0100)
swanmon: add package

566 files changed:
.github/workflows/entrypoint.sh
.github/workflows/formal.yml
.github/workflows/multi-arch-test-build.yml
CONTRIBUTING.md
admin/bottom/Makefile
admin/zabbix/Makefile
admin/zabbix/patches/110-reproducible-builds.patch
lang/golang/golang/Makefile
lang/lua-eco/Makefile
lang/luajit2/Makefile
lang/luajit2/patches/010-lua-path.patch
lang/maturin/Makefile [deleted file]
lang/node/Makefile
lang/node/patches/003-path.patch
lang/node/patches/004-musl_support.patch
lang/node/patches/200-uv_gyp.patch [new file with mode: 0644]
lang/node/patches/201-zlib_gyp.patch [new file with mode: 0644]
lang/node/patches/202-node_gyp.patch [new file with mode: 0644]
lang/node/patches/203-icu-generic_gyp.patch [new file with mode: 0644]
lang/node/patches/204-v8_gyp.patch [new file with mode: 0644]
lang/node/patches/990-delete_unnecessary_libraries_for_host_execute.patch [deleted file]
lang/node/patches/991-v8_zlib_support.patch [deleted file]
lang/node/patches/992-v8_add_include_dirs.patch [deleted file]
lang/node/patches/999-cast_for_mips32.patch [deleted file]
lang/node/patches/999-fix_icu_conflict.patch [deleted file]
lang/node/patches/999-localhost-no-addrconfig.patch
lang/node/patches/999-revert_enable_pointer_authentication_on_arm64.patch
lang/perl-text-csv_xs/Makefile
lang/perl/Makefile
lang/perl/files/base.config
lang/perl/files/libc.config
lang/perl/files/riscv64.config [new file with mode: 0644]
lang/perl/files/version.config
lang/perl/patches/001-macos_11_support.patch [deleted file]
lang/perl/patches/002-add-Internals-getcwd.patch [deleted file]
lang/perl/patches/003-fallback-to-the-built-in-getcwd-if-we-ca.patch [deleted file]
lang/perl/patches/010-musl-compat.patch
lang/perl/patches/020-storables-stacksize.patch [deleted file]
lang/perl/patches/110-always_use_miniperl.patch
lang/perl/patches/120-remove-build-timestamp.patch
lang/perl/patches/301-fix_macos_static_linking.patch [deleted file]
lang/perl/patches/320-copy-pod-hack.patch
lang/perl/patches/900-use-rm-force.patch
lang/perl/patches/910-miniperl-needs-inc-dot.patch
lang/perl/patches/920-fix-no-locale.patch [deleted file]
lang/perl/patches/998-Errno_errno.h_path.patch
lang/perl/patches/999-fix-build-failure-against-gcc-10.patch [deleted file]
lang/perl/patches/999-fixup-regex-engine-build-under-Uusedl.patch [new file with mode: 0644]
lang/perl/perlbase.mk
lang/perl/perlver.mk
lang/php8-pecl-http/Makefile
lang/php8-pecl-redis/Makefile
lang/php8-pecl-xdebug/Makefile
lang/php8/Makefile
lang/python/micropython-lib/Makefile
lang/python/micropython-mpremote/Makefile [deleted file]
lang/python/micropython-mpremote/patches/001-no-importlib_metadata.patch [deleted file]
lang/python/micropython/Makefile
lang/python/micropython/patches/030-target-no-darwin.patch
lang/python/micropython/patches/040-extmod-use-external-mbedtls.patch
lang/python/micropython/patches/050-py-stackctrl-fix-gcc-13.patch [deleted file]
lang/python/micropython/src/ports/unix/variants/standard/manifest-nossl.py
lang/python/micropython/test.sh [new file with mode: 0644]
lang/python/pillow/Makefile
lang/python/pillow/patches/001-remove-setuptools-version-limit.patch
lang/python/pillow/test.sh [new file with mode: 0644]
lang/python/pipx/Makefile [new file with mode: 0644]
lang/python/pipx/test.sh [new file with mode: 0644]
lang/python/pyodbc/Makefile [deleted file]
lang/python/python-argcomplete/Makefile [new file with mode: 0644]
lang/python/python-argcomplete/patches/001-unpin-setuptools.patch [new file with mode: 0644]
lang/python/python-argcomplete/test.sh [new file with mode: 0644]
lang/python/python-bcrypt/Makefile
lang/python/python-bcrypt/test.sh
lang/python/python-charset-normalizer/Makefile
lang/python/python-charset-normalizer/test.sh
lang/python/python-constantly/Makefile
lang/python/python-constantly/patches/001-unpin-setuptools.patch [new file with mode: 0644]
lang/python/python-constantly/test.sh [new file with mode: 0644]
lang/python/python-cryptography/Makefile
lang/python/python-cryptography/test.sh
lang/python/python-fnv-hash-fast/Makefile [new file with mode: 0644]
lang/python/python-fnvhash/Makefile [new file with mode: 0644]
lang/python/python-hatch-vcs/Makefile
lang/python/python-idna/Makefile
lang/python/python-idna/test.sh [new file with mode: 0644]
lang/python/python-jsonschema-specifications/Makefile [new file with mode: 0644]
lang/python/python-jsonschema-specifications/test.sh [new file with mode: 0644]
lang/python/python-jsonschema/Makefile
lang/python/python-jsonschema/test.sh [new file with mode: 0644]
lang/python/python-lru-dict/Makefile [new file with mode: 0644]
lang/python/python-mako/Makefile
lang/python/python-maturin/Makefile [new file with mode: 0644]
lang/python/python-orjson/Makefile [new file with mode: 0644]
lang/python/python-pathspec/Makefile
lang/python/python-pip/Makefile
lang/python/python-pip/patches/001-pyproject-hooks-pyc-fix.patch
lang/python/python-pip/patches/002-pip-runner-pyc-fix.patch
lang/python/python-pip/patches/003-disable-pip-version-check.patch
lang/python/python-platformdirs/Makefile [new file with mode: 0644]
lang/python/python-platformdirs/test.sh [new file with mode: 0644]
lang/python/python-poetry-core/Makefile
lang/python/python-pyasn1/Makefile
lang/python/python-pyasn1/test.sh [new file with mode: 0644]
lang/python/python-pycares/Makefile
lang/python/python-pyodbc/Makefile [new file with mode: 0644]
lang/python/python-pyodbc/test.sh [new file with mode: 0644]
lang/python/python-pyopenssl/Makefile
lang/python/python-referencing/Makefile [new file with mode: 0644]
lang/python/python-referencing/test.sh [new file with mode: 0644]
lang/python/python-rpds-py/Makefile [new file with mode: 0644]
lang/python/python-rpds-py/test.sh [new file with mode: 0644]
lang/python/python-setuptools-rust/Makefile
lang/python/python-setuptools/Makefile
lang/python/python-texttable/Makefile
lang/python/python-trove-classifiers/Makefile
lang/python/python-twisted/Makefile
lang/python/python-twisted/patches/001-omit-tkconch.patch
lang/python/python-twisted/patches/002-omit-tests.patch
lang/python/python-typing-extensions/Makefile
lang/python/python-userpath/Makefile [new file with mode: 0644]
lang/python/python-userpath/patches/0001-Handle-OSErrors-when-running-show-path-commands.patch [new file with mode: 0644]
lang/python/python-userpath/patches/0001-Use-Sh-as-base-class-for-Bash-and-Zsh.patch [new file with mode: 0644]
lang/python/python-userpath/patches/0002-Add-support-for-ash-Almquist-shell.patch [new file with mode: 0644]
lang/python/python-userpath/test.sh [new file with mode: 0644]
lang/python/python-versioneer/Makefile [new file with mode: 0644]
lang/python/python-websocket-client/Makefile
lang/python/python-wheel/Makefile
lang/python/python-zope-interface/Makefile
lang/python/python-zope-interface/patches/001-omit-tests.patch
lang/python/python-zope-interface/test.sh [new file with mode: 0644]
lang/python/python3-host.mk
lang/python/python3-package.mk
lang/python/python3-version.mk
lang/python/python3/Makefile
lang/python/python3/patches-host-setuptools/0001-Adjust-library-header-paths-for-cross-compilation.patch [new file with mode: 0644]
lang/python/python3/patches/003-do-not-run-compileall.patch
lang/python/python3/patches/025-choose-python-config-version.patch
lang/python/python3/patches/100-gh-95855-Refactor-platform-triplet-detection-code-GH-107221.patch
lang/rust/Config.in [new file with mode: 0644]
lang/rust/Makefile
lang/rust/files/cargo-config [deleted file]
lang/rust/patches/0001-Update-xz2-and-use-it-static.patch
lang/rust/patches/0002-rustc-bootstrap-cache.patch [new file with mode: 0644]
lang/rust/patches/0003-bump-libc-deps-to-0.2.146.patch [new file with mode: 0644]
lang/rust/rust-host-build.mk
lang/rust/rust-package.mk
lang/rust/rust-values.mk
libs/avahi/Makefile
libs/cyrus-sasl/Makefile
libs/efivar/Makefile
libs/efivar/patches/006-build-util-c-separately-for-makeguids.patch [new file with mode: 0644]
libs/elektra/Makefile
libs/elektra/patches/010-gcc13.patch [new file with mode: 0644]
libs/h2o/Makefile
libs/h2o/patches/900-cve-2023-44487.patch [new file with mode: 0644]
libs/h2o/patches/901-bump-soname.patch [new file with mode: 0644]
libs/icu/Makefile
libs/libdaq3/Makefile
libs/libmbim/Makefile
libs/libndpi/Makefile
libs/libndpi/patches/001-Move-from-PCRE-to-PCRE2.patch [new file with mode: 0644]
libs/libnpupnp/Makefile
libs/libqmi/Makefile
libs/libsocketcan/Makefile [new file with mode: 0644]
libs/libupnpp/Makefile
libs/liburing/Makefile
libs/libxslt/Makefile
libs/libzip/Makefile
libs/libzip/patches/010-nossl.patch [deleted file]
libs/newt/Makefile
libs/newt/test.sh [new file with mode: 0644]
libs/nghttp2/Makefile
libs/nghttp3/Makefile [new file with mode: 0644]
libs/ngtcp2/Makefile [new file with mode: 0644]
libs/openblas/Makefile
libs/psqlodbc/Makefile
libs/quasselc/Makefile [deleted file]
libs/quasselc/patches/001-respect-cflags-ldflags.patch [deleted file]
libs/unixodbc/Makefile
libs/unixodbc/files/pgsqlodbc.ini [new file with mode: 0644]
libs/unixodbc/files/unixodbc_conf.h [deleted file]
libs/unixodbc/patches/100-cross-compile-odbc-config.patch [deleted file]
libs/unixodbc/test.sh [new file with mode: 0644]
libs/xmlrpc-c/Makefile
libs/xmlrpc-c/patches/001-fix-format-parameter.patch [new file with mode: 0644]
libs/xmlrpc-c/patches/002-remove-unnecessary-linking.patch [new file with mode: 0644]
mail/exim/Makefile
mail/exim/patches/100-localscan_dlopen.patch
mail/fdm/Makefile
mail/fdm/patches/010-ntop-fix.patch [deleted file]
mail/fdm/patches/020-Fix-compile-with-OpenSSL-1.1.0.patch [deleted file]
mail/fdm/patches/030-cdefs.patch [deleted file]
mail/fdm/patches/100-Fix-bugs-in-PCRE2-code-don-t-walk-off-the-end-of-the.patch [new file with mode: 0644]
mail/fdm/patches/101-Fix-use-after-free-GitHub-issue-126.patch [new file with mode: 0644]
mail/postfix/Makefile
mail/postfix/patches/100-correct-signature-of-closefrom-API.patch
mail/postfix/patches/300-bdb_hash_segfault.patch
mail/postfix/patches/400-cdb.patch
mail/postfix/patches/500-crosscompile.patch
mail/postfix/patches/501-include_stdio.patch
mail/postfix/patches/502-detect-glibc.patch [deleted file]
mail/postfix/patches/700-defaultconfig.patch
multimedia/gst1-libav/Makefile
multimedia/gst1-plugins-bad/Makefile
multimedia/gst1-plugins-bad/patches/010-distutils.patch
multimedia/gst1-plugins-base/Makefile
multimedia/gst1-plugins-good/Makefile
multimedia/gst1-plugins-good/patches/010-distutils.patch
multimedia/gst1-plugins-ugly/Makefile
multimedia/gstreamer1/Makefile
multimedia/tvheadend/Config.in
multimedia/tvheadend/Makefile
multimedia/yt-dlp/Makefile
net/aardvark-dns/Makefile
net/acme-acmesh/Makefile
net/adblock-fast/Makefile
net/adblock-fast/files/etc/config/adblock-fast
net/adblock-fast/files/etc/init.d/adblock-fast
net/adblock-fast/files/etc/uci-defaults/90-adblock-fast
net/adguardhome/Makefile
net/adguardhome/patches/0001-go-get-github.com-quic-go-quic-go-v0.37.6.patch [deleted file]
net/aircrack-ng/Makefile
net/aircrack-ng/patches/104-build-add-option-to-disable-bsd-library-inclusion.patch [new file with mode: 0644]
net/aircrack-ng/patches/105-build-support-strlcat-strlcpy-from-musl-or-recent-gl.patch [new file with mode: 0644]
net/apinger/Makefile
net/apinger/files/apinger.init
net/apinger/files/apinger.rpc
net/aria2/Makefile
net/ariang/Makefile
net/banip/Makefile
net/banip/files/README.md
net/banip/files/banip-functions.sh
net/banip/files/banip.cgi [new file with mode: 0644]
net/banip/files/banip.conf
net/banip/files/banip.feeds
net/banip/files/banip.init
net/cloudreve/Makefile
net/cni-protocol/Makefile [deleted file]
net/cni-protocol/files/cni.sh [deleted file]
net/conntrack-tools/Makefile
net/croc/Makefile
net/crowdsec-firewall-bouncer/Makefile
net/crowdsec-firewall-bouncer/files/crowdsec-firewall-bouncer.initd
net/crowdsec/Makefile
net/curl/Config.in
net/curl/Makefile
net/curl/patches/200-no_docs_tests.patch
net/ddns-scripts/Makefile
net/ddns-scripts/files/usr/lib/ddns/update_route53_v1.sh
net/ddns-scripts/files/usr/share/ddns/default/ipnodns.ru.json [new file with mode: 0644]
net/ddns-scripts/files/usr/share/ddns/list
net/dhtd/Makefile [new file with mode: 0644]
net/dhtd/files/dhtd.config [new file with mode: 0644]
net/dhtd/files/dhtd.init [new file with mode: 0755]
net/dnsdist/Makefile
net/dnsproxy/Makefile
net/dnsproxy/files/dnsproxy.config
net/dnsproxy/files/dnsproxy.defaults [new file with mode: 0644]
net/dnsproxy/files/dnsproxy.init
net/external-protocol/Makefile [new file with mode: 0644]
net/external-protocol/files/external.sh [new file with mode: 0755]
net/fail2ban/Makefile
net/fail2ban/patches/101-move-global-groups-to-start-of-expression-python-3.11-compat.patch [new file with mode: 0644]
net/fail2ban/patches/102-wrap-global-flags-to-local-flags-if-supported-by-RE-engine-in-the-python-version.patch [new file with mode: 0644]
net/freeradius3/Makefile
net/freeradius3/patches/020-fix-freeradius3-krb5.patch [new file with mode: 0644]
net/gensio/Makefile
net/gensio/patches/0001-Ensure-that-ax_python_devel_found-is-defined.patch [new file with mode: 0644]
net/gensio/patches/0002_ax_python_devel-fix-serial.patch [new file with mode: 0644]
net/gensio/patches/0003-Revert-ax_pkg_swig.m4-to-latest-vanilla-version.patch [new file with mode: 0644]
net/gensio/patches/100-musl-compat.patch [deleted file]
net/haproxy/Makefile
net/haproxy/get-latest-patches.sh
net/hcxdumptool/Makefile
net/hcxdumptool/patches/010-openssl.patch [deleted file]
net/hcxtools/Makefile
net/hcxtools/patches/010-openssl.patch [deleted file]
net/https-dns-proxy/Makefile
net/https-dns-proxy/files/etc/hotplug.d/iface/90-https-dns-proxy [deleted file]
net/https-dns-proxy/files/etc/init.d/https-dns-proxy
net/https-dns-proxy/patches/010-cmakelists-remove-cflags.patch
net/https-dns-proxy/patches/020-src-options.c-add-version.patch
net/iperf3/Makefile
net/isc-dhcp/Makefile
net/isc-dhcp/files/dhcpd.init
net/keepalived/Makefile
net/keepalived/files/keepalived.init
net/knot/Makefile
net/knot/patches/03_libdnssec_pkcs11_support.patch [new file with mode: 0644]
net/librespeed-go/Makefile
net/librespeed-go/files/librespeed-go.init
net/libreswan/Makefile
net/libreswan/files/etc/config/libreswan [new file with mode: 0644]
net/libreswan/files/etc/hotplug.d/iface/89-libreswan [new file with mode: 0644]
net/libreswan/files/etc/hotplug.d/libreswan/00-default [new file with mode: 0644]
net/libreswan/files/etc/hotplug.d/libreswan/01-user [new file with mode: 0644]
net/libreswan/files/etc/hotplug.d/libreswan/02-vti [new file with mode: 0644]
net/libreswan/files/etc/hotplug.d/libreswan/61-iptables [new file with mode: 0644]
net/libreswan/files/etc/hotplug.d/libreswan/62-nftables [new file with mode: 0644]
net/libreswan/files/etc/init.d/ipsec [new file with mode: 0644]
net/libreswan/files/etc/ipsec.conf [new file with mode: 0644]
net/libreswan/files/etc/ipsec.secrets [new file with mode: 0644]
net/libreswan/files/etc/libreswan_firewall.sh [new file with mode: 0755]
net/libreswan/files/etc/uci-defaults/091-libreswan [new file with mode: 0644]
net/libreswan/files/ipsec.conf [deleted file]
net/libreswan/files/ipsec.init [deleted file]
net/libreswan/files/ipsec.secrets [deleted file]
net/libreswan/files/usr/libexec/ipsec/_updown.xfrm [new file with mode: 0644]
net/libreswan/files/usr/libexec/rpcd/libreswan [new file with mode: 0644]
net/libreswan/files/usr/share/nftables.d/chain-pre/forward/001-libreswan.nft [new file with mode: 0644]
net/libreswan/files/usr/share/nftables.d/chain-pre/input/001-libreswan.nft [new file with mode: 0644]
net/libreswan/files/usr/share/nftables.d/chain-pre/output/001-libreswan.nft [new file with mode: 0644]
net/libreswan/files/usr/share/nftables.d/chain-pre/srcnat/001-libreswan.nft [new file with mode: 0644]
net/libreswan/files/usr/share/nftables.d/table-post/001-libreswan.nft [new file with mode: 0644]
net/lighttpd/Makefile
net/mdnsresponder/Makefile
net/modemmanager/Makefile
net/modemmanager/README.md
net/modemmanager/files/modemmanager.common
net/modemmanager/files/modemmanager.init
net/modemmanager/files/modemmanager.proto
net/modemmanager/files/usr/sbin/ModemManager-wrapper
net/modemmanager/patches/100-ublox-remove-ID_MM_PROCESS-tags.patch [new file with mode: 0644]
net/mosquitto/Makefile
net/nebula/Makefile
net/nebula/files/nebula.proto
net/net-snmp/Makefile
net/net-snmp/patches/203-if-mib-data_access-interface.c-plug-a-leak-with-pcre.patch [new file with mode: 0644]
net/netavark/Makefile
net/netbird/Makefile
net/netbird/files/netbird.init
net/nginx/Config_ssl.in
net/nginx/Makefile
net/nginx/patches/nginx-mod-lua/101-bugfix-don-t-include-pcre.h-with-PCRE2-used.patch [new file with mode: 0644]
net/nmap/Makefile
net/nmap/patches/010-Build-based-on-OpenSSL-version.patch [new file with mode: 0644]
net/ooniprobe/Makefile [deleted file]
net/ooniprobe/test.sh [deleted file]
net/openconnect/Makefile
net/openconnect/files/openconnect.sh
net/openthread-br/Makefile
net/openthread-br/patches/100-rest-support-deleting-the-dataset.patch
net/openvpn/Makefile
net/openvpn/patches/100-mbedtls-disable-runtime-version-check.patch
net/openvpn/patches/101-Fix-EVP_PKEY_CTX_-compilation-with-wolfSSL.patch
net/openvpn/patches/102-Disable-external-ec-key-support-when-building-with-wolfSSL.patch
net/openvpn/patches/103-define-LN_serialNumber-for-wolfSSL.patch
net/pdns-recursor/Makefile
net/pdns/Makefile
net/pdns/files/pdns.conf-dist
net/pptpd/Makefile
net/pptpd/files/pptpd.init
net/privoxy/Makefile
net/privoxy/patches/100-Add-pcre2-support.patch [new file with mode: 0644]
net/privoxy/patches/101-Add-regex_matches-to-reduce-HAVE_PCRE2-ifdefs.patch [new file with mode: 0644]
net/privoxy/patches/102-configure-Fix-disable-pcre2.patch [new file with mode: 0644]
net/privoxy/patches/103-pcre2-compile_pattern-Actually-pass-the-anchored-pat.patch [new file with mode: 0644]
net/quassel-irssi/Makefile [deleted file]
net/quassel-irssi/patches/001-respect-cflags.patch [deleted file]
net/quassel-irssi/patches/002-use-cc-var.patch [deleted file]
net/quassel-irssi/patches/003-use-pkgconfig-ldflags-quasselc.patch [deleted file]
net/quassel-irssi/patches/010-Get-compatible-with-potential-irssi-abi-8-and-drop-p.patch [deleted file]
net/rclone/Makefile
net/restic-rest-server/Makefile
net/samba4/Makefile
net/ser2net/Makefile
net/ser2net/files/ser2net.conf [deleted file]
net/ser2net/files/ser2net.init
net/ser2net/files/ser2net.yaml [new file with mode: 0644]
net/ser2net/patches/001-fix-disabling-pam.patch [deleted file]
net/shadowsocks-libev/Makefile
net/shadowsocks-libev/patches/100-Upgrade-PCRE-to-PCRE2.patch [new file with mode: 0644]
net/sing-box/Makefile
net/snort/Makefile
net/snort/patches/900-Convert-project-to-PCRE2.patch [new file with mode: 0644]
net/snort3/Makefile
net/snort3/files/homenet.lua
net/snort3/files/local.lua
net/snort3/files/main.uc [new file with mode: 0644]
net/snort3/files/nftables.uc [new file with mode: 0644]
net/snort3/files/snort-mgr [new file with mode: 0644]
net/snort3/files/snort-rules [new file with mode: 0644]
net/snort3/files/snort.config
net/snort3/files/snort.init
net/snort3/files/snort.uc [new file with mode: 0644]
net/snort3/patches/010-gcc13.patch [new file with mode: 0644]
net/snowflake/Makefile
net/snowflake/patches/0001-Bump-minimum-required-version-of-go.patch [deleted file]
net/snowflake/patches/0002-Update-dependencies.patch [deleted file]
net/speedtestcpp/Makefile
net/sstp-client/Makefile
net/sstp-client/files/lib/netifd/proto/sstp.sh
net/sstp-client/patches/200-openssl-deprecated.patch
net/strongswan/Makefile
net/strongswan/files/swanctl.init
net/strongswan/patches/0900-src-Patch-for-building-with-musl-on-openwrt-taken-ve.patch
net/strongswan/patches/0904-gmpdh-Plugin-that-implements-gmp-DH-functions-in-an-.patch
net/tailscale/Makefile
net/tgt/Makefile
net/tinc/Makefile
net/tinc/files/tinc.init
net/tor/Makefile
net/tor/files/tor.init
net/transmission/Makefile
net/travelmate/Makefile
net/travelmate/files/README.md
net/travelmate/files/hreward.login [new file with mode: 0755]
net/travelmate/files/travelmate.init
net/travelmate/files/travelmate.sh
net/travelmate/files/travelmate.vpn
net/travelmate/files/travelmate_ntp.hotplug
net/udp-broadcast-relay-redux-openwrt/Makefile
net/udp-broadcast-relay-redux-openwrt/files/udp-broadcast-relay-redux.init
net/udp-broadcast-relay-redux-openwrt/files/udp_broadcast_relay_redux.config
net/unbound/Makefile
net/unbound/files/dnsmasq.sh
net/unbound/patches/010-configure-uname.patch
net/uspot/Makefile [new file with mode: 0644]
net/v2ray-core/Makefile
net/v2ray-geodata/Makefile
net/v2raya/Makefile
net/wavemon/Makefile
net/wifischedule/Makefile
net/wifischedule/README.md
net/wifischedule/net/etc/init.d/wifi_schedule [new file with mode: 0644]
net/wifischedule/net/usr/bin/wifi_schedule.sh
net/xray-core/Makefile
net/yggdrasil/Makefile
net/yggdrasil/files/yggdrasil.defaults [deleted file]
net/yggdrasil/files/yggdrasil.init [deleted file]
net/yggdrasil/files/yggdrasil.sh [new file with mode: 0755]
net/yggdrasil/files/ygguci [deleted file]
net/zerotier/Makefile
net/zerotier/files/etc/init.d/zerotier
sound/owntone/Makefile
sound/pulseaudio/Makefile
sound/pulseaudio/patches/010-iconv.patch [deleted file]
sound/pulseaudio/patches/010-meson_gio.patch [new file with mode: 0644]
sound/pulseaudio/patches/020-doxygen.patch [deleted file]
sound/shairplay/Makefile [deleted file]
sound/shairplay/files/shairplay.config [deleted file]
sound/shairplay/files/shairplay.init [deleted file]
sound/shairplay/patches/001-key_file_dir.patch [deleted file]
sound/shairplay/patches/003-fix_big-endian.patch [deleted file]
sound/shairplay/patches/010-configure-only-check-for-dns_sd.h-in-case-libdl-was-.patch [deleted file]
sound/upmpdcli/Makefile
utils/acpica-unix/Makefile
utils/arp-whisper/Makefile
utils/catatonit/Makefile
utils/cligen/Makefile [new file with mode: 0644]
utils/clixon/Makefile [new file with mode: 0644]
utils/clixon/files/clixon.init [new file with mode: 0755]
utils/clixon/files/netconf-subsystem.conf [new file with mode: 0644]
utils/clixon/files/restconf.xml [new file with mode: 0644]
utils/crun/Makefile
utils/cudy-bdinfo/Makefile [new file with mode: 0644]
utils/dmidecode/Makefile
utils/docker-compose/Makefile
utils/domoticz/Makefile
utils/domoticz/patches/010-gcc12.patch [deleted file]
utils/domoticz/patches/012-minizip-overflow.patch [deleted file]
utils/domoticz/patches/990-python3.10_fix.patch [deleted file]
utils/domoticz/patches/991-linux_crash_when_formating_py.patch [deleted file]
utils/domoticz/patches/992-prevent_crash_processing_py.patch [deleted file]
utils/domoticz/patches/994-compile_err_whitout_py.patch [deleted file]
utils/domoticz/patches/995-make_sure_compile_works_without_py.patch [deleted file]
utils/dysk/Makefile [new file with mode: 0644]
utils/efibootmgr/Makefile
utils/fuse3/Makefile
utils/fx/Makefile [new file with mode: 0644]
utils/gl-puli-mcu/Config.in [new file with mode: 0644]
utils/gl-puli-mcu/Makefile
utils/gl-puli-mcu/src/gl-puli-mcu.c
utils/gummiboot/Makefile
utils/gummiboot/patches/030-fix-efi-conflicts.patch [new file with mode: 0644]
utils/irqbalance/Makefile
utils/irqbalance/patches/001-upstream-fix-aarch64-irq-parsing.patch [deleted file]
utils/irqbalance/patches/010-meson.patch
utils/irqbalance/patches/020-mark-EINVAL-error-permanent.patch [new file with mode: 0644]
utils/kmod/Makefile
utils/lsof/Makefile
utils/lsof/patches/000-disable-man.patch [new file with mode: 0644]
utils/lsof/patches/001-lsof_makefile.patch [deleted file]
utils/lsof/patches/002-lsof_noportmap.patch [deleted file]
utils/lsof/patches/003-lsof_selinux.patch [deleted file]
utils/lsof/patches/004-lsof_ccv.patch [deleted file]
utils/mc/Makefile
utils/mc/patches/010-subshell.patch
utils/mc/patches/020-fix-mouse-handling-newer-terminfo.patch
utils/mc/patches/030-mc-mksh-subshell-v2.patch
utils/mpremote/Makefile [new file with mode: 0644]
utils/mpremote/patches/001-no-importlib_metadata.patch [new file with mode: 0644]
utils/mpremote/test.sh [new file with mode: 0644]
utils/nano/Makefile
utils/nano/files/ucode.nanorc [new file with mode: 0644]
utils/nerdctl/Makefile [new file with mode: 0644]
utils/podman/Makefile
utils/podman/files/containers.conf
utils/podman/patches/010-do-not-build-docs.patch
utils/podman/patches/020-fix-build-with-musl-1.2.4.patch [new file with mode: 0644]
utils/pps-tools/Makefile
utils/pps-tools/patches/001-time_t_64bit.patch [new file with mode: 0644]
utils/procs/Makefile [new file with mode: 0644]
utils/procs/files/etc/procs/procs.toml [new file with mode: 0644]
utils/prometheus-node-exporter-lua/Makefile
utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/hwmon.lua [new file with mode: 0644]
utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/thermal.lua [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/Makefile [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/conntrack.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/cpu.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/entropy.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/filefd.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/loadavg.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/meminfo.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/netclass.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/netdev.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/selinux.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/time.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/base/uname.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/config [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/extra/dnsmasq.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/extra/ltq-dsl.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/extra/netstat.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/extra/openwrt.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/extra/snmp6.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/extra/uci_dhcp_host.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/extra/wifi.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/extra/wireguard.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/init [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/metrics.uc [new file with mode: 0644]
utils/prometheus-node-exporter-ucode/files/run.sh [new file with mode: 0755]
utils/prometheus-node-exporter-ucode/test.sh [new file with mode: 0755]
utils/qemu/Makefile
utils/qemu/patches/0001-configure-allow-disable-fortify_source.patch
utils/qemu/patches/0006-util-mmap-alloc-fix-missing-MAP_SYNC.patch
utils/qemu/patches/0010-no-tests.patch
utils/quectel-timesync/Makefile [new file with mode: 0644]
utils/restic/Makefile
utils/ripgrep/Makefile
utils/rpcd-mod-wireguard/Makefile [new file with mode: 0644]
utils/rpcd-mod-wireguard/src/CMakeLists.txt [new file with mode: 0644]
utils/rpcd-mod-wireguard/src/api.c [new file with mode: 0644]
utils/rpcd-mod-wireguard/src/wireguard.c [new file with mode: 0644]
utils/rpcd-mod-wireguard/src/wireguard.h [new file with mode: 0644]
utils/sockread/Makefile
utils/sockread/src/main.c
utils/stress-ng/Makefile
utils/stress-ng/patches/001-disable-extra-stressors.patch
utils/stress-ng/patches/002-core-stress-Add-musl-gcc-detection-and-HAVE_COMPILER.patch [new file with mode: 0644]
utils/stress-ng/patches/002-disable-compiler-test.patch [deleted file]
utils/stress-ng/test.sh [new file with mode: 0644]
utils/syncthing/Makefile
utils/syncthing/files/syncthing.init
utils/tang/Makefile
utils/tang/files/tang.init
utils/tesseract/Makefile
utils/tesseract/patches/010-cmake.patch
utils/tesseract/patches/020-musl.patch [deleted file]
utils/yq/Makefile
utils/zsh/Makefile
utils/zsh/patches/001-50658-test-Enable-to-switch-between-C-UTF-8-locales-.patch [new file with mode: 0644]
utils/zsh/patches/002-51723-migrate-pcre-module-to-pcre2.patch [new file with mode: 0644]
utils/zsh/patches/003-51728-assign-pcre-named-capture-groups-to-a-hash.patch [new file with mode: 0644]
utils/zsh/patches/004-51738-support-pcre-s-alternative-DFA-matching-algori.patch [new file with mode: 0644]
utils/zsh/patches/005-51877-do-not-build-pcre-module-if-pcre2-config-is-no.patch [new file with mode: 0644]

index 8d48d8a22e0cc36acc427156947b60430fd64a24..363e1582263ae52e0bf04491cb6ad8983f1fe9ed 100755 (executable)
@@ -13,7 +13,7 @@ mkdir -p /var/lock/
 
 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
@@ -42,7 +42,7 @@ for PKG in /ci/*.ipk; do
                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"
index b3f824c524c4d3e619c7634f8d62cfd1a071edcc..1447a395991e5751759179dd08893a1dc09bcd73 100644 (file)
@@ -43,7 +43,7 @@ jobs:
             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)"
index 57182b96b65fe8e748263c91590d2b0103080a26..396bd190d9b035504c4485bd7cb1839a02b7eac5 100644 (file)
@@ -101,17 +101,20 @@ jobs:
           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
@@ -122,6 +125,7 @@ jobs:
           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
@@ -148,6 +152,7 @@ jobs:
           cat PKG-INFO
 
       - name: Store packages
+        if: always()
         uses: actions/upload-artifact@v3
         with:
           name: ${{env.ARCHIVE_NAME}}-packages
@@ -158,6 +163,7 @@ jobs:
             PKG-INFO
 
       - name: Store logs
+        if: always()
         uses: actions/upload-artifact@v3
         with:
           name: ${{env.ARCHIVE_NAME}}-logs
@@ -166,6 +172,7 @@ jobs:
             PKG-INFO
 
       - name: Remove logs
+        if: always()
         run: sudo rm -rf logs/ || true
 
       - name: Check if any packages were built
index 993915b93f85c636851dc601fc262bd43d750492..25c332146b4d26c39e68decc8f8047bbaaeabc24 100644 (file)
@@ -200,9 +200,9 @@ checking if `foobar --version` prints the correct version. `PKG_VERSION` is the
 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
index bdd049a29a3ed82c661a47e49f4fd9f14e2ae147..556b11b23d4f392f15681f1b05a4426b1c4153d1 100644 (file)
@@ -17,6 +17,7 @@ PKG_LICENSE:=MIT
 PKG_LICENSE_FILES:=LICENSE
 
 PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
 
 include $(INCLUDE_DIR)/package.mk
 include ../../lang/rust/rust-package.mk
index 721cdb1b4ad0bd1ff631669b11d61d2d1d256ca2..c4f8c464ac6ab99e3d8ace490c12fd24e7eb9d74 100644 (file)
@@ -8,13 +8,13 @@
 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
@@ -57,7 +57,7 @@ define Package/zabbix/Default
   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
@@ -157,6 +157,7 @@ define Package/zabbix-server/Default
     +ZABBIX_MYSQL:libmariadbclient \
     @(!ZABBIX_SQLITE) \
     +libevent2 \
+    +libevent2-pthreads \
     +fping
 endef
 
@@ -209,6 +210,7 @@ define Package/zabbix-proxy/Default
     +ZABBIX_MYSQL:libmariadbclient \
     +ZABBIX_SQLITE:libsqlite3 \
     +libevent2 \
+    +libevent2-pthreads \
     +fping
 endef
 
@@ -262,8 +264,8 @@ CONFIGURE_ARGS+= \
        $(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)
index 723ccfe146c4ea5315065859255bb615ddf165e4..471e1e6b14748a249e8186ed6aaa5eda22b211b5 100644 (file)
@@ -1,6 +1,6 @@
---- 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);
index e6a6448f1ae0f660d03290fb96585e73cdd2b05d..ee99de47cf13ef64e135f3cc4166ac6a7a5edc1b 100644 (file)
@@ -8,7 +8,7 @@
 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))
@@ -20,7 +20,7 @@ GO_SOURCE_URLS:=https://dl.google.com/go/ \
 
 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
index 95b9fd38f8737913a0a54b0c2b3f73830eae676e..1d472f22627c61b8c5c94c5d53bdcf0540023141 100644 (file)
@@ -1,12 +1,12 @@
 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
@@ -61,6 +61,7 @@ Package/lua-eco-termios=$(call Package/lua-eco/Module,termios)
 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
@@ -182,6 +183,12 @@ define Package/lua-eco-nl80211/install
        $(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))
@@ -198,3 +205,4 @@ $(eval $(call BuildPackage,lua-eco-termios))
 $(eval $(call BuildPackage,lua-eco-netlink))
 $(eval $(call BuildPackage,lua-eco-ip))
 $(eval $(call BuildPackage,lua-eco-nl80211))
+$(eval $(call BuildPackage,lua-eco-ssh))
index 86dc280187607dba302a148e2f3cb2bf8a6a3b43..219736d964e5ee19c2ddc83443e4cc305559a416 100644 (file)
@@ -1,12 +1,12 @@
 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
index f752002d22ac5fe6977f859f239aed67c83c4d9c..dccdee2140d3ba83c20a7ac42aa9fdb20a54cee5 100644 (file)
@@ -8,6 +8,6 @@
 -#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
diff --git a/lang/maturin/Makefile b/lang/maturin/Makefile
deleted file mode 100644 (file)
index e1c7ca5..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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))
index a58b3286da6e589067adcabe42d2ba94278d9030..b37c433b336dee9f4ecb947ba674e4d408db9d8d 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -26,7 +26,6 @@ HOST_BUILD_PARALLEL:=1
 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
@@ -38,8 +37,8 @@ define Package/node
   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
 
@@ -47,8 +46,9 @@ define Package/node/description
   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
@@ -115,7 +115,6 @@ CONFIGURE_ARGS:= \
        --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) \
@@ -157,7 +156,11 @@ define Package/node-npm/install
 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
 
index 8e390d88cc5f6f03c056e6e9cd51f6e3c9f93e8a..06201179bc291e9af37a5f02380435a563c9eef7 100644 (file)
@@ -1,6 +1,6 @@
 --- 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, '..', '..');
  
index 5e7e54b72cea3dddfb72aed47950d69f690b1bbb..b0f950315fea922ce5969bd5d28c6cb817ae5f3a 100644 (file)
@@ -20,7 +20,7 @@
    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;
diff --git a/lang/node/patches/200-uv_gyp.patch b/lang/node/patches/200-uv_gyp.patch
new file mode 100644 (file)
index 0000000..75bc8f2
--- /dev/null
@@ -0,0 +1,10 @@
+--- 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/',
diff --git a/lang/node/patches/201-zlib_gyp.patch b/lang/node/patches/201-zlib_gyp.patch
new file mode 100644 (file)
index 0000000..cc1a46e
--- /dev/null
@@ -0,0 +1,10 @@
+--- 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': [
diff --git a/lang/node/patches/202-node_gyp.patch b/lang/node/patches/202-node_gyp.patch
new file mode 100644 (file)
index 0000000..b8bd937
--- /dev/null
@@ -0,0 +1,10 @@
+--- 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'
+       ],
diff --git a/lang/node/patches/203-icu-generic_gyp.patch b/lang/node/patches/203-icu-generic_gyp.patch
new file mode 100644 (file)
index 0000000..98b522a
--- /dev/null
@@ -0,0 +1,106 @@
+--- 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)',
diff --git a/lang/node/patches/204-v8_gyp.patch b/lang/node/patches/204-v8_gyp.patch
new file mode 100644 (file)
index 0000000..48108f3
--- /dev/null
@@ -0,0 +1,158 @@
+--- 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',
diff --git a/lang/node/patches/990-delete_unnecessary_libraries_for_host_execute.patch b/lang/node/patches/990-delete_unnecessary_libraries_for_host_execute.patch
deleted file mode 100644 (file)
index c8004f4..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
---- 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",
diff --git a/lang/node/patches/991-v8_zlib_support.patch b/lang/node/patches/991-v8_zlib_support.patch
deleted file mode 100644 (file)
index 2f298ba..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
---- 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',
diff --git a/lang/node/patches/992-v8_add_include_dirs.patch b/lang/node/patches/992-v8_add_include_dirs.patch
deleted file mode 100644 (file)
index fba1aed..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
---- 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',
diff --git a/lang/node/patches/999-cast_for_mips32.patch b/lang/node/patches/999-cast_for_mips32.patch
deleted file mode 100644 (file)
index 63600b3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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).
diff --git a/lang/node/patches/999-fix_icu_conflict.patch b/lang/node/patches/999-fix_icu_conflict.patch
deleted file mode 100644 (file)
index fdf5bf3..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
---- 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',
index dadfd14ecde78b4eccaf90293c202907d18edf7b..092dc0de3bb346668d664e073a503e05fc266828 100644 (file)
@@ -13,7 +13,7 @@ Forwarded: https://github.com/nodejs/node/issues/33816
  //
  // 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,
    };
  
index 44fc715fe9e955352df85d406c8cc994466c97d0..fe9dd59d07a08542a2b767a7f5235cbb16a0820f 100644 (file)
@@ -1,6 +1,6 @@
 --- 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':
index 1ada02fdd79a6c864e5dce631f9ea8b94314ad59..eac0257f6aea54b8f15049d7509a588ca0f9ee0f 100644 (file)
@@ -8,12 +8,12 @@
 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>
index 2763de2777f8e3e60db9917ad64da7d5d127ba8f..afd82997fe558152c1aa554a742f300ed0958b96 100644 (file)
@@ -11,22 +11,15 @@ include perlver.mk
 
 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
index f2d18f547061f25ee93d0bda0937d9190042e441..67232b6d83e70505e7e85ad6893a2661f4571f7f 100644 (file)
@@ -81,6 +81,7 @@ d_asinh='define'
 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'
@@ -88,6 +89,7 @@ d_attribute_nonnull='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'
@@ -179,6 +181,8 @@ d_fd_macros='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'
@@ -214,6 +218,7 @@ d_gdbm_ndbm_h_uses_prototypes='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'
@@ -363,6 +368,8 @@ d_newlocale='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'
@@ -427,6 +434,7 @@ d_semget='define'
 d_semop='define'
 d_sendmsg='define'
 d_setegid='define'
+d_setenv='define'
 d_seteuid='define'
 d_setgrent='define'
 d_setgrent_r='undef'
@@ -436,6 +444,7 @@ d_sethostent_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'
@@ -482,6 +491,7 @@ d_sitearch='define'
 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'
@@ -524,6 +534,7 @@ d_strtoul='define'
 d_strtoull='define'
 d_strtouq='define'
 d_strxfrm='define'
+d_strxfrm_l='define'
 d_suidsafe='undef'
 d_symlink='define'
 d_syscall='define'
@@ -537,12 +548,15 @@ d_tcsetpgrp='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'
@@ -571,6 +585,7 @@ d_vprintf='define'
 d_vsnprintf='define'
 d_wait4='define'
 d_waitpid='define'
+d_wcrtomb='define'
 d_wcscmp='define'
 d_wcstombs='define'
 d_wcsxfrm='define'
@@ -717,6 +732,7 @@ i_syssockio='undef'
 i_sysstat='define'
 i_sysstatfs='define'
 i_sysstatvfs='define'
+i_syssyscall='define'
 i_systime='define'
 i_systimek='undef'
 i_systimes='define'
@@ -737,6 +753,7 @@ i_varargs='undef'
 i_varhdr='stdarg.h'
 i_vfork='undef'
 i_wchar='define'
+i_wctype='define'
 i_xlocale='undef'
 ignore_versioned_solibs='y'
 inc_version_list=' '
@@ -924,6 +941,8 @@ spackage='Perl5'
 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'
@@ -969,6 +988,7 @@ uniq='uniq'
 use5005threads='undef'
 usecbacktrace='undef'
 usecrosscompile='define'
+usedefaultstrict='undef'
 usedevel='undef'
 usedl='define'
 usedtrace='undef'
@@ -1025,6 +1045,7 @@ versiononly='undef'
 vi=''
 voidflags='15'
 xlibpth='/usr/lib/386 /lib/386'
+xlocale_needed='undef'
 yacc='yacc'
 yaccflags=''
 zcat=''
index 93d190c5a8bfa68f756184f124352a185291e479..1b198981a96f1590a398c6332b61eab071600fa0 100644 (file)
 }
 
 ($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'
diff --git a/lang/perl/files/riscv64.config b/lang/perl/files/riscv64.config
new file mode 100644 (file)
index 0000000..4596f8c
--- /dev/null
@@ -0,0 +1,21 @@
+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'
index b318648e0109855bb130933986c529a2222c3fe5..1c0e7718cd9dcbc9d5922276896abf4c274fbe29 100644 (file)
@@ -1,17 +1,17 @@
 # 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"
diff --git a/lang/perl/patches/001-macos_11_support.patch b/lang/perl/patches/001-macos_11_support.patch
deleted file mode 100644 (file)
index f61c519..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
---- 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
-       ;;
diff --git a/lang/perl/patches/002-add-Internals-getcwd.patch b/lang/perl/patches/002-add-Internals-getcwd.patch
deleted file mode 100644 (file)
index d2a8497..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-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*
diff --git a/lang/perl/patches/003-fallback-to-the-built-in-getcwd-if-we-ca.patch b/lang/perl/patches/003-fallback-to-the-built-in-getcwd-if-we-ca.patch
deleted file mode 100644 (file)
index dcadb31..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
---- 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;
index 77ea26f46b25213b33097fe3a6c31bc4dd184020..e38a05be8d553641ef984d0e5ef7e21b42b1b631 100644 (file)
@@ -1,6 +1,6 @@
 --- 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
  
diff --git a/lang/perl/patches/020-storables-stacksize.patch b/lang/perl/patches/020-storables-stacksize.patch
deleted file mode 100644 (file)
index 903d90b..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-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();
index 2f7ebcbc49667e2a397561b0b73b60a1500548b7..806a31256b2007ee5f2c36d75261fac0d176cc21 100644 (file)
@@ -1,8 +1,8 @@
 --- 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?*)
index b0e783462b79ddee3efe6bd5ecb37f6aa2d6f327..ae044c8f165937c8bdaba558ad9d53e5d9ff5241 100644 (file)
@@ -1,8 +1,8 @@
 --- 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__
@@ -16,4 +16,4 @@
 -
  #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),
diff --git a/lang/perl/patches/301-fix_macos_static_linking.patch b/lang/perl/patches/301-fix_macos_static_linking.patch
deleted file mode 100644 (file)
index 4b4ef92..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
---- 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)
index 9afb8a8ce79a09283050be9aff56d2e0b7fc793b..efe8e0c2993f161c16538a6fbc26c205f0667544 100644 (file)
@@ -1,8 +1,8 @@
 --- 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
@@ -20,7 +20,7 @@
  # 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) = @_;
@@ -29,7 +29,7 @@
      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 => {
index d2197571a9299d6ad32990374487b5f3666fac57..09967bebd6cc64b83bc706c71bb4106962cbef63 100644 (file)
@@ -1,14 +1,14 @@
 --- 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)
@@ -17,7 +17,7 @@
        $(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)
@@ -48,7 +48,7 @@
  
  !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!'
@@ -64,7 +64,7 @@
        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!'
@@ -73,7 +73,7 @@
        $(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
  
index 347f6f2a3f33d4e639c423509d5d53b2d73891ba..6589926bc511746e59a3f1f51bada4cfd29a1f63 100644 (file)
@@ -1,6 +1,6 @@
 --- 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)
diff --git a/lang/perl/patches/920-fix-no-locale.patch b/lang/perl/patches/920-fix-no-locale.patch
deleted file mode 100644 (file)
index 25ff285..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-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';
index a098210dd3a5ed0885f0a31cd699f9b1c703b5df..d0ccec913fc6c1496fd1c5e8cbc9617545b549b3 100644 (file)
@@ -1,11 +1,11 @@
 --- 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};
+     }
diff --git a/lang/perl/patches/999-fix-build-failure-against-gcc-10.patch b/lang/perl/patches/999-fix-build-failure-against-gcc-10.patch
deleted file mode 100644 (file)
index aa43f05..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-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.
diff --git a/lang/perl/patches/999-fixup-regex-engine-build-under-Uusedl.patch b/lang/perl/patches/999-fixup-regex-engine-build-under-Uusedl.patch
new file mode 100644 (file)
index 0000000..99cc13b
--- /dev/null
@@ -0,0 +1,541 @@
+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, ...)
+ {
index e23bf8ef58ed0e44102a4d9185e07aad600ae435..c50fda1b1fd2cb7c43b54c61ec033abd51a99c00 100644 (file)
@@ -51,20 +51,6 @@ endef
 $(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
@@ -154,7 +140,7 @@ endef
 
 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))
@@ -419,7 +405,6 @@ endef
 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))
@@ -557,9 +542,9 @@ DEPENDS+=+perlbase-config
 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))
@@ -572,7 +557,7 @@ DEPENDS+=+perlbase-essential +perlbase-feature +perlbase-version
 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
 
@@ -725,7 +710,7 @@ 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))
@@ -905,7 +890,7 @@ endef
 
 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))
@@ -919,7 +904,7 @@ endef
 
 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))
@@ -1142,7 +1127,7 @@ endef
 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/
@@ -1202,7 +1187,6 @@ endef
 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))
@@ -1382,7 +1366,7 @@ DEPENDS+=+perlbase-base +perlbase-config +perlbase-essential +perlbase-io +perlb
 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
@@ -1441,7 +1425,7 @@ DEPENDS+=+perlbase-essential +perlbase-fcntl +perlbase-xsloader
 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
 
@@ -1522,7 +1506,7 @@ DEPENDS+=+perlbase-essential +perlbase-re +perlbase-unicore
 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
 
index dbec8151ebe6aa1b7fc0c3b7a100d85697770321..b0acc5d9e18f69dfe62288779ae25b9a88272543 100644 (file)
@@ -1,4 +1,4 @@
-PERL_VERSION:=5.28.1
+PERL_VERSION:=5.38.2
 
 PERL_EXPLODE:=$(subst ., ,$(PERL_VERSION))
 
index 1a6543caca4cfc061d1f000c0102bfc6fc76ca61..07b2a5677cff3d4dd5bef021015ec7aede31fa46 100644 (file)
@@ -8,9 +8,9 @@ include $(TOPDIR)/rules.mk
 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
index 0a53121c9e118bd065b3e9f32108f430af424b80..88ed4d60f6ca92784d1dad2574ce4c2c3636982c 100644 (file)
@@ -8,9 +8,9 @@ include $(TOPDIR)/rules.mk
 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
index d2a85f26c550fdef7af958558d1d01c47745bc40..3c62f65614de6fd2efc86a3e8b205ad82322be40 100644 (file)
@@ -8,9 +8,9 @@ include $(TOPDIR)/rules.mk
 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
index 56e77c7ca92321edf3fde73cd6b52bbb9c52d452..a92c703cbbe4426f5cf2927110ce1b0b0d1ccbe1 100644 (file)
@@ -6,7 +6,7 @@
 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>
@@ -16,7 +16,7 @@ PKG_CPE_ID:=cpe:/a:php:php
 
 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
index 7bd167898a871edee62cba3593449ba041286d96..d6b86642936834ece9374274ef068bb0fd2d4fc7 100644 (file)
@@ -12,9 +12,9 @@ PKG_RELEASE:=1
 
 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
@@ -23,9 +23,8 @@ PKG_LICENSE_FILES:=LICENSE
 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
 
@@ -50,7 +49,7 @@ endef
 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
@@ -88,7 +87,7 @@ This contains source files for packages specific to the MicroPython Unix
 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 \
@@ -112,7 +111,7 @@ define Build/Compile
 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
@@ -120,7 +119,7 @@ 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/
diff --git a/lang/python/micropython-mpremote/Makefile b/lang/python/micropython-mpremote/Makefile
deleted file mode 100644 (file)
index 9beca01..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# 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))
diff --git a/lang/python/micropython-mpremote/patches/001-no-importlib_metadata.patch b/lang/python/micropython-mpremote/patches/001-no-importlib_metadata.patch
deleted file mode 100644 (file)
index 6f5fc49..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
---- a/requirements.txt
-+++ b/requirements.txt
-@@ -1,2 +1 @@
- pyserial >= 3.3
--importlib_metadata >= 1.4
index 6e129c15d6329fa027953e73bf06613b35dbf6fe..17b0bdd0c521e5e02b5342cd549021ed03711c11 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -70,14 +70,20 @@ $(call Package/micropython/Default/description)
 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
@@ -89,20 +95,20 @@ define Build/Configure
 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
index a847e96b44b1c797fa9807e9fdea97c702730437..9dc4c59bc7f033503659a2d0285aebc513911bf8 100644 (file)
@@ -1,7 +1,7 @@
 --- 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)
index dccd5ba51f48102370fe016260f7cbaee040d4d7..3399412e4acf4b17ab5ccac63c5babad8c1fc33a 100644 (file)
@@ -9,7 +9,7 @@ Subject: [PATCH 06/10] extmod: Use system mbedtls
 
 --- 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)
@@ -54,7 +54,6 @@ Subject: [PATCH 06/10] extmod: Use system mbedtls
 -      md4.c \
 -      md5.c \
 -      md.c \
--      md_wrap.c \
 -      oid.c \
 -      padlock.c \
 -      pem.c \
@@ -79,9 +78,11 @@ Subject: [PATCH 06/10] extmod: Use system mbedtls
 -      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 \
diff --git a/lang/python/micropython/patches/050-py-stackctrl-fix-gcc-13.patch b/lang/python/micropython/patches/050-py-stackctrl-fix-gcc-13.patch
deleted file mode 100644 (file)
index 8cd7df6..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-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) {
index 21f53bddddc453b73c592118d7a157aa8af518de..ee2b4620dd46a586c84c932f7187e7fd4898f13f 100644 (file)
@@ -1 +1 @@
-include("$(MPY_DIR)/extmod/uasyncio")
+include("$(MPY_DIR)/extmod/asyncio")
diff --git a/lang/python/micropython/test.sh b/lang/python/micropython/test.sh
new file mode 100644 (file)
index 0000000..82cf2ec
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+nl="
+"
+
+micropython -c "import sys${nl}print(sys.version)" | grep -F " MicroPython v${PKG_VERSION} "
index c974723a97621dee09e72f34dc7623a750485983..c6b1faf0ee0f941e22c2918d359ecaacec11edc4 100644 (file)
@@ -7,11 +7,11 @@
 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
 
index 3dc07d9926674519754b1935334b6f6fb0267f8a..e5ac168cbfadbf0a4cf264642acdae5ce90876c4 100644 (file)
@@ -6,6 +6,6 @@
  requires = [
 -  "setuptools>=67.8",
 +  "setuptools",
-   "wheel",
  ]
  backend-path = [
+   "_custom_build",
diff --git a/lang/python/pillow/test.sh b/lang/python/pillow/test.sh
new file mode 100644 (file)
index 0000000..9bad292
--- /dev/null
@@ -0,0 +1,20 @@
+#!/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
diff --git a/lang/python/pipx/Makefile b/lang/python/pipx/Makefile
new file mode 100644 (file)
index 0000000..f45abe5
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# 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))
diff --git a/lang/python/pipx/test.sh b/lang/python/pipx/test.sh
new file mode 100644 (file)
index 0000000..a4f2348
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$1" = pipx ] || exit 0
+
+pipx --version | grep -Fx "$PKG_VERSION"
diff --git a/lang/python/pyodbc/Makefile b/lang/python/pyodbc/Makefile
deleted file mode 100644 (file)
index 4f10f91..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# 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))
diff --git a/lang/python/python-argcomplete/Makefile b/lang/python/python-argcomplete/Makefile
new file mode 100644 (file)
index 0000000..b725a4b
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# 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))
diff --git a/lang/python/python-argcomplete/patches/001-unpin-setuptools.patch b/lang/python/python-argcomplete/patches/001-unpin-setuptools.patch
new file mode 100644 (file)
index 0000000..a85ce85
--- /dev/null
@@ -0,0 +1,9 @@
+--- 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]
diff --git a/lang/python/python-argcomplete/test.sh b/lang/python/python-argcomplete/test.sh
new file mode 100644 (file)
index 0000000..0ecba3e
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$1" = python3-argcomplete ] || exit 0
+
+python3 -c 'import argcomplete'
index 267f59f346341145e6217a6dbf96615a785175c3..da5951b8dc3e2efe987bbcf82b768fed7b7d4d39 100644 (file)
@@ -6,11 +6,11 @@
 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
index 9443614f42a07abd5cae80cf84c788974164e10a..0f59e743f81569b45d2f9ddd2db7138ef4f27b22 100644 (file)
@@ -2,10 +2,11 @@
 
 [ "$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
index 6e88357d22a0b9b16a2548116f39a3f82e5558a1..4ba811e9a8644c6dfc4309da42bc4f88e597c696 100644 (file)
@@ -8,11 +8,11 @@
 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
index b1b2f7996883cc0bdd69dbc8337b9bf42548df30..398b017c5f04c42d619f085743c8a15e4e947aa6 100644 (file)
@@ -2,11 +2,12 @@
 
 [ "$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
index 129a72b5c8dc057c361f24c5026cea1cd6a902ae..f0cd24659e1950b9e1575e304a75dfff96b60123 100644 (file)
@@ -1,5 +1,5 @@
 #
-# 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.
@@ -8,16 +8,18 @@
 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
diff --git a/lang/python/python-constantly/patches/001-unpin-setuptools.patch b/lang/python/python-constantly/patches/001-unpin-setuptools.patch
new file mode 100644 (file)
index 0000000..9d890ab
--- /dev/null
@@ -0,0 +1,9 @@
+--- 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]
diff --git a/lang/python/python-constantly/test.sh b/lang/python/python-constantly/test.sh
new file mode 100644 (file)
index 0000000..d6b367c
--- /dev/null
@@ -0,0 +1,27 @@
+#!/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
index 6ef9cb969f7ddfc5fa16fb340225da7cc82a48e3..c8b1950d2e21f7e4f9d3f3845767f5cbef909361 100644 (file)
@@ -8,15 +8,16 @@
 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
 
index b706d561ab62a1ac6a31676c943179602442c295..308f5456b8681ff1cac753682fa7f8893b1de4e3 100644 (file)
@@ -2,11 +2,13 @@
 
 [ "$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
diff --git a/lang/python/python-fnv-hash-fast/Makefile b/lang/python/python-fnv-hash-fast/Makefile
new file mode 100644 (file)
index 0000000..b475859
--- /dev/null
@@ -0,0 +1,38 @@
+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))
diff --git a/lang/python/python-fnvhash/Makefile b/lang/python/python-fnvhash/Makefile
new file mode 100644 (file)
index 0000000..b0c2316
--- /dev/null
@@ -0,0 +1,33 @@
+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))
index 39f890985afbb3612381f6cecf18a80562c0607b..6726a77768d63b4ff2f9b9f77d8744b76ced0dd4 100644 (file)
@@ -8,12 +8,12 @@
 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
index ee8738a61a3526e3b0b84fe07df0208074e80bad..33129b03a8f1991bfbc24a80e983729c8ca5884a 100644 (file)
@@ -8,14 +8,14 @@
 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
@@ -30,9 +30,7 @@ define Package/python3-idna
   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
diff --git a/lang/python/python-idna/test.sh b/lang/python/python-idna/test.sh
new file mode 100644 (file)
index 0000000..85f779c
--- /dev/null
@@ -0,0 +1,23 @@
+#!/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
diff --git a/lang/python/python-jsonschema-specifications/Makefile b/lang/python/python-jsonschema-specifications/Makefile
new file mode 100644 (file)
index 0000000..c33f57e
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# 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))
diff --git a/lang/python/python-jsonschema-specifications/test.sh b/lang/python/python-jsonschema-specifications/test.sh
new file mode 100644 (file)
index 0000000..cdf2f57
--- /dev/null
@@ -0,0 +1,12 @@
+#!/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
index 4c6e44d4680c7a1c585bd2a4e6b68082f3de0b79..cd87fa1e67d3c2762c70af2a0afed0059e1e26dc 100644 (file)
@@ -1,11 +1,11 @@
 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
@@ -22,9 +22,16 @@ define Package/python3-jsonschema
   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
diff --git a/lang/python/python-jsonschema/test.sh b/lang/python/python-jsonschema/test.sh
new file mode 100644 (file)
index 0000000..37fe492
--- /dev/null
@@ -0,0 +1,21 @@
+#!/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
diff --git a/lang/python/python-lru-dict/Makefile b/lang/python/python-lru-dict/Makefile
new file mode 100644 (file)
index 0000000..a5171d6
--- /dev/null
@@ -0,0 +1,37 @@
+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))
index 50f828151457f067cde934e0bb11e95b0e441d41..51465159328a4de6854d576aa1da65113a9dbef3 100644 (file)
@@ -6,11 +6,11 @@
 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
diff --git a/lang/python/python-maturin/Makefile b/lang/python/python-maturin/Makefile
new file mode 100644 (file)
index 0000000..67bb1e0
--- /dev/null
@@ -0,0 +1,51 @@
+# 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))
diff --git a/lang/python/python-orjson/Makefile b/lang/python/python-orjson/Makefile
new file mode 100644 (file)
index 0000000..39ef2cf
--- /dev/null
@@ -0,0 +1,37 @@
+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))
index f7aef963337487e1e7d022d5646fd6b1d35e3796..e2dcacfd32bc3a01186006a93129b2af3546e9d0 100644 (file)
@@ -8,11 +8,11 @@
 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
index c21d2bdffd3eca0aca2fd6a22ecf68231f678b23..c41b27ca4448d3e16448a52a03cc56914d5689ea 100644 (file)
@@ -8,11 +8,11 @@
 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
index 27681c1af4557c2b77bba1da4fd37a2f88f297da..e9eafab969dacb399efe4d6c7d096cf13c0b49de 100644 (file)
@@ -1,13 +1,19 @@
 --- 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))
index 4616fe0654e821c2d0ca8a9b0a9f7195c6a43014..8f68049a8b284f4e52bf0b3f00d08ce9a19b16ec 100644 (file)
@@ -1,11 +1,15 @@
 --- 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]:
index 87a8178a76cd639a2725198dd42207a706dddd36..99a0258aa6088434b6b6ddabd60e44bbf795d364 100644 (file)
@@ -9,7 +9,7 @@ Patch-Name: disable-pip-version-check.patch
 
 --- 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",
diff --git a/lang/python/python-platformdirs/Makefile b/lang/python/python-platformdirs/Makefile
new file mode 100644 (file)
index 0000000..cd867cd
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# 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))
diff --git a/lang/python/python-platformdirs/test.sh b/lang/python/python-platformdirs/test.sh
new file mode 100644 (file)
index 0000000..40dabb2
--- /dev/null
@@ -0,0 +1,33 @@
+#!/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
index 3bcb1d9ca6b44ef5150ba6d459b610d7317f4e59..ab0d12aa44a749249d5b05de8982dc5127e0bbb2 100644 (file)
@@ -8,12 +8,12 @@
 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
index 998a06a5713e57ac88fba3e543883c98456007ee..b44ea2a4241bdda51f2d650a3ddab79acd32f751 100644 (file)
@@ -8,11 +8,11 @@
 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
diff --git a/lang/python/python-pyasn1/test.sh b/lang/python/python-pyasn1/test.sh
new file mode 100644 (file)
index 0000000..2f13e5f
--- /dev/null
@@ -0,0 +1,51 @@
+#!/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
index c3516f73f4ce7f19dac24d30486400b9be66892a..f16e2b1e38dd979809e902d73b49ac1685eef739 100644 (file)
@@ -2,11 +2,11 @@
 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
diff --git a/lang/python/python-pyodbc/Makefile b/lang/python/python-pyodbc/Makefile
new file mode 100644 (file)
index 0000000..6357d4b
--- /dev/null
@@ -0,0 +1,42 @@
+# 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
diff --git a/lang/python/python-pyodbc/test.sh b/lang/python/python-pyodbc/test.sh
new file mode 100644 (file)
index 0000000..f6cf04b
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$1" = python3-pyodbc ] || exit 0
+
+python3 -c 'import pyodbc'
index 383d48d6bc8ea6aac3bfde15617021ff6813e31b..6aed546abe08f58bf2393e14a2899088466c6138 100644 (file)
@@ -8,11 +8,11 @@
 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
diff --git a/lang/python/python-referencing/Makefile b/lang/python/python-referencing/Makefile
new file mode 100644 (file)
index 0000000..7575ba7
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# 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))
diff --git a/lang/python/python-referencing/test.sh b/lang/python/python-referencing/test.sh
new file mode 100644 (file)
index 0000000..0517ba1
--- /dev/null
@@ -0,0 +1,35 @@
+#!/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
diff --git a/lang/python/python-rpds-py/Makefile b/lang/python/python-rpds-py/Makefile
new file mode 100644 (file)
index 0000000..c2aef84
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# 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))
diff --git a/lang/python/python-rpds-py/test.sh b/lang/python/python-rpds-py/test.sh
new file mode 100644 (file)
index 0000000..d5dec8f
--- /dev/null
@@ -0,0 +1,21 @@
+#!/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
index 19325c1fda4356e75455809a9690b3c518b3863f..7fe77ff7ad70a7c6b1f4c37c9c3c70289aa3c572 100644 (file)
@@ -8,11 +8,11 @@
 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
@@ -26,7 +26,6 @@ HOST_BUILD_DEPENDS:= \
        python-wheel/host \
        python-setuptools-scm/host \
        python-semantic-version/host \
-       python-typing-extensions/host \
        rust/host
 
 include ../pypi.mk
@@ -46,7 +45,6 @@ define Package/python3-setuptools-rust
     +python3-logging \
     +python3-semantic-version \
     +python3-setuptools \
-    +python3-typing-extensions \
     +rust
   BUILDONLY:=1
 endef
index 8138a9955648c3380e86b7fd47ab3f9b38f67de8..b2ebfa1c642a965a4a18cc3977fc17aca56b7d2d 100644 (file)
@@ -8,11 +8,11 @@
 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
index 98f6ec98ead886591f56da6f5b165514511a4498..20fec724cf9681044703c5ca6b4754df4e5d4573 100644 (file)
@@ -1,11 +1,11 @@
 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
index 447fa8704bd36e81c6a17bf941b28e091e40ba01..fd802604717adbc2807c58b977ade21b2b64259a 100644 (file)
@@ -8,11 +8,11 @@
 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
index 5befac2b3e081ef0c047369b7603890be10b3f33..79f2f2a237af8a8b4165540b15d6b698980ba3e6 100644 (file)
@@ -9,12 +9,12 @@
 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
 
index bf8873f41437b2d5083c9ba30d20be477d843252..d9ad0d59e2178b8cf096a5a02d983c7c880108f8 100644 (file)
@@ -1,6 +1,6 @@
 --- 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"
index 841b5e09e7c261d0d9358c30c1d1a426006c0e6f..ddf8f9e306c1aacb1a48bb99e292d8d339348926 100644 (file)
@@ -1,6 +1,6 @@
 --- a/pyproject.toml
 +++ b/pyproject.toml
-@@ -194,6 +194,7 @@ exclude = [
+@@ -182,6 +182,7 @@ exclude = [
      "*.pxi",
      "*.pyx",
      "build.bat",
index 12abc240a5a0b3726f48e802b4db358652cb0736..501eec31f9353d69d2f21a2a2c11fa8fe47aca81 100644 (file)
@@ -8,12 +8,12 @@
 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
diff --git a/lang/python/python-userpath/Makefile b/lang/python/python-userpath/Makefile
new file mode 100644 (file)
index 0000000..969a238
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# 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))
diff --git a/lang/python/python-userpath/patches/0001-Handle-OSErrors-when-running-show-path-commands.patch b/lang/python/python-userpath/patches/0001-Handle-OSErrors-when-running-show-path-commands.patch
new file mode 100644 (file)
index 0000000..3a412e6
--- /dev/null
@@ -0,0 +1,31 @@
+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()]
diff --git a/lang/python/python-userpath/patches/0001-Use-Sh-as-base-class-for-Bash-and-Zsh.patch b/lang/python/python-userpath/patches/0001-Use-Sh-as-base-class-for-Bash-and-Zsh.patch
new file mode 100644 (file)
index 0000000..69dfde2
--- /dev/null
@@ -0,0 +1,89 @@
+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 = {
diff --git a/lang/python/python-userpath/patches/0002-Add-support-for-ash-Almquist-shell.patch b/lang/python/python-userpath/patches/0002-Add-support-for-ash-Almquist-shell.patch
new file mode 100644 (file)
index 0000000..2c1132e
--- /dev/null
@@ -0,0 +1,112 @@
+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,
diff --git a/lang/python/python-userpath/test.sh b/lang/python/python-userpath/test.sh
new file mode 100644 (file)
index 0000000..e87d325
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$1" = python3-userpath ] || exit 0
+
+userpath --version | grep -Fx "userpath, version $PKG_VERSION"
diff --git a/lang/python/python-versioneer/Makefile b/lang/python/python-versioneer/Makefile
new file mode 100644 (file)
index 0000000..b21866a
--- /dev/null
@@ -0,0 +1,51 @@
+#
+# 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))
index 3044b2eb59763f7ee64230155ed4eb97fd396253..c3173ce1edf5b18925cddeff61f43454e9fd394e 100644 (file)
@@ -1,11 +1,11 @@
 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
index 2b89d569e295c2d2fa976faa589e57e2807d0763..28f549b559201c1e41114e44a5ecbd4c2d2716bf 100644 (file)
@@ -8,11 +8,11 @@
 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
index d1fb831d0787a01ab4f60eb1e48a1a7ca0bf3d1e..81eac63f9b2df92c51e1680cfc1bab9f812fb56b 100644 (file)
@@ -9,11 +9,11 @@
 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
@@ -29,7 +29,7 @@ define Package/python3-zope-interface
   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
index 364ae216fbb17e076106e6362ed2cdb688a12c6e..40aed6e2bff3b8840aec5a4927b891f5376db180 100644 (file)
@@ -1,6 +1,6 @@
 --- 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",
        ],
@@ -9,7 +9,7 @@
        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,
diff --git a/lang/python/python-zope-interface/test.sh b/lang/python/python-zope-interface/test.sh
new file mode 100644 (file)
index 0000000..4812377
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$1" = python3-zope-interface ] || exit 0
+
+python3 -c 'import zope.interface'
index ca5cb64baacc31e607eca4fe56ca4047a0866924..3cc20c2cef0ed150241c48100ffb2a1dacdafc08 100644 (file)
@@ -78,8 +78,8 @@ HOST_PYTHON3_VARS = \
        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
index 0693d21ee0694f3361e0111cdf2e9db0e62547d1..3300f1beabe39c2c5651b100896c7f8c4369e108 100644 (file)
@@ -45,11 +45,9 @@ PYTHON3_VARS = \
        _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
index 4e503fb6e41c4c79a38e88a56a84507ad820698f..555b1804c0e2ddd4559ea0af36ec1fd61f04bb45 100644 (file)
@@ -8,11 +8,11 @@
 # 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
index 14915715bca77d64bc203104e22fb129abb45f53..f34fc86951d9edd5dcdc64ab98e2e6e4fd5cfccf 100644 (file)
@@ -16,7 +16,7 @@ PKG_VERSION:=$(PYTHON3_VERSION).$(PYTHON3_VERSION_MICRO)
 
 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
diff --git a/lang/python/python3/patches-host-setuptools/0001-Adjust-library-header-paths-for-cross-compilation.patch b/lang/python/python3/patches-host-setuptools/0001-Adjust-library-header-paths-for-cross-compilation.patch
new file mode 100644 (file)
index 0000000..06dbb43
--- /dev/null
@@ -0,0 +1,38 @@
+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('.')
index 9bb10fac7927a7197108ddae50cd794c954d705d..7c0044ff891b7ba9c895a660c56cbedc18db758e 100644 (file)
@@ -1,6 +1,6 @@
 --- 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
@@ -8,7 +8,7 @@
        -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
index aa56d89426003c7d0b1b68aefaa42400ee631883..3c74874c91ed7f6285e84033430d8e3f38e6539c 100644 (file)
@@ -1,6 +1,6 @@
 --- 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).
index c3e95a3f40b0c2ac197a68a254b135daa1c33f74..8f1ae5bdc31ae97d822dd8414e9ed98c35a78919 100644 (file)
@@ -289,7 +289,7 @@ Signed-off-by: Jeffery To <jeffery.to@gmail.com>
 +#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])
diff --git a/lang/rust/Config.in b/lang/rust/Config.in
new file mode 100644 (file)
index 0000000..62051af
--- /dev/null
@@ -0,0 +1,15 @@
+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
index 096b225c39694715b30c1249c5b2b80ce0c38fdb..ba322cf1dcb8fb212ef2e2c5b586190d7174963c 100644 (file)
@@ -5,20 +5,20 @@
 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
@@ -31,7 +31,6 @@ define Package/rust
   TITLE:=Rust Programming Language Compiler
   URL:=https://www.rust-lang.org/
   DEPENDS:=$(RUST_ARCH_DEPENDS)
-  BUILDONLY:=1
 endef
 
 define Package/rust/description
@@ -40,8 +39,12 @@ 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 = \
@@ -50,23 +53,24 @@ 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 \
@@ -81,22 +85,24 @@ define Host/Uninstall
 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
 
diff --git a/lang/rust/files/cargo-config b/lang/rust/files/cargo-config
deleted file mode 100644 (file)
index 2f490dc..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-[target.@RUSTC_TARGET_ARCH@]
-linker = "@TARGET_CC_NOCACHE@"
-
-[profile.stripped]
-inherits = "release"
-opt-level = "s"
-strip = true
index c5266669dbebc872cf6269fae8fb93d3c8ca2e6b..a700a007d225fd7635f215332cb38667ca12ec00 100644 (file)
@@ -11,7 +11,7 @@ Subject: [PATCH] Update xz2 and use it static
 
 --- a/src/bootstrap/Cargo.lock
 +++ b/src/bootstrap/Cargo.lock
-@@ -430,9 +430,9 @@ dependencies = [
+@@ -424,9 +424,9 @@ dependencies = [
  
  [[package]]
  name = "lzma-sys"
@@ -23,7 +23,7 @@ Subject: [PATCH] Update xz2 and use it static
  dependencies = [
   "cc",
   "libc",
-@@ -899,9 +899,9 @@ dependencies = [
+@@ -871,9 +871,9 @@ dependencies = [
  
  [[package]]
  name = "xz2"
diff --git a/lang/rust/patches/0002-rustc-bootstrap-cache.patch b/lang/rust/patches/0002-rustc-bootstrap-cache.patch
new file mode 100644 (file)
index 0000000..d678a6d
--- /dev/null
@@ -0,0 +1,52 @@
+--- 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));
diff --git a/lang/rust/patches/0003-bump-libc-deps-to-0.2.146.patch b/lang/rust/patches/0003-bump-libc-deps-to-0.2.146.patch
new file mode 100644 (file)
index 0000000..7d02916
--- /dev/null
@@ -0,0 +1,128 @@
+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"
index 39cf1f23c5c33ea02f9a96ddae1d1ff445d6ce49..e5629293760b57ed0ee2ec5d58b12575aeeca646 100644 (file)
@@ -2,36 +2,42 @@
 #
 # 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
index 8d30ee86ce680c37401635c720977538bfe4356b..24341d7063f20cc5fda33b858eadb7a7bb49d170 100644 (file)
@@ -15,26 +15,22 @@ ifeq ($(origin RUST_INCLUDE_DIR),undefined)
 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
index dfd417340aa11198ca7e237ae0d015be236ca9a5..7a4d1fcf888bf6235b29d527257cd54061b57749 100644 (file)
@@ -5,8 +5,7 @@
 # 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
@@ -53,6 +52,7 @@ ifeq ($(ARCH),arm)
 
   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
 
@@ -62,3 +62,37 @@ 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)
index 1ea497c561d51e8b656b18544e211a855902a67f..88b51c32b8158684342676690e9d141398cbb71f 100644 (file)
@@ -217,23 +217,6 @@ $(call Package/avahi/Default/description)
  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
@@ -294,10 +277,6 @@ CONFIGURE_ARGS += \
        --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
@@ -314,11 +293,6 @@ define Build/InstallDev
        $(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
@@ -341,11 +315,6 @@ define Package/libavahi-client/install
        $(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/
@@ -393,7 +362,6 @@ define Package/avahi-dnsconfd/install
 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))
index 88964f5ff0a3dbe95a460c208803c9e524ca9755..b39d46c2573964c549b83358c5192da6d9c5f35b 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=cyrus-sasl
 PKG_VERSION:=2.1.28
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 
@@ -47,6 +47,12 @@ define Package/libsasl2-sasldb
   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 \
@@ -132,5 +138,11 @@ define Package/libsasl2-sasldb/install
        $(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))
index f0563ba7ba932e743f0ddbcc525d8a22c78dd0ac..fd5302ee441553d11463470e69add7ab4ce52b5b 100644 (file)
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 
 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)
@@ -25,7 +25,7 @@ define Package/efivar
   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
 
diff --git a/libs/efivar/patches/006-build-util-c-separately-for-makeguids.patch b/libs/efivar/patches/006-build-util-c-separately-for-makeguids.patch
new file mode 100644 (file)
index 0000000..2305ebb
--- /dev/null
@@ -0,0 +1,32 @@
+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))
index d2a0e9601ff58dfe1bc5f0c4b79ad1396d648601..975882226b090d75229342f1dc594e6d7245b8f8 100644 (file)
@@ -15,7 +15,7 @@ PKG_NAME:=elektra
 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
diff --git a/libs/elektra/patches/010-gcc13.patch b/libs/elektra/patches/010-gcc13.patch
new file mode 100644 (file)
index 0000000..35195de
--- /dev/null
@@ -0,0 +1,19 @@
+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>
index 30241356fa163de835e4f66dbbb3899cf5e30768..9ff131de3686c590a49849aa2c19fdbf8b024778 100644 (file)
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
 
 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
diff --git a/libs/h2o/patches/900-cve-2023-44487.patch b/libs/h2o/patches/900-cve-2023-44487.patch
new file mode 100644 (file)
index 0000000..d5489d5
--- /dev/null
@@ -0,0 +1,203 @@
+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;
+ }
diff --git a/libs/h2o/patches/901-bump-soname.patch b/libs/h2o/patches/901-bump-soname.patch
new file mode 100644 (file)
index 0000000..6ae3c22
--- /dev/null
@@ -0,0 +1,35 @@
+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
index 310dc354cb4f32f58b19276840e7124e7859a2d6..0fddd5ffd5e8e18f8f65cd84f607fb9736e57294 100644 (file)
@@ -8,14 +8,14 @@
 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
index 59caff9511bfa6d4fc8e47bba7b1d05d89702790..f5f91d8d2ae5826faf2e4d629316283a4d0e2443 100644 (file)
@@ -8,7 +8,7 @@
 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>
@@ -17,7 +17,7 @@ PKG_LICENSE:=GPL-2.0-only
 
 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
index 0d74b542eb3564df9abf052b9b7edd38d331fdfe..85024008e73ad3fa3bde3f845926ba9dce3c25d7 100644 (file)
@@ -8,12 +8,12 @@
 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
 
index 41878f57efa1ea94aadeb06bfc0d88ce17be5b6d..66dfc36531194bcbf329116541094dd207b84abb 100644 (file)
@@ -8,12 +8,12 @@
 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>
@@ -36,7 +36,7 @@ CONFIGURE_ARGS += --with-local-libgcrypt
 endif
 
 ifneq ($(CONFIG_LIBNDPI_PCRE),)
-CONFIGURE_ARGS += --with-pcre
+CONFIGURE_ARGS += --with-pcre2
 endif
 
 ifneq ($(CONFIG_LIBNDPI_MAXMINDDB),)
@@ -48,7 +48,7 @@ define Package/libndpi
   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
diff --git a/libs/libndpi/patches/001-Move-from-PCRE-to-PCRE2.patch b/libs/libndpi/patches/001-Move-from-PCRE-to-PCRE2.patch
new file mode 100644 (file)
index 0000000..731d1b2
--- /dev/null
@@ -0,0 +1,197 @@
+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
index 54e7f2b21d3d314fde1c7ca849c3a423020775be..f4ce5117ceeaa604e025dadc1a7dff7fa4eb9fe7 100644 (file)
@@ -1,23 +1,21 @@
 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
@@ -33,6 +31,9 @@ venerable pupnp (https://github.com/pupnp/pupnp), based on its 1.6.x
 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/
index 21a7af1fc7e791a7890ae1fa3b87441ae12f2726..5652332fe3816250a52e6d0e080c084b054505e0 100644 (file)
@@ -8,12 +8,12 @@
 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
 
diff --git a/libs/libsocketcan/Makefile b/libs/libsocketcan/Makefile
new file mode 100644 (file)
index 0000000..67ba3a9
--- /dev/null
@@ -0,0 +1,55 @@
+#
+# 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))
index 1690b67e23eefd064f9dccf3e791b3fbcd944bc4..1d76e81169cb11ecb18da4f0f36a77e57f47e498 100644 (file)
@@ -8,12 +8,12 @@
 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
index 08403d527b9f13d2f4c01b9798c497eeff577583..1896c6188ad20ad5f9323fd0093c90ef08db23ce 100644 (file)
@@ -1,12 +1,12 @@
 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
index 1edc610b954c3230812c2acb599e368c6c4531f9..d9c0873c96dc16c47111beef1dcbdaddec57ccd8 100644 (file)
@@ -8,12 +8,12 @@
 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
index c481387285381cfa4c292888b619e1b957afe87b..656becde61847684d18b7347f3f3fb34fe2ed424 100644 (file)
@@ -6,12 +6,12 @@
 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>
 
diff --git a/libs/libzip/patches/010-nossl.patch b/libs/libzip/patches/010-nossl.patch
deleted file mode 100644 (file)
index 6a68752..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- 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);
index c0bc799df2e0bb620e703060db78087d94dfd43f..30b9b5b27c7720c1140699df473b1fee1558b4c9 100644 (file)
 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
diff --git a/libs/newt/test.sh b/libs/newt/test.sh
new file mode 100644 (file)
index 0000000..ae90067
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+case "$1" in
+
+python3-newt)
+       python3 -c 'import snack'
+       ;;
+
+whiptail)
+       whiptail --version | grep -Fx "whiptail (newt): $PKG_VERSION"
+       ;;
+
+esac
index 7135194eaed25ccfe049049d1a2843bb4456e34c..a3848fb3c52ad42917486fdf9abdaf2b16fe7bf7 100644 (file)
@@ -1,12 +1,12 @@
 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
diff --git a/libs/nghttp3/Makefile b/libs/nghttp3/Makefile
new file mode 100644 (file)
index 0000000..6573977
--- /dev/null
@@ -0,0 +1,38 @@
+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))
diff --git a/libs/ngtcp2/Makefile b/libs/ngtcp2/Makefile
new file mode 100644 (file)
index 0000000..dc5d04d
--- /dev/null
@@ -0,0 +1,40 @@
+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))
index 38947885812450034d5cbfe78d7254987edd29d3..0b403f21bfe71ddd8571995fa096426bc67553a4 100644 (file)
@@ -5,12 +5,12 @@
 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>
 
index 4bb3b85886d188b449afb4298b7c7f847a268514..4f916690259a85a0cf96725a253d76304b141280 100644 (file)
@@ -23,7 +23,7 @@ PKG_INSTALL:=1
 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
diff --git a/libs/quasselc/Makefile b/libs/quasselc/Makefile
deleted file mode 100644 (file)
index 7fd7295..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# 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))
diff --git a/libs/quasselc/patches/001-respect-cflags-ldflags.patch b/libs/quasselc/patches/001-respect-cflags-ldflags.patch
deleted file mode 100644 (file)
index e5c8f61..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
---- 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
index f2600432f5bf90eb4e05310352f666b7b3d42b37..c45b69183c27634c6c432d957d784e16caba8af9 100644 (file)
@@ -8,22 +8,27 @@
 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
@@ -35,91 +40,145 @@ include $(INCLUDE_DIR)/host-build.mk
 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/
@@ -127,34 +186,34 @@ endef
 
 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))
diff --git a/libs/unixodbc/files/pgsqlodbc.ini b/libs/unixodbc/files/pgsqlodbc.ini
new file mode 100644 (file)
index 0000000..54a64bc
--- /dev/null
@@ -0,0 +1,3 @@
+[PostgreSQL]
+Description = unixODBC PostgreSQL driver
+Driver = /usr/lib/libodbcpsql.so
diff --git a/libs/unixodbc/files/unixodbc_conf.h b/libs/unixodbc/files/unixodbc_conf.h
deleted file mode 100644 (file)
index f149d02..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-@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
diff --git a/libs/unixodbc/patches/100-cross-compile-odbc-config.patch b/libs/unixodbc/patches/100-cross-compile-odbc-config.patch
deleted file mode 100644 (file)
index 4b952ae..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
---- 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 )
diff --git a/libs/unixodbc/test.sh b/libs/unixodbc/test.sh
new file mode 100644 (file)
index 0000000..d4c42a4
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$1" = unixodbc-tools ] || exit 0
+
+isql --version | grep -Fx "unixODBC $PKG_VERSION"
index 49e43a3e34950ab41968b5825617c2f414b2e31e..0ea2071d56a09296f025d02e2643d6066b9e7b28 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -42,22 +42,15 @@ define Package/xmlrpc-c-internal
   $(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
 
@@ -76,7 +69,7 @@ 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
@@ -101,11 +94,10 @@ Package/xmlrpc-c-internal/description += Uses internal expat variant (stripped d
 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 += \
@@ -118,7 +110,7 @@ ifeq ($(BUILD_VARIANT),internal)
 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
 
@@ -208,15 +200,10 @@ define Package/xmlrpc-c-common/install
                $(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))
diff --git a/libs/xmlrpc-c/patches/001-fix-format-parameter.patch b/libs/xmlrpc-c/patches/001-fix-format-parameter.patch
new file mode 100644 (file)
index 0000000..2986a96
--- /dev/null
@@ -0,0 +1,11 @@
+--- 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);
+         }
+     }
diff --git a/libs/xmlrpc-c/patches/002-remove-unnecessary-linking.patch b/libs/xmlrpc-c/patches/002-remove-unnecessary-linking.patch
new file mode 100644 (file)
index 0000000..0e21dcf
--- /dev/null
@@ -0,0 +1,37 @@
+--- 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 = \
index 69d200bf1ebf227599110c305c08884486f94dd0..ebc17dcecb52ae3b9eb2746af80d2eebec05e5b5 100644 (file)
@@ -1,12 +1,12 @@
 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
index e5efd5e5666772f48c746e75619e7f439e4d4eeb..115201c05ac667d960f690b1b695e10deb710610 100644 (file)
@@ -287,7 +287,7 @@ Last-Update: 2021-07-28
  #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)
@@ -295,7 +295,7 @@ Last-Update: 2021-07-28
  /*************************************************
  *            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);
  }
index 762fd933c45c02a812ee7b7724f47807e0f45815..522765db8b716031cf20fb8f3983dd9bb39a0dfa 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -30,7 +30,7 @@ define Package/fdm
   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
 
@@ -42,7 +42,7 @@ define Package/fdm/description
 endef
 
 ifdef CONFIG_FDM_WITH_PCRE
-       CONFIGURE_ARGS += --enable-pcre
+       CONFIGURE_ARGS += --enable-pcre2
 endif
 
 define Package/fdm/config
diff --git a/mail/fdm/patches/010-ntop-fix.patch b/mail/fdm/patches/010-ntop-fix.patch
deleted file mode 100644 (file)
index e324795..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
---- 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
diff --git a/mail/fdm/patches/020-Fix-compile-with-OpenSSL-1.1.0.patch b/mail/fdm/patches/020-Fix-compile-with-OpenSSL-1.1.0.patch
deleted file mode 100644 (file)
index 3d2f45d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-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);
diff --git a/mail/fdm/patches/030-cdefs.patch b/mail/fdm/patches/030-cdefs.patch
deleted file mode 100644 (file)
index d1ae7af..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-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 */
diff --git a/mail/fdm/patches/100-Fix-bugs-in-PCRE2-code-don-t-walk-off-the-end-of-the.patch b/mail/fdm/patches/100-Fix-bugs-in-PCRE2-code-don-t-walk-off-the-end-of-the.patch
new file mode 100644 (file)
index 0000000..8c63f96
--- /dev/null
@@ -0,0 +1,75 @@
+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
diff --git a/mail/fdm/patches/101-Fix-use-after-free-GitHub-issue-126.patch b/mail/fdm/patches/101-Fix-use-after-free-GitHub-issue-126.patch
new file mode 100644 (file)
index 0000000..98024d2
--- /dev/null
@@ -0,0 +1,21 @@
+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;
index b86fdcb6d7998fa0622422c37d15f71d8d32e3a5..5fbecf1258d358f3d043de7b704a99bdbdde0c43 100644 (file)
@@ -8,14 +8,14 @@
 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
@@ -44,7 +44,7 @@ define Package/postfix
        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
 
@@ -172,8 +172,8 @@ ifdef CONFIG_POSTFIX_PGSQL
 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
index c3201097ad41450aa450df41c322eedee166f911..28754e1a4aec38b38fd93a320c60d03af31facc4 100644 (file)
@@ -44,7 +44,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
  #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
@@ -53,7 +53,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
  
  #endif
  
-@@ -1563,7 +1563,7 @@ typedef int pid_t;
+@@ -1573,7 +1573,7 @@ typedef int pid_t;
  
   /*
    * Clang-style attribute tests.
@@ -62,7 +62,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
    * 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.
@@ -71,7 +71,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
    * 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).
@@ -86,7 +86,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
    * 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.
index 1ae9359fbbeb21ac8c7a31fd57dd514eae83f850..fdd01706f241da630b78a0633ce78b420c4bbb7f 100644 (file)
@@ -1,6 +1,6 @@
 --- 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");
@@ -9,5 +9,5 @@
 +//    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)
index 074d03095de80e7a39ff48f7e185a85d1d722156..3afcf19dcb7f62edc3eccc4e5e2ddf6185b50f4b 100644 (file)
@@ -1,6 +1,6 @@
 --- 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
index c7448a3a1a3b7a36737eaa780bd1a63aec52447e..329436ce692c25d6a3977395add9b2075bc36b17 100644 (file)
@@ -1,6 +1,6 @@
 --- a/makedefs
 +++ b/makedefs
-@@ -215,7 +215,7 @@ error() {
+@@ -233,7 +233,7 @@ ARFL=rv
  
  case $# in
   # Officially supported usage.
@@ -9,7 +9,7 @@
      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
index 84ad04a835e64214cafbe017248802b1a9735157..7681a54c100618326171cff3c77ff590142cbb1e 100644 (file)
@@ -1,6 +1,6 @@
 --- 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>
diff --git a/mail/postfix/patches/502-detect-glibc.patch b/mail/postfix/patches/502-detect-glibc.patch
deleted file mode 100644 (file)
index abfc9d4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- 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
index c779d12ed9a8772daec72dc871ad8f404efae7cc..d601ad7fb8e6f3c8831bb84ee761c1c099a5659e 100644 (file)
@@ -1,6 +1,6 @@
 --- 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
  
@@ -44,7 +44,7 @@
  # 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
  
index 8237ca1c229ccd593e6fc370b0258efe31fba20c..9ef7ce8ad7cf93950f050ed6d018bc8882234168 100644 (file)
@@ -8,12 +8,12 @@
 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> \
index b5dad4177f503517200b16e332befe5f0f146fa4..0f999a3738f4e942b6affd0af56ec5680959acd5 100644 (file)
@@ -8,12 +8,12 @@
 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> \
index 952d52577e13b52b5f94f3be3ce248d3a7f6d5ca..856692f1f3840ab11d515181cf94a4ca36c5a233 100644 (file)
@@ -1,6 +1,6 @@
 --- 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')
  
index 24907d141e91189fdd3e94ddc4cd0d392624aad3..cbfa51c88236327e818538cdefb867390981ed61 100644 (file)
@@ -8,12 +8,12 @@
 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> \
index 3b3853c82cbd45c924e6fadf4e24c73f05002fd4..174e8eecd18a67a0a5c6bbec5e6c7b62ca8be871 100644 (file)
@@ -8,12 +8,12 @@
 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> \
index 582df3b628156b4b4021ec5acd98faac42bfc617..a0e6365ffef0c2477321433bdad565ea5022b745 100644 (file)
@@ -1,6 +1,6 @@
 --- 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')
  
index 572adda1eb34ba33fa68b6e64cab9965672c37f4..3da36b89715b9d73146cf74139d1d5a65ad3e7fa 100644 (file)
@@ -8,12 +8,12 @@
 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> \
index 81653efacf9727c6b36d5b2e57f14e75b50df479..de77412e0a250d499c4ad45679b2fc63a3f2b26d 100644 (file)
@@ -8,12 +8,12 @@
 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> \
index de689fd330e45a966d698f22ddb1cb7b16598de8..b750bd9eb4f5a3473d78c6cc5108bde3fef1a601 100644 (file)
@@ -36,11 +36,6 @@ choice
     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
index f33b666624215f73f7c1aa9b5db76a91ecbacdcc..674d2862a5cdc578bd0971a6766673cf3c31d78a 100644 (file)
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
 
 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
@@ -36,7 +36,6 @@ define Package/tvheadend
        $(ICONV_DEPENDS) \
        +zlib \
        +TVHEADEND_AVAHI_SUPPORT:libavahi-client \
-       +TVHEADEND_REGEX_PCRE:libpcre \
        +TVHEADEND_REGEX_PCRE2:libpcre2 \
        +BUILD_PATENTED&&TVHEADEND_CSA:libdvbcsa
 
@@ -77,15 +76,12 @@ ifeq ($(CONFIG_TVHEADEND_TRACE),)
        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
 
index 7ec1274161d5fa894f979817627583a05ed8a4f6..145a0d37eb4c4674cf1d8cc3494b3926ec3cddac 100644 (file)
@@ -1,11 +1,11 @@
 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
index 6131a4a07a3726ef462319fac68eb5801754785d..d556c4baca92f4ae04c26af23b2c56359b2d82bb 100644 (file)
@@ -1,18 +1,19 @@
 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
index a97326f3470a6a2cc7bdbca16c269e70a62104b2..efbed1852560a26c7d1c79945b3ff9c11a48b7a9 100644 (file)
@@ -8,12 +8,12 @@
 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>
index f923a27b4717f706796422fc25ee7734f12ce541..49defa013a9bf60c8b909149cc6dbfae6dc5d859 100644 (file)
@@ -1,12 +1,12 @@
-# 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
 
@@ -28,7 +28,7 @@ define Package/adblock-fast
 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
index f459411f03fd5a7bc2725aeaf6f7e39b088dbf0b..68a6392ff4ec90e8975aaf4857a113143bd0d783 100644 (file)
@@ -7,7 +7,7 @@ config adblock-fast 'config'
        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'
@@ -29,7 +29,9 @@ config adblock-fast 'config'
 #      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'
 
index 8229f0845d7ee53acc64ee4121f30393d399c5ae..a94b65415878841d477e1cc25c4ae269b1731b84 100755 (executable)
@@ -1,6 +1,6 @@
 #!/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
@@ -8,25 +8,6 @@ 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"
@@ -53,12 +34,28 @@ readonly dnsmasqServersFile="/var/run/${packageName}/dnsmasq.servers"
 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;'
@@ -67,11 +64,11 @@ readonly adBlockPlusFilter='/^#/d;/^!/d;s/[[:space:]]*#.*$//;s/^||//;s/\^$//;s/[
 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)"
@@ -93,7 +90,246 @@ load_environment_flag=
 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"
@@ -107,15 +343,35 @@ uci_add_list_if_new() {
        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
@@ -154,6 +410,7 @@ get_text() {
                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";;
@@ -162,61 +419,23 @@ get_text() {
                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
@@ -237,8 +456,7 @@ load_network() {
        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
@@ -252,14 +470,14 @@ load_network() {
                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
@@ -271,37 +489,23 @@ append_url() {
        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
@@ -310,32 +514,34 @@ load_environment() {
        [ -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
                        ;;
@@ -343,27 +549,31 @@ load_environment() {
        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'
@@ -372,19 +582,37 @@ load_environment() {
                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
@@ -393,6 +621,7 @@ load_environment() {
                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
 
@@ -402,39 +631,24 @@ load_environment() {
                        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"
@@ -442,40 +656,57 @@ load_environment() {
                        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
@@ -484,15 +715,15 @@ load_environment() {
        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="$gawk"
-                       is_present '/usr/libexec/grep-gnu' || s="$grep"
-                       is_present '/usr/libexec/sed-gnu' || s="$sed"
-                       is_present '/usr/libexec/sort-coreutils' || 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.
@@ -543,144 +774,190 @@ load_environment() {
        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"
@@ -689,88 +966,6 @@ dns() {
        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
@@ -812,9 +1007,9 @@ cache() {
        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
@@ -847,7 +1042,7 @@ process_file_url() {
                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"
@@ -862,9 +1057,10 @@ process_file_url() {
                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
@@ -890,6 +1086,7 @@ process_file_url() {
                        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"
@@ -900,21 +1097,19 @@ process_file_url() {
 }
 
 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'
@@ -929,35 +1124,65 @@ download_dnsmasq_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'
 
@@ -968,37 +1193,44 @@ download_lists() {
                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
 
@@ -1006,11 +1238,15 @@ $(cat $A_TMP)"
                 [ "$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
@@ -1019,49 +1255,49 @@ $(cat $A_TMP)"
                                                        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
@@ -1071,7 +1307,7 @@ $(cat $A_TMP)"
                                        output_ok
                                else
                                        output_failn
-                                       json add error "errorDataFileFormatting"
+                                       json add error 'errorDataFileFormatting'
                                fi
                        ;;
                esac
@@ -1080,27 +1316,39 @@ $(cat $A_TMP)"
        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
 
@@ -1108,28 +1356,28 @@ $(cat $A_TMP)"
                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'
 }
@@ -1149,13 +1397,13 @@ adb_allow() {
                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
@@ -1171,7 +1419,7 @@ adb_allow() {
                                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})"
@@ -1191,12 +1439,46 @@ adb_allow() {
                                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
@@ -1212,7 +1494,7 @@ adb_allow() {
                                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})"
@@ -1257,6 +1539,8 @@ adb_check() {
                                                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
@@ -1267,6 +1551,54 @@ adb_check() {
        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"
@@ -1277,7 +1609,7 @@ adb_config_update() {
        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 
@@ -1288,9 +1620,10 @@ adb_config_update() {
                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"
@@ -1298,33 +1631,32 @@ adb_config_update() {
                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
@@ -1357,7 +1689,7 @@ adb_start() {
        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'
@@ -1369,7 +1701,7 @@ adb_start() {
        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.'
@@ -1377,7 +1709,7 @@ adb_start() {
                                output_okn
                        else
                                output_failn
-                               json add error "errorRestoreCompressedCache"
+                               json add error 'errorRestoreCompressedCache'
                                output "${_ERROR_}: $(get_text 'errorRestoreCompressedCache')!\\n"
                                action='download'
                        fi
@@ -1387,10 +1719,10 @@ adb_start() {
                        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
@@ -1398,50 +1730,52 @@ adb_start() {
        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'
@@ -1458,7 +1792,8 @@ adb_start() {
                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 ""
@@ -1484,7 +1819,7 @@ adb_start() {
                done
        fi
        case "$dns" in
-               dnsmasq.ipset)
+               dnsmasq.ipset|smartdns.ipset)
                        json_add_object ""
                        json_add_string type ipset
                        json_add_string name adb
@@ -1500,7 +1835,7 @@ adb_start() {
                        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
@@ -1515,7 +1850,7 @@ adb_start() {
                        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
@@ -1540,12 +1875,12 @@ adb_start() {
 }
 
 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;
@@ -1554,19 +1889,20 @@ adb_status() {
                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
@@ -1579,19 +1915,19 @@ adb_stop() {
        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
@@ -1603,7 +1939,7 @@ adb_pause() {
        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
@@ -1613,10 +1949,16 @@ adb_pause() {
 
 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
@@ -1634,26 +1976,26 @@ killcache() {
        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
@@ -1667,7 +2009,7 @@ start_service() {
        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"; }
@@ -1681,8 +2023,6 @@ load_validate_file_url_section() {
 }
 
 load_validate_config() {
-       . /lib/functions/network.sh
-       . /usr/share/libubox/jshn.sh
        local enabled
        local force_dns
        local force_dns_port
@@ -1723,9 +2063,9 @@ load_validate_config() {
                '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' \
@@ -1733,8 +2073,9 @@ load_validate_config() {
                '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'
index 5366b46e64c055079cd771d4b68a3a27e7bf0173..d1655503ad294cb3db5f5cda2205ee90988a1de6 100644 (file)
@@ -1,51 +1,14 @@
 #!/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() {
@@ -54,7 +17,7 @@ _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
 }
 
@@ -63,32 +26,32 @@ enable_add_url() {
        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
@@ -100,31 +63,30 @@ if [ -s '/etc/config/simple-adblock' ] \
                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
@@ -133,7 +95,7 @@ if [ -s '/etc/config/simple-adblock' ] \
                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' \
index ada453c8565a26564954801c895c00bce0c484d2..38a97c5cf33ae97e5d1b22ad324e806f37ae5247 100644 (file)
@@ -6,13 +6,13 @@
 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
diff --git a/net/adguardhome/patches/0001-go-get-github.com-quic-go-quic-go-v0.37.6.patch b/net/adguardhome/patches/0001-go-get-github.com-quic-go-quic-go-v0.37.6.patch
deleted file mode 100644 (file)
index c158b23..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-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=
index 70a13a0d4633f4bcfad3a01d2aa6fbb11f784254..ae5d9d66f715552c5e54acf87090c3e2d9de362c 100644 (file)
@@ -83,6 +83,7 @@ CONFIGURE_ARGS += \
        --with-libpcap-include=$(STAGING_DIR)/usr/include \
        --with-libpcap-lib=$(STAGING_DIR)/usr/lib \
        --without-opt \
+       --with-libbsd=no \
        \
        PYTHON=$(PYTHON) \
        \
diff --git a/net/aircrack-ng/patches/104-build-add-option-to-disable-bsd-library-inclusion.patch b/net/aircrack-ng/patches/104-build-add-option-to-disable-bsd-library-inclusion.patch
new file mode 100644 (file)
index 0000000..e575706
--- /dev/null
@@ -0,0 +1,58 @@
+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
diff --git a/net/aircrack-ng/patches/105-build-support-strlcat-strlcpy-from-musl-or-recent-gl.patch b/net/aircrack-ng/patches/105-build-support-strlcat-strlcpy-from-musl-or-recent-gl.patch
new file mode 100644 (file)
index 0000000..7eacd43
--- /dev/null
@@ -0,0 +1,30 @@
+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
index b2f5372752ddffd82c8c787e5c2614f3a65d9d22..244df968493ab1a362dc6d9522fc76faadd304c4 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 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
index 7a287c03b5d51b084524029b6eef447844bad990..745ba6b633dd1cc1abb1c8e6d9fd8cc131b830e1 100644 (file)
@@ -54,10 +54,15 @@ append_target() {
        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}\"}
@@ -115,7 +120,7 @@ append_alarm_loss() {
        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
@@ -132,9 +137,9 @@ init_apinger_config() {
        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
 
index 0be6e1657226b671dbe66c3705d3573904e80330..360d473e27f5d70e15da621b3c015738270369eb 100644 (file)
@@ -38,7 +38,7 @@ apinger_status() {
                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"
index af441bf52678ff328443cdc18507411d1db9fa9a..6aee1cc9c44ddb81c757d7406dcbf2ae2c13c9a5 100644 (file)
@@ -7,12 +7,12 @@
 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
index 4787a0e0baedbe3c4455324d138906f39202c40f..3c36b489b619f4cd8d4baadaf2792fa53aea880b 100644 (file)
@@ -1,12 +1,12 @@
 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>
@@ -56,6 +56,8 @@ define Package/ariang/install
                $(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
 
index 0c9f4460fac0610db0ecbd56d7d263ea359d0f90..00803da00cd43705fb7d6e9ffec08343c8bb6fce 100644 (file)
@@ -5,7 +5,7 @@
 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>
@@ -16,7 +16,7 @@ define Package/banip
        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
 
@@ -63,6 +63,9 @@ define Package/banip/install
        $(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))
index d65e6e391f6880fad8099cb279f26e282bc7c904..299a2cae8ee2611fad28bc6bd2f617a92d9882fb 100644 (file)
@@ -89,9 +89,10 @@ IP address blocking is commonly used to protect against brute force attacks, pre
 * 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
@@ -134,62 +135,65 @@ Available commands:
 
 ## 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**  
@@ -291,6 +295,7 @@ list ban_logterm 'luci: failed login'
 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**  
@@ -323,6 +328,18 @@ MAC-address with IPv4 and IPv6 wildcard concatenation:
 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.
index c0c4ea95958b158b4ecb3154b5eecc23d5bd6c6d..f075eb6b1385ed5e29c63a6cfb34e0fe7e1e50e5 100644 (file)
@@ -23,7 +23,8 @@ ban_rtfile="/var/run/banip_runtime.json"
 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)"
@@ -42,6 +43,8 @@ ban_mailtopic="banIP notification"
 ban_mailprofile="ban_notify"
 ban_mailnotification="0"
 ban_reportelements="1"
+ban_remotelog="0"
+ban_remotetoken=""
 ban_nftloglevel="warn"
 ban_nftpriority="-200"
 ban_nftpolicy="memory"
@@ -188,10 +191,15 @@ f_rmpid() {
        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}"
 }
@@ -283,19 +291,25 @@ f_conf() {
                }
        }
        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")"
@@ -662,8 +676,8 @@ f_down() {
 
        # 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
@@ -685,16 +699,21 @@ f_down() {
                        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="${?}"
@@ -702,8 +721,15 @@ f_down() {
                                "${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
@@ -968,7 +994,11 @@ f_down() {
        # 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="${?}"
@@ -1086,7 +1116,7 @@ f_genstatus() {
                                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"
@@ -1471,12 +1501,20 @@ f_mail() {
 # 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=""
@@ -1490,9 +1528,9 @@ f_monitor() {
                                        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
diff --git a/net/banip/files/banip.cgi b/net/banip/files/banip.cgi
new file mode 100644 (file)
index 0000000..2ac5ef0
--- /dev/null
@@ -0,0 +1,36 @@
+#!/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
index eaa30989eaa38a6ef47d968bc9ab4dc4823c0c5c..3bb5bc96c710e3b8437f06aa92c864f3bbfd46bf 100644 (file)
@@ -7,3 +7,4 @@ config banip 'global'
        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 '\''.*'\'''
index cfe1a70cc690f4ed7f89433f4def2ec9226b5dfc..1adb11eb59adb6f481e10dd1dcb26a24469938ad 100644 (file)
        },
        "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":{
index a934b4a9196708cebca58da85abebd74c800dad8..4ef70e3d0c0071a83194b403f9fd01b53b223cb7 100755 (executable)
@@ -22,6 +22,7 @@ ban_lock="/var/run/banip.lock"
 
 [ "${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}"
 
@@ -31,8 +32,8 @@ boot() {
 }
 
 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}"}"
@@ -43,7 +44,6 @@ start_service() {
                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
index 245f595c337705bcf2c29df4fd470b1cccf12d4f..d9927734435f7aff2c9b121565f2a3ee0458e02e 100644 (file)
@@ -5,13 +5,13 @@
 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
diff --git a/net/cni-protocol/Makefile b/net/cni-protocol/Makefile
deleted file mode 100644 (file)
index 3711452..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-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))
diff --git a/net/cni-protocol/files/cni.sh b/net/cni-protocol/files/cni.sh
deleted file mode 100755 (executable)
index 73a3711..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/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
-}
index 9c063d84c6743526da848a7c441f54012f41b802..4a415e8c0279e6cd01f8ec70190a1e61964cf422 100644 (file)
@@ -8,12 +8,12 @@
 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
index eab3c8e70f5626d29d4db1713962dcee3f7250d0..c1c57904f71b124bb8b9a6fb7e6b5583be9ae426 100644 (file)
@@ -5,12 +5,12 @@
 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
index ee8c732233600be7b4580efe09b0da62e3f8f27c..3f1464099bb19b0b040323e1b332b5b0f9db8313 100644 (file)
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 
 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)?
index 04acd16173c8a0a251bd0f29231008fc0365c18d..eb5b79b7b08fb4ab0715b08b4754d63baa3b5980 100755 (executable)
@@ -210,6 +210,13 @@ run_bouncer() {
                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
 }
index 554669592bdc8fa2c1601b54ee0dde0a47e21601..48a0ac9e9bf27d1a962ea9bb8dc043497f7c95ff 100644 (file)
@@ -6,12 +6,12 @@
 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
index 24b7b9627188437e986c3015765c7e369019fe2c..29865a87a7afd51e22125dc96f47766ee88f9c71 100644 (file)
@@ -105,6 +105,16 @@ config LIBCURL_NGHTTP2
        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
index b1d69930ad0a7d4b03956973bb81772ad7ed2922..c41e9ee57a5fd7d54bfd859d01ae9f335b91edda 100644 (file)
@@ -9,15 +9,15 @@ include $(TOPDIR)/rules.mk
 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
@@ -58,6 +58,8 @@ PKG_CONFIG_DEPENDS:= \
   CONFIG_LIBCURL_TELNET \
   CONFIG_LIBCURL_TFTP \
   CONFIG_LIBCURL_NGHTTP2 \
+  CONFIG_LIBCURL_NGHTTP3 \
+  CONFIG_LIBCURL_NGTCP2 \
   \
   CONFIG_LIBCURL_COOKIES \
   CONFIG_LIBCURL_CRYPTO_AUTH \
@@ -95,7 +97,7 @@ define Package/libcurl
   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
@@ -135,6 +137,8 @@ CONFIGURE_ARGS += \
        $(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) \
index d3a5cca61380f475a0c193552842c231343c3469..38f323e26b59e42f59b9a6afab3e45de65a91091 100644 (file)
@@ -1,6 +1,6 @@
 --- 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
@@ -9,7 +9,7 @@
  
  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)
index e37da9a746fade88b7c0254e70eaa614a5a3e88d..607152a1c7d863297a56575751b5958d39960926 100644 (file)
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ddns-scripts
 PKG_VERSION:=2.8.2
-PKG_RELEASE:=40
+PKG_RELEASE:=42
 
 PKG_LICENSE:=GPL-2.0
 
index 499f272031600aeea61ab2b184f860dba4188cdb..0d474051eed323380031de020d8cf33bfd4723b7 100644 (file)
 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/"
 
diff --git a/net/ddns-scripts/files/usr/share/ddns/default/ipnodns.ru.json b/net/ddns-scripts/files/usr/share/ddns/default/ipnodns.ru.json
new file mode 100644 (file)
index 0000000..026caa1
--- /dev/null
@@ -0,0 +1,7 @@
+{
+       "name": "ipnodns.ru",
+       "ipv4": {
+               "url": "https://ipnodns.ru/cgi-bin/dyndns.cgi?login=[USERNAME]&secret=[PASSWORD]",
+               "answer": "ok"
+       }
+}
index 86902313a0648a9c64ae57eb28c5fb00924926c7..88d369c9c16cfbe17464d390b2a7c09027a55dc0 100644 (file)
@@ -34,6 +34,7 @@ google.com
 he.net
 hosting.de
 infomaniak.com
+ipnodns.ru
 inwx.de
 joker.com
 loopia.se
diff --git a/net/dhtd/Makefile b/net/dhtd/Makefile
new file mode 100644 (file)
index 0000000..75609b0
--- /dev/null
@@ -0,0 +1,44 @@
+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))
diff --git a/net/dhtd/files/dhtd.config b/net/dhtd/files/dhtd.config
new file mode 100644 (file)
index 0000000..e933e65
--- /dev/null
@@ -0,0 +1,34 @@
+##
+## 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'
diff --git a/net/dhtd/files/dhtd.init b/net/dhtd/files/dhtd.init
new file mode 100755 (executable)
index 0000000..a3b1552
--- /dev/null
@@ -0,0 +1,116 @@
+#!/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'
+}
index 50b0cfacb5ddf418ebca103efd6abf7cffde0277..34b12e12e89939aaa827dd4f7402ae6b383a03be 100644 (file)
@@ -1,12 +1,12 @@
 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
index 20d25d60f0b01e032cd43c4ae7ba2c3a5c4615dc..6ac9079818a67958f76d115b2b8d3a7294b29303 100644 (file)
@@ -5,12 +5,12 @@
 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
@@ -49,6 +49,8 @@ define Package/dnsproxy/install
        $(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
index a9fa020280804e2432b7983aadadd061fde4a292..90feb94d468b5904bd8949523828cf666d1c9ed3 100644 (file)
@@ -3,13 +3,16 @@
 
 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'
diff --git a/net/dnsproxy/files/dnsproxy.defaults b/net/dnsproxy/files/dnsproxy.defaults
new file mode 100644 (file)
index 0000000..7ce089f
--- /dev/null
@@ -0,0 +1,8 @@
+#!/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
index 1514ee152630b558ec470e66460597ebffda0da0..fc04ac9a6828ca29e50944d6a14a6bfcdeb59b64 100644 (file)
@@ -44,6 +44,7 @@ append_param_bool() {
 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"
@@ -51,6 +52,18 @@ load_config_arg() {
 }
 
 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
@@ -59,9 +72,8 @@ load_config_list() {
 }
 
 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"
diff --git a/net/external-protocol/Makefile b/net/external-protocol/Makefile
new file mode 100644 (file)
index 0000000..2123060
--- /dev/null
@@ -0,0 +1,87 @@
+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))
diff --git a/net/external-protocol/files/external.sh b/net/external-protocol/files/external.sh
new file mode 100755 (executable)
index 0000000..5326159
--- /dev/null
@@ -0,0 +1,141 @@
+#!/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
+}
index 77568e908353674fca8d246125d6ba65b97f53c7..fba0a11df237fc4e5f0b2f7b73105ec4fd0be98b 100644 (file)
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 
 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)?
diff --git a/net/fail2ban/patches/101-move-global-groups-to-start-of-expression-python-3.11-compat.patch b/net/fail2ban/patches/101-move-global-groups-to-start-of-expression-python-3.11-compat.patch
new file mode 100644 (file)
index 0000000..bd50c17
--- /dev/null
@@ -0,0 +1,44 @@
+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
diff --git a/net/fail2ban/patches/102-wrap-global-flags-to-local-flags-if-supported-by-RE-engine-in-the-python-version.patch b/net/fail2ban/patches/102-wrap-global-flags-to-local-flags-if-supported-by-RE-engine-in-the-python-version.patch
new file mode 100644 (file)
index 0000000..5a677c1
--- /dev/null
@@ -0,0 +1,36 @@
+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
index d908ed81524fe6a00becfed0fa97003716710f01..62d7f0b5bbc4a3c6c184037bc3eeffe7253255e6 100644 (file)
@@ -8,19 +8,19 @@
 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
 
@@ -63,7 +63,7 @@ endef
 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
@@ -131,16 +131,11 @@ define Package/freeradius3-mod-attr-filter/conffiles
 /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
@@ -152,6 +147,26 @@ define Package/freeradius3-mod-chap/conffiles
 /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
@@ -174,6 +189,17 @@ define Package/freeradius3-mod-digest/conffiles
 /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
@@ -188,6 +214,12 @@ define Package/freeradius3-mod-eap/conffiles
 /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
@@ -277,6 +309,26 @@ define Package/freeradius3-mod-files/conffiles
 /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
@@ -287,6 +339,16 @@ define Package/freeradius3-mod-ldap/conffiles
 /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
@@ -309,6 +371,16 @@ define Package/freeradius3-mod-mschap/conffiles
 /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
@@ -378,6 +450,36 @@ define Package/freeradius3-mod-realm/conffiles
 /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
@@ -388,6 +490,27 @@ define Package/freeradius3-mod-rest/conffiles
 /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
@@ -398,6 +521,16 @@ define Package/freeradius3-mod-sql/conffiles
 /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
@@ -437,7 +570,7 @@ endef
 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
@@ -469,6 +602,46 @@ define Package/freeradius3-mod-unix/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
@@ -498,36 +671,21 @@ CONFIGURE_ARGS+= \
        --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
 
@@ -535,10 +693,20 @@ PKG_DICTIONARIES:= \
        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 \
@@ -579,6 +747,14 @@ else
   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" \
@@ -602,6 +778,24 @@ else
   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
@@ -652,6 +846,15 @@ 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
@@ -763,9 +966,13 @@ $(eval $(call BuildPackage,freeradius3-democerts))
 $(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,))
@@ -777,17 +984,27 @@ $(eval $(call BuildPlugin,freeradius3-mod-exec,rlm_exec,))
 $(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,))
@@ -795,4 +1012,8 @@ $(eval $(call BuildPlugin,freeradius3-mod-sql-sqlite,rlm_sql_sqlite,))
 $(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))
diff --git a/net/freeradius3/patches/020-fix-freeradius3-krb5.patch b/net/freeradius3/patches/020-fix-freeradius3-krb5.patch
new file mode 100644 (file)
index 0000000..0512b30
--- /dev/null
@@ -0,0 +1,6635 @@
+--- 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
index b193a049259444cbd21cfedd9f05d4d72937bd92..98b429d0df97d7396f409d3f7a12133beb86599b 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -39,15 +39,28 @@ include $(INCLUDE_DIR)/package.mk
 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 += \
@@ -64,6 +77,9 @@ 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 \
@@ -161,8 +177,9 @@ endef
 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),)
@@ -173,8 +190,11 @@ endif
 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
@@ -200,7 +220,7 @@ endef
 
 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))
diff --git a/net/gensio/patches/0001-Ensure-that-ax_python_devel_found-is-defined.patch b/net/gensio/patches/0001-Ensure-that-ax_python_devel_found-is-defined.patch
new file mode 100644 (file)
index 0000000..a21d516
--- /dev/null
@@ -0,0 +1,30 @@
+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],
diff --git a/net/gensio/patches/0002_ax_python_devel-fix-serial.patch b/net/gensio/patches/0002_ax_python_devel-fix-serial.patch
new file mode 100644 (file)
index 0000000..211f692
--- /dev/null
@@ -0,0 +1,11 @@
+--- 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],[
diff --git a/net/gensio/patches/0003-Revert-ax_pkg_swig.m4-to-latest-vanilla-version.patch b/net/gensio/patches/0003-Revert-ax_pkg_swig.m4-to-latest-vanilla-version.patch
new file mode 100644 (file)
index 0000000..fb13df9
--- /dev/null
@@ -0,0 +1,144 @@
+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])
diff --git a/net/gensio/patches/100-musl-compat.patch b/net/gensio/patches/100-musl-compat.patch
deleted file mode 100644 (file)
index da61fe7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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
index 9f57f746b773e76a87939a106471d48a91eeacd4..4cc22bd92b5816428826755875b9e68f4bd5e92e 100644 (file)
 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>
@@ -46,7 +46,7 @@ endef
 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
 
@@ -59,7 +59,7 @@ define Package/haproxy-nossl
   $(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
 
@@ -92,7 +92,7 @@ define Build/Compile
                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) \
index 8f4d9e0aff712cf644932c800781963a1340d8e5..97665fc03089d750a3c3045a81f709c33fbb65ce 100755 (executable)
@@ -1,7 +1,7 @@
 #!/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
 
index 022f03c52ae6d8ecfca5b3b82f661a1bf358ef0f..c05bd5fda2de5e523c0ed38049d5c9915f64fb4b 100644 (file)
@@ -8,12 +8,12 @@
 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
diff --git a/net/hcxdumptool/patches/010-openssl.patch b/net/hcxdumptool/patches/010-openssl.patch
deleted file mode 100644 (file)
index 6e2b04f..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
---- 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;
index 36e7d95013e397183fd26aed7816707a6884b534..c829806e9d52cb67cbb957b1b1163d84b3379da3 100644 (file)
@@ -8,18 +8,19 @@
 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
@@ -35,27 +36,17 @@ define Package/hcxtools/description
   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))
diff --git a/net/hcxtools/patches/010-openssl.patch b/net/hcxtools/patches/010-openssl.patch
deleted file mode 100644 (file)
index 9122368..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
---- 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;
- }
- /*===========================================================================*/
index 88b75774942de3ed206b0c4166e21590aa8389b0..d290ef7b5f5fb42757f96aa8a185373abcd640d9 100644 (file)
@@ -1,14 +1,15 @@
 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
@@ -24,6 +25,8 @@ define Package/https-dns-proxy
        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
 
@@ -45,8 +48,6 @@ define Package/https-dns-proxy/install
        $(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
diff --git a/net/https-dns-proxy/files/etc/hotplug.d/iface/90-https-dns-proxy b/net/https-dns-proxy/files/etc/hotplug.d/iface/90-https-dns-proxy
deleted file mode 100644 (file)
index 5acf7b7..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/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'
index 6529bf3e32653feebf9fba2ef26ab55e624f4c97..0a11111c5705a8b58d2af04dc2703230a15d04a5 100755 (executable)
@@ -5,6 +5,8 @@
 # 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
@@ -26,10 +28,14 @@ readonly DEFAULT_BOOTSTRAP="${BOOTSTRAP_CF},${BOOTSTRAP_GOOGLE}"
 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"
@@ -48,6 +54,7 @@ output_ok() { output "$_OK_"; }
 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"
@@ -66,9 +73,6 @@ uci_changes() {
        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"; }
@@ -127,12 +131,11 @@ append_bootstrap() {
        [ "$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() {
@@ -166,7 +169,7 @@ 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
@@ -198,7 +201,8 @@ start_instance() {
        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
@@ -215,7 +219,7 @@ start_instance() {
                fi
                output_ok
                port="$((port+1))"
-               force_dns=0
+               force_dns='0'
        else
                output_fail
        fi
@@ -250,20 +254,21 @@ start_service() {
                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() {
@@ -291,29 +296,32 @@ 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
@@ -332,7 +340,7 @@ dnsmasq_doh_server() {
                        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
index cd60c6dc017699b2829dbcd462153640c6620a59..6af8d7ce9653216f2eb5edbbce5eb66dad565a7a 100644 (file)
@@ -5,10 +5,10 @@
  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
index 8bb2d93614939c5d1543db444556241e0623a033..993a9b8d32dc2d5dc859a28d66d2ce0f7a3597c5 100644 (file)
@@ -1,11 +1,11 @@
 --- 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
  }
  
index fa41fd54535f3966e20c6e5dd8fe3abb7b6cf631..41d8cb7e2ff66376101fc397453b35be95cd6888 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -45,7 +45,8 @@ define Package/iperf3-ssl
 $(call Package/iperf3/default)
   TITLE+= with iperf_auth support
   VARIANT:=ssl
-  DEPENDS:=+libopenssl
+  DEPENDS:=+libopenssl +libatomic
+  CONFLICTS:=iperf3
 endef
 
 define Package/libiperf3
@@ -53,9 +54,11 @@ 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
index d7c4a156614bb375276aa15fb0a7f73447b49424..81fd97681b2de56064358365ed94b75a5b057c70 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 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
index 967ba83da25e22153c4fb22a21a19c6c54fa1393..927924dbc69ac2cc0d06f0febefa045654fdd518 100755 (executable)
@@ -4,6 +4,7 @@ START=25
 USE_PROCD=1
 PROG=/usr/sbin/dhcpd
 
+WS=$'[\t ]'
 TTL=3600
 PREFIX="update add"
 
@@ -46,23 +47,35 @@ time2seconds() {
        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
 }
 
@@ -110,12 +123,6 @@ update() {
                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"
@@ -138,20 +145,35 @@ create_empty_zone() {
 }
 
 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() {
@@ -174,7 +196,7 @@ append_dhcp_options() {
                        value="\"$value\""
                        ;;
                esac
-               formatted="$formatted${formatted:+, }$value"
+               append formatted "$value" ", "
        done
        echo " option $tag $formatted;"
 }
@@ -280,7 +302,7 @@ static_host_add() {
        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"
@@ -290,26 +312,24 @@ static_host_add() {
 
        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
@@ -325,7 +345,7 @@ static_host_add() {
                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
@@ -374,11 +394,13 @@ gen_dhcp_subnet() {
                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;"
@@ -388,7 +410,7 @@ gen_dhcp_subnet() {
                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;"
@@ -411,7 +433,7 @@ dhcpd_add() {
        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
@@ -429,27 +451,30 @@ dhcpd_add() {
        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
@@ -488,9 +513,9 @@ general_config() {
        [ $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"
@@ -615,6 +640,7 @@ start_service() {
                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' ' ')"
@@ -632,6 +658,7 @@ EOF
 
                rfc1918_nets=
 
+               dhcp_ifs=
                config_foreach dhcpd_add dhcp 1 >> $config_file
 
                static_hosts >> $config_file
index 62f4373f727e0a8ff35873c20b801e125d28f65f..da44823c57a03c869e74dc08b483e396d2717c09 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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
index 63beb298337403ab81f13a803c466cdb5b7a3a7d..cbbff49410e094cad162195bea1ca7c5fd1596d7 100644 (file)
@@ -105,6 +105,11 @@ globals() {
        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
 
@@ -353,7 +358,7 @@ vrrp_instance() {
                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
index b40a2b28a9500ed337476d9497ad365553faf36b..11be30e818026ebfc8cbd4875ede324aa87e6eba 100644 (file)
@@ -8,12 +8,12 @@
 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
diff --git a/net/knot/patches/03_libdnssec_pkcs11_support.patch b/net/knot/patches/03_libdnssec_pkcs11_support.patch
new file mode 100644 (file)
index 0000000..4e7e30c
--- /dev/null
@@ -0,0 +1,17 @@
+--- 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;
index ddef5b563f742123cede2746e3783383d984e24b..984370e64b8e223318716a5f8ae8493fbd4f4ad6 100644 (file)
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 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)?
index 13c333c1a78671f23a6905ab9d90e4f8afa179ec..7ff2c76683de69555a9d23288c5883707ca28683 100644 (file)
@@ -12,6 +12,7 @@ mount_jail_file() {
        local cfg="$1"
        local isdir="${2:-0}"
        local rw="${3:-0}"
+       local reload="${4:-0}"
 
        local value
        config_get value "config" "$cfg"
@@ -31,6 +32,8 @@ mount_jail_file() {
        else
                procd_add_jail_mount "$value"
        fi
+
+       [ "$reload" = "0" ] || procd_append_param file "$value"
 }
 
 start_service() {
@@ -74,8 +77,8 @@ 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
 }
index 4ecc00a442bb273baed000fa6f2aadec466897d0..eb407e432c6518549dd786b14e92b6e5073c3d20 100644 (file)
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
 
 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/
@@ -25,46 +25,65 @@ PKG_BUILD_FLAGS:=lto
 
 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+= \
@@ -103,20 +122,82 @@ endef
 
 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))
diff --git a/net/libreswan/files/etc/config/libreswan b/net/libreswan/files/etc/config/libreswan
new file mode 100644 (file)
index 0000000..140c8f6
--- /dev/null
@@ -0,0 +1,41 @@
+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
diff --git a/net/libreswan/files/etc/hotplug.d/iface/89-libreswan b/net/libreswan/files/etc/hotplug.d/iface/89-libreswan
new file mode 100644 (file)
index 0000000..9ebc618
--- /dev/null
@@ -0,0 +1,11 @@
+#!/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
diff --git a/net/libreswan/files/etc/hotplug.d/libreswan/00-default b/net/libreswan/files/etc/hotplug.d/libreswan/00-default
new file mode 100644 (file)
index 0000000..940c495
--- /dev/null
@@ -0,0 +1,220 @@
+#!/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
diff --git a/net/libreswan/files/etc/hotplug.d/libreswan/01-user b/net/libreswan/files/etc/hotplug.d/libreswan/01-user
new file mode 100644 (file)
index 0000000..1202609
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+[ -e "/etc/ipsec.user" ] && {
+       . /etc/ipsec.user
+}
+
+exit 0
diff --git a/net/libreswan/files/etc/hotplug.d/libreswan/02-vti b/net/libreswan/files/etc/hotplug.d/libreswan/02-vti
new file mode 100644 (file)
index 0000000..719d60e
--- /dev/null
@@ -0,0 +1,24 @@
+#!/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"
diff --git a/net/libreswan/files/etc/hotplug.d/libreswan/61-iptables b/net/libreswan/files/etc/hotplug.d/libreswan/61-iptables
new file mode 100644 (file)
index 0000000..b795d30
--- /dev/null
@@ -0,0 +1,76 @@
+#!/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
diff --git a/net/libreswan/files/etc/hotplug.d/libreswan/62-nftables b/net/libreswan/files/etc/hotplug.d/libreswan/62-nftables
new file mode 100644 (file)
index 0000000..fe88147
--- /dev/null
@@ -0,0 +1,87 @@
+#!/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
diff --git a/net/libreswan/files/etc/init.d/ipsec b/net/libreswan/files/etc/init.d/ipsec
new file mode 100644 (file)
index 0000000..8a94785
--- /dev/null
@@ -0,0 +1,337 @@
+#!/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'
+}
diff --git a/net/libreswan/files/etc/ipsec.conf b/net/libreswan/files/etc/ipsec.conf
new file mode 100644 (file)
index 0000000..3b8f2dc
--- /dev/null
@@ -0,0 +1,3 @@
+include /var/run/ipsec/setup.conf
+include /var/run/ipsec/conf.d/*.conf
+include /etc/ipsec.d/*.conf
diff --git a/net/libreswan/files/etc/ipsec.secrets b/net/libreswan/files/etc/ipsec.secrets
new file mode 100644 (file)
index 0000000..68bbe91
--- /dev/null
@@ -0,0 +1,2 @@
+include /var/run/ipsec/conf.d/*.secret
+include /etc/ipsec.d/*.secrets
diff --git a/net/libreswan/files/etc/libreswan_firewall.sh b/net/libreswan/files/etc/libreswan_firewall.sh
new file mode 100755 (executable)
index 0000000..94ba275
--- /dev/null
@@ -0,0 +1,90 @@
+#!/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
diff --git a/net/libreswan/files/etc/uci-defaults/091-libreswan b/net/libreswan/files/etc/uci-defaults/091-libreswan
new file mode 100644 (file)
index 0000000..91a16e1
--- /dev/null
@@ -0,0 +1,8 @@
+#!/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
diff --git a/net/libreswan/files/ipsec.conf b/net/libreswan/files/ipsec.conf
deleted file mode 100644 (file)
index 8b7493b..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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
diff --git a/net/libreswan/files/ipsec.init b/net/libreswan/files/ipsec.init
deleted file mode 100755 (executable)
index f33d412..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/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
-
-}
-
diff --git a/net/libreswan/files/ipsec.secrets b/net/libreswan/files/ipsec.secrets
deleted file mode 100644 (file)
index 5ef87b0..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# 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
diff --git a/net/libreswan/files/usr/libexec/ipsec/_updown.xfrm b/net/libreswan/files/usr/libexec/ipsec/_updown.xfrm
new file mode 100644 (file)
index 0000000..58b51ba
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+/sbin/hotplug-call libreswan
diff --git a/net/libreswan/files/usr/libexec/rpcd/libreswan b/net/libreswan/files/usr/libexec/rpcd/libreswan
new file mode 100644 (file)
index 0000000..cf251f0
--- /dev/null
@@ -0,0 +1,183 @@
+#!/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 "$@"
diff --git a/net/libreswan/files/usr/share/nftables.d/chain-pre/forward/001-libreswan.nft b/net/libreswan/files/usr/share/nftables.d/chain-pre/forward/001-libreswan.nft
new file mode 100644 (file)
index 0000000..7861a91
--- /dev/null
@@ -0,0 +1 @@
+jump libreswan_forward 
diff --git a/net/libreswan/files/usr/share/nftables.d/chain-pre/input/001-libreswan.nft b/net/libreswan/files/usr/share/nftables.d/chain-pre/input/001-libreswan.nft
new file mode 100644 (file)
index 0000000..6659309
--- /dev/null
@@ -0,0 +1,2 @@
+jump libreswan_nflog_input
+jump libreswan_input
diff --git a/net/libreswan/files/usr/share/nftables.d/chain-pre/output/001-libreswan.nft b/net/libreswan/files/usr/share/nftables.d/chain-pre/output/001-libreswan.nft
new file mode 100644 (file)
index 0000000..825666a
--- /dev/null
@@ -0,0 +1,2 @@
+jump libreswan_nflog_output
+jump libreswan_output
diff --git a/net/libreswan/files/usr/share/nftables.d/chain-pre/srcnat/001-libreswan.nft b/net/libreswan/files/usr/share/nftables.d/chain-pre/srcnat/001-libreswan.nft
new file mode 100644 (file)
index 0000000..4c9fbec
--- /dev/null
@@ -0,0 +1 @@
+jump libreswan_srcnat
diff --git a/net/libreswan/files/usr/share/nftables.d/table-post/001-libreswan.nft b/net/libreswan/files/usr/share/nftables.d/table-post/001-libreswan.nft
new file mode 100644 (file)
index 0000000..0e00ea0
--- /dev/null
@@ -0,0 +1,6 @@
+chain libreswan_input {}
+chain libreswan_nflog_input {}
+chain libreswan_forward {}
+chain libreswan_output {}
+chain libreswan_nflog_output {}
+chain libreswan_srcnat {}
index e04350b7ff488e2026e083f60497a63c30b6fe28..82b947173a3cec6cb46c4380c15b00f8b91a31fe 100644 (file)
@@ -8,16 +8,16 @@
 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
index 36566d0475a3c47ded6ec792f4100aadca607e32..0c886f3ccb0bcd7fa660333460918e225cad8b0a 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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/
@@ -121,11 +121,11 @@ define Build/Compile
 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
@@ -152,9 +152,9 @@ define Package/mdnsd/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
index 864127a3d72c666a881423478b6fbd999756190f..2b455512f5f2c8989ff6f8997a7882ece224aab7 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -64,6 +64,7 @@ MESON_ARGS += \
        -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) \
@@ -98,10 +99,6 @@ define Package/modemmanager/install
        $(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
 
index 93a7f9b09165618b830afe1000be0dbee3db2147..1def1c354f3464523e7c14e0d390f8d95104ba0c 100644 (file)
@@ -26,6 +26,7 @@ Once installed, you can configure the 2G/3G/4G modem connections directly in
         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.
@@ -42,3 +43,17 @@ The 'plmn' option allows to set the network operator MCCMNC.
 
 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.
index d46ee72430f1eae7e250ec5c4a47d2ee72bd9ff4..2ba2036ce9281b61364ebbff598e1fb5fa11b0a3 100644 (file)
@@ -235,24 +235,20 @@ mm_report_modem_wait() {
 # 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() {
@@ -277,7 +273,7 @@ mm_report_event() {
        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)"
@@ -298,11 +294,15 @@ mm_report_event() {
        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() {
@@ -319,9 +319,6 @@ 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
@@ -346,6 +343,9 @@ mm_report_events_from_cache() {
                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}"
index 7f014dc56ecb64746e71083b86b5ec2873579d88..a036d884da4f2c11d6253aec396b4d4d8d7f2ec6 100755 (executable)
@@ -6,13 +6,6 @@ START=70
 
 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
        #
index a4d837c1e51420f25bb1babe9ca28ba331e30d90..afbe2397ff18e7d112662f66fc869efbea8a546d 100755 (executable)
@@ -339,6 +339,12 @@ proto_modemmanager_init_config() {
        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
 }
 
@@ -364,6 +370,50 @@ modemmanager_set_allowed_mode() {
        }
 }
 
+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"
@@ -394,6 +444,38 @@ modemmanager_set_preferred_mode() {
        }
 }
 
+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"
 
@@ -405,12 +487,20 @@ proto_modemmanager_setup() {
        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"
@@ -430,6 +520,9 @@ proto_modemmanager_setup() {
        }
        echo "modem available at ${modempath}"
 
+       modemmanager_check_state "$device" "${modemstatus}" "$pincode"
+       [ "$?" -ne "0" ] && return 1
+
        [ -z "${allowedmode}" ] || {
                case "$allowedmode" in
                        "2g")
@@ -460,10 +553,51 @@ proto_modemmanager_setup() {
        # 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}'..."
@@ -477,7 +611,12 @@ proto_modemmanager_setup() {
                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}}"
@@ -485,7 +624,6 @@ proto_modemmanager_setup() {
        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
index 4fd64227fe33840c4d4559eba6710b8e79915ca8..97c2a826de89845cf325f817ee7c0270dbd38869 100644 (file)
@@ -20,7 +20,6 @@ main() {
 
        mkdir -p "${MODEMMANAGER_RUNDIR}"
        chmod 0755 "${MODEMMANAGER_RUNDIR}"
-       mm_cleanup_interfaces
 
        /usr/sbin/ModemManager "$@" 1>/dev/null 2>/dev/null &
        CHILD="$!"
@@ -28,6 +27,9 @@ main() {
        mm_report_events_from_cache
 
        wait "$CHILD"
+
+       # Set all configured interfaces as unavailable
+       mm_cleanup_interfaces
 }
 
 main "$@"
diff --git a/net/modemmanager/patches/100-ublox-remove-ID_MM_PROCESS-tags.patch b/net/modemmanager/patches/100-ublox-remove-ID_MM_PROCESS-tags.patch
new file mode 100644 (file)
index 0000000..d1f6753
--- /dev/null
@@ -0,0 +1,13 @@
+--- 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"
index 56568f42bba837e2f2036f7cda1721b45de45781..d3b106e8ef3906ad7157f5a13772c231201a4edd 100644 (file)
@@ -9,17 +9,19 @@
 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
@@ -163,9 +165,9 @@ Package/mosquitto-nossl/conffiles = $(Package/mosquitto-ssl/conffiles)
 
 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
 
@@ -177,69 +179,69 @@ define Package/mosquitto-ssl/install
        $(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))
index 6d98fa2382db6f81b70d38a8606e2d1978325beb..bef27143b71efb917f304396dbe8b5d1c3a98e20 100644 (file)
@@ -4,12 +4,12 @@
 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
@@ -51,6 +51,9 @@ define Package/nebula-proto
   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
 
@@ -60,6 +63,8 @@ define Package/nebula-service
   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
@@ -69,28 +74,28 @@ define Build/Compile
 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
index b77be1254a6f5f1162726b0f09f90aed026a527a..c8f4991afa0f0641da3885be4bfa2ea43b0aa8dd 100644 (file)
@@ -49,6 +49,7 @@ proto_nebula_setup() {
 
        [ -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")."
@@ -71,7 +72,7 @@ proto_nebula_setup() {
        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
                        *:*/*)
index 46aa5e2735101770db341e619c0e32d6593826b9..1a1194955bfa4eddf6f9d406dc9904fae9779278 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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
diff --git a/net/net-snmp/patches/203-if-mib-data_access-interface.c-plug-a-leak-with-pcre.patch b/net/net-snmp/patches/203-if-mib-data_access-interface.c-plug-a-leak-with-pcre.patch
new file mode 100644 (file)
index 0000000..e2da12f
--- /dev/null
@@ -0,0 +1,30 @@
+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)
index d6d976fc24ee5dc88698a7e4de9eea7b70243414..84d7092ae33662393793bc14e97ac99574de82fa 100644 (file)
@@ -1,12 +1,12 @@
 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
@@ -15,6 +15,7 @@ PKG_LICENSE_FILES:=LICENSE
 PKG_BUILD_DEPENDS:= \
        rust/host \
        protobuf/host
+PKG_BUILD_PARALLEL:=1
 
 include $(INCLUDE_DIR)/package.mk
 include ../../lang/rust/rust-package.mk
@@ -36,7 +37,7 @@ define Package/netavark/conffiles
 /etc/config/netavark
 endef
 
-CARGO_VARS += \
+CARGO_PKG_VARS += \
        PROTOC=$(STAGING_DIR_HOSTPKG)/bin/protoc
 
 define Package/netavark/install
index 637df8dedd28f6def2c394d83f3fa920567103f8..d6ee0ce30615f012c9adbbc1d19376279920ac5c 100644 (file)
@@ -1,12 +1,12 @@
 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
@@ -33,10 +33,10 @@ define Package/netbird
 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
 
@@ -44,6 +44,12 @@ define Package/netbird/conffiles
 /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
index b7ccd2d4b253e70b3c5a96a704ec6ba7d857e3e8..87427c4061c2041588d7cf16003944066e972971 100755 (executable)
@@ -1,11 +1,19 @@
 #!/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
index 990a01e813c5831acf8e1aff28ca425621718755..b02166f36d922cdcff042c6c3311a3909ebf1dbc 100644 (file)
@@ -200,4 +200,9 @@ config NGINX_HTTP_SUB
        prompt "Enable HTTP sub module"
        default n
 
+config NGINX_STREAM_REAL_IP
+       bool
+       prompt "Enable STREAM real ip module"
+       default n
+
 endmenu
index 66a0c8713d1d71c1a0d65ffd6facaf42fd422bc1..0accdd0999367a2a71065203f993516cfb775ff5 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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/
@@ -82,6 +82,7 @@ PKG_CONFIG_DEPENDS := \
        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))
@@ -449,6 +450,7 @@ CONFIGURE_ARGS += \
        $(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)))
diff --git a/net/nginx/patches/nginx-mod-lua/101-bugfix-don-t-include-pcre.h-with-PCRE2-used.patch b/net/nginx/patches/nginx-mod-lua/101-bugfix-don-t-include-pcre.h-with-PCRE2-used.patch
new file mode 100644 (file)
index 0000000..da3c460
--- /dev/null
@@ -0,0 +1,27 @@
+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
index b84b2ccd840944e9a20dfff265ba2c4d3b54a21e..55c52b9399f51c367456d740026f35804105e454 100644 (file)
@@ -14,7 +14,7 @@ include $(TOPDIR)/rules.mk
 
 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
diff --git a/net/nmap/patches/010-Build-based-on-OpenSSL-version.patch b/net/nmap/patches/010-Build-based-on-OpenSSL-version.patch
new file mode 100644 (file)
index 0000000..3a615df
--- /dev/null
@@ -0,0 +1,295 @@
+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
diff --git a/net/ooniprobe/Makefile b/net/ooniprobe/Makefile
deleted file mode 100644 (file)
index bb7cf42..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# 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))
diff --git a/net/ooniprobe/test.sh b/net/ooniprobe/test.sh
deleted file mode 100644 (file)
index 9ecab82..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-ooniprobe version | grep "$2"
index e4c776726501b137271b7b9af55f0e34de5be62c..1ec7d70d2d2dca73dac9187712777e99d7f517de 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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/
index 25fb7d542468b2e4cf5a7446541a356a9936caec..d318b97e0d455cb8f5a0c7247e56b832380e17a4 100755 (executable)
@@ -20,6 +20,7 @@ proto_openconnect_init_config() {
        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"
@@ -58,6 +59,7 @@ proto_openconnect_setup() {
                os \
                password \
                password2 \
+               pfs \
                port \
                proxy \
                reconnect_timeout \
@@ -84,6 +86,7 @@ proto_openconnect_setup() {
        [ -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"
 
index d5b61b1e1391d5e19451c135d8c4ab932fca2d49..1b42cceee555b4e7d1012fafd6abe428c6bec675 100644 (file)
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 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
@@ -74,9 +74,7 @@ CMAKE_OPTIONS += \
        -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) \
@@ -96,6 +94,7 @@ endef
 
 define Package/openthread-br/install
        $(INSTALL_DIR) \
+               $(1)/etc/init.d \
                $(1)/lib/netifd/proto \
                $(1)/usr/sbin \
                $(1)/var/lib/thread
index 5605acb154023b1be982bd3625f99aada6cd06d2..014c306f3b4daf03f4f3d6a7a77bf1978ad5ecd6 100644 (file)
@@ -16,6 +16,8 @@ otDatasetCreateNewNetwork).
  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:
@@ -53,6 +55,8 @@ otDatasetCreateNewNetwork).
  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:
@@ -103,6 +107,8 @@ otDatasetCreateNewNetwork).
      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:
@@ -113,3 +119,6 @@ otDatasetCreateNewNetwork).
  
      void DeleteOutDatedDiagnostic(void);
      void UpdateDiag(std::string aKey, std::vector<otNetworkDiagTlv> &aDiag);
+-- 
+2.41.0
+
index 8f79f2b10b861c797a608c686b0772c1250c6c24..903af60d23b18a040c5094020497a03313c6b8a8 100644 (file)
@@ -9,14 +9,14 @@ include $(TOPDIR)/rules.mk
 
 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>
 
index c54277006d067044bba9d131ffb8dcc9f839664a..6ac30df594743d1db6d2793830c70c0c91bb0835 100644 (file)
@@ -1,6 +1,6 @@
 --- 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];
index 0a45ea49e535a000bab28e2f611f4de8402ba46b..e5b103bc59d460ec76e7210d02f6e2c04dc4501d 100644 (file)
@@ -1,6 +1,6 @@
 --- 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>
  
@@ -9,8 +9,8 @@
  #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)
index f0e7361f2565b27285cd669a90bc1b19bcd5ce11..50834b3bb77c0e59078b0622631534041f8630b2 100644 (file)
@@ -1,6 +1,6 @@
 --- a/src/openvpn/ssl_openssl.c
 +++ b/src/openvpn/ssl_openssl.c
-@@ -1351,7 +1351,7 @@ err:
+@@ -1347,7 +1347,7 @@ err:
      return 0;
  }
  
@@ -9,7 +9,7 @@
  
  /* 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;
          }
      }
index 30e1822a1ce2a2e583cea60a2c83a9c477753592..690521ee649d73219a70bbd05a11c4797b62fe39 100644 (file)
@@ -1,6 +1,6 @@
 --- 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;
          }
      }
index f0820f378b104ecbca02a89c5d51f4c0a8024fab..0642c34597c86658a35060cd44c8ea1e086d6d27 100644 (file)
@@ -1,12 +1,12 @@
 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
@@ -35,7 +35,7 @@ define Package/pdns-recursor/description
 endef
 
 define Package/pdns-recursor/conffiles
-/etc/powerdns/pdns-recursor.conf
+/etc/powerdns/recursor.conf
 /etc/init.d/pdns-recursor
 endef
 
index 39ac66747fa46a9218802a394f9e4d9cd6cfdff7..eedc3c6d112eb6cae6b7e6282b8756689d131de0 100644 (file)
@@ -1,12 +1,12 @@
 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
index 9242373a2974b9d110c1e72fbbebc49614c20d3a..2e417c4cb13e371bf47e54aa4790dd836ff0b4e7 100644 (file)
 #
 # 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
 #
index 6c90f4f492b74153d6c020b74a47fd0659083e8d..4892a3e9b06949ba6c7d0b814e337db3a617c46c 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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
index 322eaaf1b5ef3f0db786a1caab4cc1ce41653429..ae39c0fd577ef432fee4e9a2355363bd73b14213 100644 (file)
@@ -18,11 +18,11 @@ validate_login_section() {
 
 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() {
index f59920cf30bf55d963789b24d7137c14db519fa0..485280964bac5689131fc5cea54dcf147ffad64d 100644 (file)
@@ -8,13 +8,13 @@
 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
 
@@ -58,7 +58,7 @@ define Package/privoxy
   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
diff --git a/net/privoxy/patches/100-Add-pcre2-support.patch b/net/privoxy/patches/100-Add-pcre2-support.patch
new file mode 100644 (file)
index 0000000..8975e94
--- /dev/null
@@ -0,0 +1,1014 @@
+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);
diff --git a/net/privoxy/patches/101-Add-regex_matches-to-reduce-HAVE_PCRE2-ifdefs.patch b/net/privoxy/patches/101-Add-regex_matches-to-reduce-HAVE_PCRE2-ifdefs.patch
new file mode 100644 (file)
index 0000000..a77ddac
--- /dev/null
@@ -0,0 +1,138 @@
+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);
diff --git a/net/privoxy/patches/102-configure-Fix-disable-pcre2.patch b/net/privoxy/patches/102-configure-Fix-disable-pcre2.patch
new file mode 100644 (file)
index 0000000..300440f
--- /dev/null
@@ -0,0 +1,30 @@
+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
diff --git a/net/privoxy/patches/103-pcre2-compile_pattern-Actually-pass-the-anchored-pat.patch b/net/privoxy/patches/103-pcre2-compile_pattern-Actually-pass-the-anchored-pat.patch
new file mode 100644 (file)
index 0000000..f56f4e1
--- /dev/null
@@ -0,0 +1,38 @@
+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)
diff --git a/net/quassel-irssi/Makefile b/net/quassel-irssi/Makefile
deleted file mode 100644 (file)
index 8b850be..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# 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))
diff --git a/net/quassel-irssi/patches/001-respect-cflags.patch b/net/quassel-irssi/patches/001-respect-cflags.patch
deleted file mode 100644 (file)
index 291bed4..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
---- 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)
diff --git a/net/quassel-irssi/patches/002-use-cc-var.patch b/net/quassel-irssi/patches/002-use-cc-var.patch
deleted file mode 100644 (file)
index aa73850..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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
diff --git a/net/quassel-irssi/patches/003-use-pkgconfig-ldflags-quasselc.patch b/net/quassel-irssi/patches/003-use-pkgconfig-ldflags-quasselc.patch
deleted file mode 100644 (file)
index ddf313a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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
diff --git a/net/quassel-irssi/patches/010-Get-compatible-with-potential-irssi-abi-8-and-drop-p.patch b/net/quassel-irssi/patches/010-Get-compatible-with-potential-irssi-abi-8-and-drop-p.patch
deleted file mode 100644 (file)
index 5c84128..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-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) {
index 01d253a9a7a848d0c287138564c6a81c501651d6..dc48c6ad4f8747747f7589ec7a13166d7642ed26 100644 (file)
@@ -6,12 +6,12 @@
 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
index e0d45525b7cd0464ad6b00b5609a98dcaedcefff..a3b8b28b0fcca8d96f422b51dfd6b1070480f36a 100644 (file)
@@ -1,13 +1,13 @@
 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
index f0840cebb80729496b289c8dbaa34547d9c91280..4afa8746372cf54e5df65b9b44bc9029b4596655 100644 (file)
@@ -2,7 +2,7 @@
 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
@@ -13,7 +13,7 @@ PKG_SOURCE_URL:= \
                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
 
index d3723073acabde9c6ce072dfe4d478ec1f91e153..6c6058ed31e966e68f8673ccc68f6a74849b5b43 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -44,7 +44,7 @@ endef
 
 define Package/ser2net/conffiles
 /etc/config/ser2net
-/etc/ser2net.conf
+/etc/ser2net.yaml
 endef
 
 define Package/ser2net/install
@@ -52,7 +52,7 @@ 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
diff --git a/net/ser2net/files/ser2net.conf b/net/ser2net/files/ser2net.conf
deleted file mode 100644 (file)
index 2c9605b..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# 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
index ca9915b908175b3dd90192bddcccead20bb40b2d..5453ca380adfb135882f30fafd6e139b507703e7 100644 (file)
@@ -7,55 +7,71 @@ STOP=10
 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
@@ -70,8 +86,12 @@ ser2net_controlport() {
 
        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() {
@@ -80,84 +100,114 @@ 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() {
@@ -169,15 +219,15 @@ 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
diff --git a/net/ser2net/files/ser2net.yaml b/net/ser2net/files/ser2net.yaml
new file mode 100644 (file)
index 0000000..8a46ef0
--- /dev/null
@@ -0,0 +1,10 @@
+# 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.
+
diff --git a/net/ser2net/patches/001-fix-disabling-pam.patch b/net/ser2net/patches/001-fix-disabling-pam.patch
deleted file mode 100644 (file)
index 02417d9..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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
index 0c4ce1bd689b3399a7405356763a13073f505854..b10eb32f7f2d28d6cabacf333b04c850df23ec44 100644 (file)
@@ -14,7 +14,7 @@ include $(TOPDIR)/rules.mk
 #
 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)
@@ -29,7 +29,7 @@ PKG_FIXUP:=autoreconf
 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
 
@@ -71,8 +71,8 @@ define Package/shadowsocks-libev/Default
 
 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
diff --git a/net/shadowsocks-libev/patches/100-Upgrade-PCRE-to-PCRE2.patch b/net/shadowsocks-libev/patches/100-Upgrade-PCRE-to-PCRE2.patch
new file mode 100644 (file)
index 0000000..91b2e5b
--- /dev/null
@@ -0,0 +1,544 @@
+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;
index 20a7c6dd0c8ea86c65768ed77c8050c403456148..3bd577e8f8a1bfa66893c5825ea7aeb225b35069 100644 (file)
@@ -1,12 +1,12 @@
 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
@@ -35,7 +35,7 @@ endef
 
 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
@@ -77,11 +77,6 @@ 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
@@ -106,7 +101,6 @@ PKG_CONFIG_DEPENDS:= \
        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
@@ -121,7 +115,6 @@ GO_PKG_TAGS:=$(subst $(space),$(comma),$(strip \
        $(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) \
index 6afffec5c85b6df26234f15361cece016a8bbb99..66a8806cfebda6989388bd64f3e5b8739f5d4d0c 100644 (file)
@@ -8,8 +8,8 @@
 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>
@@ -18,7 +18,7 @@ PKG_CPE_ID:=cpe:/a:snort:snort
 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)
@@ -31,7 +31,7 @@ define Package/snort
   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
@@ -57,8 +57,8 @@ CONFIGURE_ARGS += \
        --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
diff --git a/net/snort/patches/900-Convert-project-to-PCRE2.patch b/net/snort/patches/900-Convert-project-to-PCRE2.patch
new file mode 100644 (file)
index 0000000..4e01347
--- /dev/null
@@ -0,0 +1,2114 @@
+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");
index 4c7cbb407364772e1950fecb34ec477b3640734a..2cd80567e22ef3db9393665f84532e3b97b96372 100644 (file)
@@ -6,14 +6,14 @@
 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
@@ -25,7 +25,7 @@ define Package/snort3
   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
@@ -76,6 +76,10 @@ define Package/snort3/install
                $(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 \
@@ -90,6 +94,19 @@ define Package/snort3/install
                $(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) \
index 975f7025418d5f9da75f8e7ccac9d1efa8ace233..91845611d3c5a4a8207a1e1f95a97472ad16033d 100644 (file)
@@ -1,3 +1,4 @@
+-- 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"
index c48ffd0c8bc637181c9252b21d7af901c91ed9db..8de694131d86378806579d561237ee19f3cfc002 100644 (file)
@@ -1,3 +1,6 @@
+-- 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
diff --git a/net/snort3/files/main.uc b/net/snort3/files/main.uc
new file mode 100644 (file)
index 0000000..7db420f
--- /dev/null
@@ -0,0 +1,263 @@
+{%
+//------------------------------------------------------------------------------
+// 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;
+}
+
+//------------------------------------------------------------------------------
+-%}
diff --git a/net/snort3/files/nftables.uc b/net/snort3/files/nftables.uc
new file mode 100644 (file)
index 0000000..c87246b
--- /dev/null
@@ -0,0 +1,18 @@
+# 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 }}
+       }
+}
diff --git a/net/snort3/files/snort-mgr b/net/snort3/files/snort-mgr
new file mode 100644 (file)
index 0000000..6a5e85e
--- /dev/null
@@ -0,0 +1,260 @@
+#!/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
diff --git a/net/snort3/files/snort-rules b/net/snort3/files/snort-rules
new file mode 100644 (file)
index 0000000..24ae7a7
--- /dev/null
@@ -0,0 +1,92 @@
+#!/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
index 84f5e96d91d5fe1b4510022265439ef0c70f0b45..5567ef46468d9e2a4bacf6ef5832e0a527af8262 100644 (file)
@@ -1,3 +1,74 @@
+#
+# 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
+
index ff864e02b273abfe1ad2c87b56863ffe412bbc1e..f73ebe8799c88aab7f3793bb1a534e2928726053 100644 (file)
@@ -1,36 +1,58 @@
 #!/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()
diff --git a/net/snort3/files/snort.uc b/net/snort3/files/snort.uc
new file mode 100644 (file)
index 0000000..b58fa01
--- /dev/null
@@ -0,0 +1,126 @@
+{%
+// 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 %}
diff --git a/net/snort3/patches/010-gcc13.patch b/net/snort3/patches/010-gcc13.patch
new file mode 100644 (file)
index 0000000..4bfaee1
--- /dev/null
@@ -0,0 +1,14 @@
+--- 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
index a7f3e61bc37bdda80a54059f451ba1aa2781bcca..56019d076c22c5eef9b500ffc35612dee702ae3d 100644 (file)
@@ -1,13 +1,13 @@
 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
@@ -41,11 +41,6 @@ $(call Package/snowflake/Default)
   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
@@ -81,12 +76,6 @@ $(call Package/snowflake/description/Default)
 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)
 
@@ -115,11 +104,6 @@ define Package/snowflake-client/install
        $(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
@@ -138,7 +122,6 @@ endef
 
 $(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))
diff --git a/net/snowflake/patches/0001-Bump-minimum-required-version-of-go.patch b/net/snowflake/patches/0001-Bump-minimum-required-version-of-go.patch
deleted file mode 100644 (file)
index b5d503a..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-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
-+)
diff --git a/net/snowflake/patches/0002-Update-dependencies.patch b/net/snowflake/patches/0002-Update-dependencies.patch
deleted file mode 100644 (file)
index b82a01f..0000000
+++ /dev/null
@@ -1,792 +0,0 @@
-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=
index 95e8dc3823d899f7ec3bb88821ef1caeb17930f1..bd39bfe1d1855558dd6c62df72c11dbb2236a18f 100644 (file)
@@ -1,12 +1,12 @@
 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
index 7010fba520d4e58fbff8f4447048d0baed71e6ca..0c72655f0a6b98b220e7f342659924e0d9045e91 100644 (file)
@@ -8,17 +8,19 @@
 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
index f8cb704c51981e5dc3d73d016a13cc07b3bdf513..f5c9e6ec371e5cc49b1fed285a6acbecd4482a7c 100755 (executable)
@@ -10,6 +10,7 @@
 
 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"
@@ -28,7 +29,7 @@ proto_sstp_setup() {
        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" )
@@ -42,7 +43,7 @@ proto_sstp_setup() {
                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
@@ -82,7 +83,7 @@ proto_sstp_setup() {
                --save-server-route \
                --ipparam $config \
                $sstp_options \
-               $server \
+               $server${port:+:$port} \
                ifname $ifname \
                require-mschap-v2 \
                ${ipv6:++ipv6} \
index 3d2eb9462c991076c981266b35e4fc440a3df970..a9d5683eac1e8b2a5c652ddafa05cd3352069277 100644 (file)
@@ -1,6 +1,6 @@
 --- 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;
  
@@ -8,7 +8,7 @@
      /* 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());
index c106257bf51ce255a3384a8c22dd2858ddbe6d16..09ae9ea8731fb76d47563f32bc5cb6de431033a0 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -41,6 +41,7 @@ PKG_MOD_AVAILABLE:= \
        dnskey \
        drbg \
        duplicheck \
+       eap-dynamic \
        eap-identity \
        eap-md5 \
        eap-mschapv2 \
@@ -183,6 +184,7 @@ $(call Package/strongswan/Default)
        +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 \
@@ -681,6 +683,7 @@ $(eval $(call BuildPlugin,dhcp,DHCP based attribute provider,))
 $(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))
index dcc065d2ea1b07fc957f24e8684e424315714984..289e7ff567aa17c986212fb297306426cd691f16 100644 (file)
@@ -244,6 +244,7 @@ config_child() {
        local lifebytes
        local rekeypackets
        local lifepackets
+       local replay_window
 
        config_get startaction "$conf" startaction "route"
        config_get local_nat "$conf" local_nat ""
@@ -262,6 +263,7 @@ config_child() {
        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 ","
@@ -370,6 +372,7 @@ config_child() {
 
        [ -n "$updown" ] && swanctl_xappend4 "updown = $updown"
        [ -n "$dpdaction" ] && swanctl_xappend4 "dpd_action = $dpdaction"
+       [ -n "$replay_window" ] && swanctl_xappend4 "replay_window = $replay_window"
 
         swanctl_xappend3 "}"
 }
index 4323cd56348af049165dc54584a47a966197efaa..91e6afbe2a889014b46439bd0c3da35bdaab4662 100644 (file)
@@ -48,7 +48,7 @@ Subject: [PATCH 900/904] src: Patch for building with musl on openwrt (taken
  #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"
index ded7b21a4f7531117579fbc1002ee27da5e9350f..b81138c564853f599f330ad2b57ae58a22fda92c 100644 (file)
@@ -26,7 +26,7 @@ Subject: [PATCH 904/904] gmpdh: Plugin that implements gmp DH functions in an
  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])
@@ -34,7 +34,7 @@ Subject: [PATCH 904/904] gmpdh: Plugin that implements gmp DH functions in an
  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)
@@ -42,7 +42,7 @@ Subject: [PATCH 904/904] gmpdh: Plugin that implements gmp DH functions in an
  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
@@ -52,7 +52,7 @@ Subject: [PATCH 904/904] gmpdh: Plugin that implements gmp DH functions in an
        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
  
index d787ee25d64a507fa3d05fa1f503c709dd569b7d..a1efec68610b856118ffe3c38cc58b31292e693d 100644 (file)
@@ -8,12 +8,12 @@
 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
index 70ff9a1ea28fdafd313c5f645e2aa10509c9fdbe..1e8af2cc9edc2e29c3e62b0d7e166402748ef391 100644 (file)
@@ -4,12 +4,12 @@
 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
index 4f7018c5b26025aa6e6bce8558f51a8a3c67dcc4..3cfccd816205580ef8f2378e6d942ee46b6ba95d 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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
index 8823b97e74b604d1da325dfb4898f8375ce4075b..86c267472313d6a0f95157fff316c04f2d2270c8 100644 (file)
@@ -91,11 +91,16 @@ prepare_host() {
        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
        }
 
@@ -107,7 +112,7 @@ prepare_host() {
 
        [ ! -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, "
@@ -118,12 +123,25 @@ prepare_host() {
 
        # 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() {
@@ -139,9 +157,9 @@ 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"
@@ -187,7 +205,6 @@ prepare_net() {
                Device \
                DeviceType \
                Ed25519PrivateKeyFile \
-               ECDSAPublicKey \
                Forwarding \
                Interface \
                ListenAddress \
index 756d2785c0d1adbc59b3c496cae6b3f3b2fd1642..2a3c1f9336a3a43935ee5f832036eed2c9eb7323 100644 (file)
@@ -8,13 +8,13 @@
 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
index 142e2512def11559dcf42df3d47ea40feaaa677e..cb1cb73c5cd4159ba7f634ac19886811c7479f03 100644 (file)
@@ -32,7 +32,7 @@ generate_conf() {
 }
 
 reload_service() {
-       procd_send_signal /usr/sbin/tor
+       procd_send_signal tor
 }
 
 start_service() {
index 0fd6f23b982f965c4350d59fb72ed0d958a4c035..c71f947a32cf76185a047e6baa9d807a6ddb5ebc 100644 (file)
@@ -8,12 +8,12 @@
 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
index b04b069cadeae5dd50ee002e35068c1ea42c8beb..ef0bf2779b3bc11d835f22ed004b761aa2ea1468 100644 (file)
@@ -1,13 +1,13 @@
 #
-# 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>
 
@@ -17,7 +17,7 @@ define Package/travelmate
        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
 
index 69bf321fcc34bff103a75c70f046a1fa4258c2b6..c089e668ea53cf33132ba271127b4aa73008f51b 100644 (file)
@@ -32,7 +32,7 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
 * 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
@@ -55,7 +55,7 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
 * 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                                                                              |
 | :----------------- | :--------------------------------- | :---------------------------------------------------------------------------------------------------- |
@@ -83,8 +83,11 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
 | 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                                                                              |
 | :----------------- | :--------------------------------- | :---------------------------------------------------------------------------------------------------- |
@@ -102,7 +105,7 @@ To avoid these kind of deadlocks, travelmate will set all station interfaces to
 | 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:
@@ -110,6 +113,7 @@ Please follow one of the following guides to get a working vpn client setup on y
 * [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
@@ -161,18 +165,18 @@ Hopefully more scripts for different captive portals will be provided by the com
 
 **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-"_)
@@ -182,7 +186,7 @@ Please join the travelmate discussion in this [forum thread](https://forum.lede-
 
 ## 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  
diff --git a/net/travelmate/files/hreward.login b/net/travelmate/files/hreward.login
new file mode 100755 (executable)
index 0000000..01342a1
--- /dev/null
@@ -0,0 +1,77 @@
+#!/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
index 9c03d9875352419a9565ec1a3e51836749a0710b..be10d77f2bd4d4f24db77e34b5818adacb52d30a 100755 (executable)
@@ -1,9 +1,9 @@
 #!/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
index fd717c34b921145776b5c9dd20836c584ebee8c4..dca5bc8964a5f09ab80c5e8d6299e987ac1452ba 100755 (executable)
@@ -1,15 +1,14 @@
 #!/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=""
@@ -34,14 +33,18 @@ trm_wpaflags=""
 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"
@@ -58,9 +61,9 @@ f_env() {
                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() {
@@ -73,7 +76,7 @@ f_env() {
                        }
                        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
                        }
@@ -95,7 +98,7 @@ f_env() {
        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
@@ -170,8 +173,8 @@ f_wifi() {
                                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}"
@@ -204,24 +207,22 @@ f_vpn() {
                        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
@@ -235,7 +236,7 @@ f_vpn() {
                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
@@ -254,7 +255,7 @@ f_vpn() {
                        [ -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
@@ -274,13 +275,13 @@ f_mac() {
                        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
@@ -298,22 +299,22 @@ f_ctrack() {
                        "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")"
@@ -321,7 +322,7 @@ f_ctrack() {
                                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
@@ -331,7 +332,7 @@ f_ctrack() {
                                ;;
                        "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
                                ;;
@@ -379,7 +380,7 @@ f_getovpn() {
                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
@@ -390,7 +391,7 @@ f_getvpn() {
        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
@@ -399,7 +400,7 @@ f_getvpn() {
                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
@@ -410,7 +411,7 @@ f_getvpn() {
                        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
@@ -536,7 +537,7 @@ f_setif() {
 # 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() {
@@ -557,39 +558,45 @@ f_addsta() {
        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}"
 }
@@ -603,9 +610,9 @@ f_net() {
        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}'"
@@ -623,7 +630,7 @@ f_net() {
                                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
@@ -643,7 +650,7 @@ f_net() {
 # 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"
@@ -663,7 +670,9 @@ f_check() {
                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
@@ -679,11 +688,13 @@ f_check() {
                                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
@@ -768,8 +779,6 @@ f_check() {
                        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}"
 }
@@ -777,12 +786,12 @@ f_check() {
 # 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")"
@@ -792,16 +801,7 @@ f_jsnup() {
                        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")"                      
@@ -867,8 +867,8 @@ f_log() {
 # 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}"
@@ -924,7 +924,7 @@ f_main() {
                                        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="-"};
@@ -942,6 +942,18 @@ f_main() {
                                        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
@@ -984,10 +996,6 @@ f_main() {
                                                                        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
@@ -999,6 +1007,10 @@ f_main() {
        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
@@ -1009,6 +1021,13 @@ else
        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
index ed8bd30b2e9e409b350f5d23e1f07032797517f1..ece79c4dd9f178f0d12e75b3467359f52cd05e41 100755 (executable)
@@ -1,10 +1,10 @@
 #!/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
 
@@ -20,33 +20,43 @@ vpn_iface="${4}"
 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
@@ -56,12 +66,13 @@ if [ "${vpn}" = "1" ] && [ "${vpn_action%_*}" = "enable" ]; 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
@@ -69,7 +80,8 @@ if [ "${vpn}" = "1" ] && [ "${vpn_action%_*}" = "enable" ]; then
                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
index c27bea73d5b1b8f6a682623f1e269701c49a5903..5195c03dc1170a8dfbed6c267e47b2d4a137b48b 100755 (executable)
@@ -1,20 +1,16 @@
 #!/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
index 8f120d944147a9c6ca451ac43857019c3588b375..4e47aea6e6f3e442b771b956e7c2db4302e517ad 100644 (file)
@@ -1,7 +1,7 @@
 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
index 6694215885ee46f4fa646feec8b0278b1384de6f..cafa4efa4e1c4807e9674c540940bd240b73a730 100644 (file)
@@ -15,7 +15,8 @@ validate_section_udp_broadcast_relay_redux()
        'port:port' \
        'network:list(string)' \
        'src_override:ip4addr' \
-       'dest_override:ip4addr'
+       'dest_override:ip4addr' \
+       'multicast:ip4addr'
 
     [ -z "$id" ] && return 1
 
@@ -27,7 +28,7 @@ validate_section_udp_broadcast_relay_redux()
 }
 
 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"
@@ -58,6 +59,10 @@ udp_broadcast_relay_redux_instance() {
         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
 }
index f7164bd680942cf1d9f221709fa2b6be4962f96a..6ba4de2209a491f74ecdc585275534b5ae65942b 100644 (file)
@@ -4,3 +4,4 @@
 #       list network lan
 #       list network vpnsrv
 #       option dest_override 10.66.2.13
+#       option multicast 239.255.255.250
index d0cb41fac52eb6dae135839dcff5169e2227d5dc..3a7a27cbf7b681bdefe1bc1cad6d5c79a0a07bb9 100644 (file)
@@ -8,12 +8,12 @@
 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
index eae8dae9889e197fa4ff075a680488948db9bcb3..28f3c86dcf9fb66ae318f475c44c9cde7e54ed5d 100644 (file)
@@ -69,7 +69,7 @@ create_local_zone() {
 
 ##############################################################################
 
-create_host_record() {
+create_host_record_from_domain() {
   local cfg="$1"
   local ip name debug_ip
 
@@ -102,6 +102,35 @@ create_host_record() {
 
 ##############################################################################
 
+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
@@ -215,7 +244,8 @@ dnsmasq_inactive() {
     # 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
index f53962fcd45a3006a51084ffb2900aa1705da6d4..098f2785c40bb148624b4c777feb993f3c552af4 100644 (file)
@@ -3,7 +3,7 @@ Fix cross compile errors by inserting an environment variable for the
 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
  
diff --git a/net/uspot/Makefile b/net/uspot/Makefile
new file mode 100644 (file)
index 0000000..9d6dd64
--- /dev/null
@@ -0,0 +1,96 @@
+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))
index 60084a7df6acd5312cd2480f3f85b8f43fc2e62f..b23ae025e8840951b4750af6100a5247712ebcd6 100644 (file)
@@ -5,12 +5,12 @@
 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
index 1ce0b2e7329329a846e7874946550496ad539287..144bc218bad702a8ed393bf3b5c85f9d06df5bc2 100644 (file)
@@ -12,31 +12,31 @@ PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
 
 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
index eec759a7b328fb6307214b505f11abad3ad318b0..a47d533a0f06dc13cb36927e5773118f4c1f72b8 100644 (file)
@@ -5,12 +5,12 @@
 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
@@ -54,12 +54,12 @@ define Package/v2raya/conffiles
 /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
@@ -67,7 +67,7 @@ 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
 
index 65c69b370b4a2b20f94425cf8f90aab01b146532..b701835c38089a97f34633151218ceb83f91e73c 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -28,7 +28,7 @@ define Package/wavemon
   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
index 8c26f7051ccadbf6a0d2d6236d0bb62c40cbb2e1..98e748c4d4bd37b165e83384018c481a1097abc4 100644 (file)
@@ -15,8 +15,8 @@
 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> 
@@ -53,6 +53,18 @@ define Package/wifischedule/install
        $(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))
index 6d53da5f5a583ac0da3f245ee0b7643d54e916f7..7b40eb87d2518ab7fdfe60f698396163de9f8d11 100644 (file)
@@ -74,10 +74,11 @@ Then call the script as follows in order to get the necessary cron jobs created:
 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.
@@ -85,3 +86,6 @@ wifi_schedule.sh cron|start|stop|forcestop|recheck|getmodules|savemodules|help
     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.
diff --git a/net/wifischedule/net/etc/init.d/wifi_schedule b/net/wifischedule/net/etc/init.d/wifi_schedule
new file mode 100644 (file)
index 0000000..9156fdc
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh /etc/rc.common
+# Startup Script for wifi_schedule
+
+START=100
+
+start() {
+    /usr/bin/wifi_schedule.sh startup
+}
index be483d0bc680fc68b8c50ca3236d862c5d2128b5..9787bc37d101180428fa97afeb450a9065c988ed 100755 (executable)
@@ -14,6 +14,8 @@
 #
 # Author: Nils Koenig <openwrt@newk.it>
 
+set -o pipefail
+
 SCRIPT=$0
 LOCKFILE=/tmp/wifi_schedule.lock
 LOGFILE=/tmp/log/wifi_schedule.log
@@ -122,10 +124,46 @@ _enable_wifi_schedule()
     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" "
 }
 
 
@@ -218,6 +256,38 @@ _create_cron_entries()
     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
@@ -231,7 +301,7 @@ check_cron_status()
 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
@@ -241,7 +311,7 @@ disable_wifi()
 
 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"
@@ -261,14 +331,18 @@ soft_disable_wifi()
         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)
@@ -276,6 +350,17 @@ soft_disable_wifi()
     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"
@@ -284,18 +369,20 @@ enable_wifi()
     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."
@@ -305,16 +392,28 @@ usage()
     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 ;;
index 971a8a78de7ac9b9288f51774d5f4161caf98791..fb0f89a231d1587230fba3f22952cdb5941b9501 100644 (file)
@@ -1,12 +1,12 @@
 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
index a40a9f5be82c845555b92386121f9ac559726f76..71d6b5f48abe00646250d2b9936717f152cb1ec8 100644 (file)
@@ -1,12 +1,12 @@
 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>
@@ -33,7 +33,7 @@ define Package/yggdrasil
        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
@@ -46,14 +46,9 @@ 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) \
@@ -65,16 +60,8 @@ define Package/yggdrasil/install
                $(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))
diff --git a/net/yggdrasil/files/yggdrasil.defaults b/net/yggdrasil/files/yggdrasil.defaults
deleted file mode 100644 (file)
index 2697262..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/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
diff --git a/net/yggdrasil/files/yggdrasil.init b/net/yggdrasil/files/yggdrasil.init
deleted file mode 100755 (executable)
index 3510e3a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/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
-}
diff --git a/net/yggdrasil/files/yggdrasil.sh b/net/yggdrasil/files/yggdrasil.sh
new file mode 100755 (executable)
index 0000000..9d3c6c3
--- /dev/null
@@ -0,0 +1,205 @@
+#!/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
+}
diff --git a/net/yggdrasil/files/ygguci b/net/yggdrasil/files/ygguci
deleted file mode 100755 (executable)
index cdeb3c1..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-#!/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
index 6eefb3a7a9ff3daefeebd1df9004367cfc3fbe03..e9c1426a14600c48614b0d24e44b4ff3976c0961 100644 (file)
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 
 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)?
index a919dacea131f4babc00791a9b3250c4f6687b91..84002f9526f7956c90392b2205abbc56834592b9 100755 (executable)
@@ -18,7 +18,7 @@ start_instance() {
        local args=""
 
        if ! section_enabled "$cfg"; then
-               echo "disabled in /ect/config/zerotier"
+               echo "disabled in /etc/config/zerotier"
                return 1
        fi
 
index 0c4ba66a9a58f8e1f42ff3adb2cdd4da820454b1..108da781d28924f916602eb4c395b1df3aa78f12 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -32,7 +32,7 @@ CATEGORY:=Sound
 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
@@ -54,8 +54,7 @@ CONFIGURE_ARGS += \
        --disable-install_conf_file \
        --disable-install_user \
        --with-alsa \
-       --without-pulseaudio \
-       --without-libevent_pthreads
+       --without-pulseaudio
 
 TARGET_CFLAGS += $(FPIC)
 
index 24f604e9d93b08f2122f83f54290451c1cfed728..9c1606dabaac6b1b43c7f0fb7bda382a3c32a2d2 100644 (file)
@@ -8,12 +8,12 @@
 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
@@ -29,7 +29,7 @@ include $(INCLUDE_DIR)/meson.mk
 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/
@@ -45,7 +45,7 @@ endef
 
 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
@@ -121,19 +121,22 @@ MESON_ARGS += \
        -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
 
@@ -183,8 +186,8 @@ define Package/pulseaudio-daemon/install
        $(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
diff --git a/sound/pulseaudio/patches/010-iconv.patch b/sound/pulseaudio/patches/010-iconv.patch
deleted file mode 100644 (file)
index 8da46b9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
---- 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)
diff --git a/sound/pulseaudio/patches/010-meson_gio.patch b/sound/pulseaudio/patches/010-meson_gio.patch
new file mode 100644 (file)
index 0000000..3f7f4d9
--- /dev/null
@@ -0,0 +1,11 @@
+--- 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)
diff --git a/sound/pulseaudio/patches/020-doxygen.patch b/sound/pulseaudio/patches/020-doxygen.patch
deleted file mode 100644 (file)
index 1333943..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- 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')
diff --git a/sound/shairplay/Makefile b/sound/shairplay/Makefile
deleted file mode 100644 (file)
index 0b303da..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#
-# 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))
diff --git a/sound/shairplay/files/shairplay.config b/sound/shairplay/files/shairplay.config
deleted file mode 100644 (file)
index 6e1f939..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-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 ''
diff --git a/sound/shairplay/files/shairplay.init b/sound/shairplay/files/shairplay.init
deleted file mode 100644 (file)
index 093a168..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/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
-}
diff --git a/sound/shairplay/patches/001-key_file_dir.patch b/sound/shairplay/patches/001-key_file_dir.patch
deleted file mode 100644 (file)
index af9bd84..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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");
diff --git a/sound/shairplay/patches/003-fix_big-endian.patch b/sound/shairplay/patches/003-fix_big-endian.patch
deleted file mode 100644 (file)
index 4db204e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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>
diff --git a/sound/shairplay/patches/010-configure-only-check-for-dns_sd.h-in-case-libdl-was-.patch b/sound/shairplay/patches/010-configure-only-check-for-dns_sd.h-in-case-libdl-was-.patch
deleted file mode 100644 (file)
index 84db6b8..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-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.])])
index 6d7a0626c4f3b226ddbcad9317589a688b54b108..b46318513220cf8ef9101c1ac8b8641425ca8f00 100644 (file)
@@ -8,12 +8,12 @@
 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
index b1471c7c08939c9e7f4a31854a6934728f5f9ee1..e415b14d0ec334f0f1e4da2d866e39065442db0e 100644 (file)
@@ -22,6 +22,7 @@ PKG_LICENSE:=GPL-2.0
 PKG_FORTIFY_SOURCE:=0
 PKG_BUILD_PARALLEL:=1
 
+include $(INCLUDE_DIR)/host-build.mk
 include $(INCLUDE_DIR)/package.mk
 
 define Package/acpica-unix
@@ -43,6 +44,25 @@ endef
 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
@@ -55,3 +75,4 @@ define Package/acpica-unix/install
 endef
 
 $(eval $(call BuildPackage,acpica-unix))
+$(eval $(call HostBuild))
index 23461f998488d76ccf0e4a9325d6ea331f3e41f4..207ed5f1b50527fc14e996fa009c19144b9ae889 100644 (file)
@@ -17,6 +17,7 @@ PKG_LICENSE:=GPL-3.0-or-later
 PKG_LICENSE_FILES:=LICENCE
 
 PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
 
 include $(INCLUDE_DIR)/package.mk
 include ../../lang/rust/rust-package.mk
index 5d78af25e7ffe9784d289368002f30956a2258e8..973c171a3c3094a66ade710c42bf43676e5bdac4 100644 (file)
@@ -1,21 +1,19 @@
 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
diff --git a/utils/cligen/Makefile b/utils/cligen/Makefile
new file mode 100644 (file)
index 0000000..f15d9cd
--- /dev/null
@@ -0,0 +1,61 @@
+#
+# 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))
diff --git a/utils/clixon/Makefile b/utils/clixon/Makefile
new file mode 100644 (file)
index 0000000..44209b8
--- /dev/null
@@ -0,0 +1,93 @@
+#
+# 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))
+
diff --git a/utils/clixon/files/clixon.init b/utils/clixon/files/clixon.init
new file mode 100755 (executable)
index 0000000..edf9b1a
--- /dev/null
@@ -0,0 +1,35 @@
+#!/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"
+}
diff --git a/utils/clixon/files/netconf-subsystem.conf b/utils/clixon/files/netconf-subsystem.conf
new file mode 100644 (file)
index 0000000..d40316f
--- /dev/null
@@ -0,0 +1 @@
+Subsystem      netconf         /usr/bin/clixon_netconf
diff --git a/utils/clixon/files/restconf.xml b/utils/clixon/files/restconf.xml
new file mode 100644 (file)
index 0000000..a170b36
--- /dev/null
@@ -0,0 +1,13 @@
+<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>
index 332c7844a1fd444f2b54a5ec133815e4fbef46d0..9971adee5a8dc7e42b98a8225361085b4ea4d33e 100644 (file)
@@ -1,12 +1,12 @@
 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
diff --git a/utils/cudy-bdinfo/Makefile b/utils/cudy-bdinfo/Makefile
new file mode 100644 (file)
index 0000000..7d56ffb
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# 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))
index ca6a0430086650875af967a574b1cc7501900a37..35a95114b159258320ec444f95e5d449f5b59b84 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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)
@@ -26,7 +26,7 @@ include $(INCLUDE_DIR)/package.mk
 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
index 1d3e7424f0dcb1be605f9edee3b08607ad391b27..5a09ef79c65965c91d87674effb311680e067b2d 100644 (file)
@@ -1,14 +1,14 @@
 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>
 
index 7d1f5ce3986cc9fd45f283f5cf83d4d5ede4aa19..9e8a012e1a3d0e7218a25bf916b576920c0bec0f 100644 (file)
@@ -8,12 +8,12 @@
 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
diff --git a/utils/domoticz/patches/010-gcc12.patch b/utils/domoticz/patches/010-gcc12.patch
deleted file mode 100644 (file)
index 676e6a3..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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)
- {
diff --git a/utils/domoticz/patches/012-minizip-overflow.patch b/utils/domoticz/patches/012-minizip-overflow.patch
deleted file mode 100644 (file)
index 570ebfc..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-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;
diff --git a/utils/domoticz/patches/990-python3.10_fix.patch b/utils/domoticz/patches/990-python3.10_fix.patch
deleted file mode 100644 (file)
index 8f0c867..0000000
+++ /dev/null
@@ -1,4364 +0,0 @@
-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&param2=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, &ltime);
-                               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
diff --git a/utils/domoticz/patches/991-linux_crash_when_formating_py.patch b/utils/domoticz/patches/991-linux_crash_when_formating_py.patch
deleted file mode 100644 (file)
index 1955b25..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-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();
diff --git a/utils/domoticz/patches/992-prevent_crash_processing_py.patch b/utils/domoticz/patches/992-prevent_crash_processing_py.patch
deleted file mode 100644 (file)
index 32b7653..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-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(),
diff --git a/utils/domoticz/patches/994-compile_err_whitout_py.patch b/utils/domoticz/patches/994-compile_err_whitout_py.patch
deleted file mode 100644 (file)
index d8bbfa6..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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
diff --git a/utils/domoticz/patches/995-make_sure_compile_works_without_py.patch b/utils/domoticz/patches/995-make_sure_compile_works_without_py.patch
deleted file mode 100644 (file)
index a55bafc..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-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
-+
diff --git a/utils/dysk/Makefile b/utils/dysk/Makefile
new file mode 100644 (file)
index 0000000..cc559b0
--- /dev/null
@@ -0,0 +1,41 @@
+# 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))
index fc53f8729472926a7d44fe6e4881afc817c3385e..1463a6c820784809e80d14f7cd2d55f27292df78 100644 (file)
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
 
 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
@@ -23,7 +23,7 @@ define Package/efibootmgr
   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
 
index 3a47a8a766c57cf519089b4d923be42741aefc4d..81541493d181e91f7b10170a7557a2a5c71e82db 100644 (file)
@@ -9,17 +9,19 @@ include $(TOPDIR)/rules.mk
 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
 
diff --git a/utils/fx/Makefile b/utils/fx/Makefile
new file mode 100644 (file)
index 0000000..9642d60
--- /dev/null
@@ -0,0 +1,38 @@
+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))
diff --git a/utils/gl-puli-mcu/Config.in b/utils/gl-puli-mcu/Config.in
new file mode 100644 (file)
index 0000000..315526c
--- /dev/null
@@ -0,0 +1,12 @@
+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
index d33e9288f3062dc2360994eac8c2ac136f8b15cd..b1da42c77748ae49943db705e4f3d35db80e9506 100644 (file)
@@ -1,24 +1,40 @@
 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.
index fe55cc42d3003135fb6f75da4ad0949ef6b48c04..da7d7db8391477cca0cedf71ee4d996b3894465b 100644 (file)
 #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;
@@ -39,6 +50,9 @@ struct Battery
        bool set;
 } battery;
 
+#if GL_TARGET == GL_TARGET_XE300
+// MCU status returns something like:
+// {OK},100,275,1,0
 static bool
 process(char *read)
 {
@@ -66,6 +80,65 @@ 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)
@@ -79,7 +152,7 @@ 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;
@@ -202,7 +275,7 @@ main(int argc, char **argv)
        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;
index b1e6d052ecb4b0b4d07c94b90e609836eb0a885a..688764e43ccda647dece2c0862e8f5e24082b4f2 100644 (file)
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 
 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/
diff --git a/utils/gummiboot/patches/030-fix-efi-conflicts.patch b/utils/gummiboot/patches/030-fix-efi-conflicts.patch
new file mode 100644 (file)
index 0000000..51b28d4
--- /dev/null
@@ -0,0 +1,66 @@
+--- 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;
index 6717c352e56d3cb410f21c00348cc24f46cfbf79..83f07da8494445c9ced1b2b187cff4142e8bfffb 100644 (file)
@@ -5,13 +5,13 @@
 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
diff --git a/utils/irqbalance/patches/001-upstream-fix-aarch64-irq-parsing.patch b/utils/irqbalance/patches/001-upstream-fix-aarch64-irq-parsing.patch
deleted file mode 100644 (file)
index 33213f0..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-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
index 7e3ae36d82afd98d566646993061795d7e248860..71a8ebae7f1ce3eaea7856bf01d44bb2dbc42031 100644 (file)
@@ -4,6 +4,9 @@ Date: Fri, 10 Jun 2022 23:14:27 -0700
 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 +++++++++++
@@ -15,7 +18,7 @@ Signed-off-by: Rosen Penev <rosenp@gmail.com>
 +++ b/meson.build
 @@ -0,0 +1,43 @@
 +project('irqbalance', 'c',
-+  version : '1.9.0',
++  version : '1.9.3',
 +  default_options : ['warning_level=1']
 +)
 +
diff --git a/utils/irqbalance/patches/020-mark-EINVAL-error-permanent.patch b/utils/irqbalance/patches/020-mark-EINVAL-error-permanent.patch
new file mode 100644 (file)
index 0000000..44eb15d
--- /dev/null
@@ -0,0 +1,15 @@
+--- 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;
index ed9a6a19840633ce83016a8fc05ba4b40b97d852..4b10747189916d3005f9ff3d82c7373144b1bea4 100644 (file)
@@ -8,12 +8,12 @@
 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
index a49b053c49025105e30a4f6a6cc27c6f6bd73c9e..11a774dce608bfd928f9156bf1ad7312b16a112a 100644 (file)
@@ -1,6 +1,4 @@
 #
-# Copyright (C) 2007-2015 OpenWrt.org
-#
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
 #
@@ -9,17 +7,17 @@ include $(TOPDIR)/rules.mk
 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
 
@@ -31,36 +29,7 @@ define Package/lsof
   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
diff --git a/utils/lsof/patches/000-disable-man.patch b/utils/lsof/patches/000-disable-man.patch
new file mode 100644 (file)
index 0000000..cf9a391
--- /dev/null
@@ -0,0 +1,18 @@
+--- 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
diff --git a/utils/lsof/patches/001-lsof_makefile.patch b/utils/lsof/patches/001-lsof_makefile.patch
deleted file mode 100644 (file)
index eb2b735..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- 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
diff --git a/utils/lsof/patches/002-lsof_noportmap.patch b/utils/lsof/patches/002-lsof_noportmap.patch
deleted file mode 100644 (file)
index 825f255..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
---- 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) */
diff --git a/utils/lsof/patches/003-lsof_selinux.patch b/utils/lsof/patches/003-lsof_selinux.patch
deleted file mode 100644 (file)
index ee1426d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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"
diff --git a/utils/lsof/patches/004-lsof_ccv.patch b/utils/lsof/patches/004-lsof_ccv.patch
deleted file mode 100644 (file)
index 1f4e57c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- 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"   # {
index 28dbad66fc6c3a13a7d7a313a68ee817e889e485..8ff5a85df4b81c1565f1f0c27f7d7d1bb262476b 100644 (file)
@@ -6,15 +6,15 @@
 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
@@ -57,7 +57,6 @@ CONFIGURE_ARGS += \
        --enable-silent-rules \
        --disable-tests \
        --disable-doxygen-doc \
-       --with-homedir=/etc/mc \
        --with-screen=ncurses \
        --without-x \
 
@@ -99,7 +98,7 @@ define Package/mc/install
        $(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
index bc7ddee5fa6ef4ed412e6411ba666343c4c0a8dd..64f3fdba91eb325e3668552b58ca1e971c62da9d 100644 (file)
@@ -1,6 +1,6 @@
 --- 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; "
index bf6853a710245088d9e0f861d207c0bb488dff38..1d122f678418f434f6e7bc2f8392559b6f871856 100644 (file)
@@ -1,6 +1,6 @@
 --- 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)
index 0191be0e6825898478dac9c8db418d35f2e05a61..37274c14c10b3313454b32e4709aafbb8e9b73e6 100644 (file)
@@ -1,6 +1,6 @@
 --- 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");
@@ -9,7 +9,7 @@
      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";
      }
@@ -34,7 +34,7 @@
      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;
  
@@ -46,7 +46,7 @@
          /* 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:
@@ -54,7 +54,7 @@
      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;
diff --git a/utils/mpremote/Makefile b/utils/mpremote/Makefile
new file mode 100644 (file)
index 0000000..af69d80
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# 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))
diff --git a/utils/mpremote/patches/001-no-importlib_metadata.patch b/utils/mpremote/patches/001-no-importlib_metadata.patch
new file mode 100644 (file)
index 0000000..6f5fc49
--- /dev/null
@@ -0,0 +1,5 @@
+--- a/requirements.txt
++++ b/requirements.txt
+@@ -1,2 +1 @@
+ pyserial >= 3.3
+-importlib_metadata >= 1.4
diff --git a/utils/mpremote/test.sh b/utils/mpremote/test.sh
new file mode 100644 (file)
index 0000000..3010c24
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$1" = mpremote ] || exit 0
+
+mpremote version | grep -Fx "mpremote $PKG_VERSION"
index e68b289501af04534dfbc5e4d3fdb74d4df9c2b4..4400b780f2d66434cb008f38a6178128f7f0c6e4 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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
@@ -140,6 +140,7 @@ define Package/nano-full/install
        $(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
 
diff --git a/utils/nano/files/ucode.nanorc b/utils/nano/files/ucode.nanorc
new file mode 100644 (file)
index 0000000..96c7848
--- /dev/null
@@ -0,0 +1,51 @@
+## 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 "\{#[+-]?|-?#\}"
diff --git a/utils/nerdctl/Makefile b/utils/nerdctl/Makefile
new file mode 100644 (file)
index 0000000..ea19ec4
--- /dev/null
@@ -0,0 +1,38 @@
+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))
index 11afb8765c8a0a88064e55aff7a06cf52037a7fc..cdcc2be54eda65f1ef9b7beff2a6dec0965bfcf0 100644 (file)
@@ -1,12 +1,12 @@
 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
@@ -39,7 +39,7 @@ define Package/podman
   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
index 13d3fb2955ca77e3091724211eb2ae4b1326b5ca..b956f0db0fd849cb2eb64dc1634aa075274bf153 100644 (file)
@@ -3,11 +3,14 @@
 [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"
 
@@ -29,30 +32,116 @@ default_sysctls = [
   "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 = [
@@ -67,8 +156,19 @@ uxc = [
        "/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]
index c64c4bd07912fd7d88ff232a7f81b35d1d043833..b2f1efd496f32f030063012d6e1a7100d900b444 100644 (file)
@@ -1,6 +1,6 @@
 --- a/Makefile
 +++ b/Makefile
-@@ -219,7 +219,7 @@ GV_SHA=db608827124caa71ba411cec8ea959bb9
+@@ -224,7 +224,7 @@ GV_VERSION=v0.7.1
  default: all
  
  .PHONY: all
@@ -9,7 +9,7 @@
  
  .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
diff --git a/utils/podman/patches/020-fix-build-with-musl-1.2.4.patch b/utils/podman/patches/020-fix-build-with-musl-1.2.4.patch
new file mode 100644 (file)
index 0000000..9d56ca7
--- /dev/null
@@ -0,0 +1,16 @@
+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
index 5ac3dc5fefbe92a9cc0cada988c2a11abec96166..cbcb82be817adaa1a35d68e3558a1e96eab82e19 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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
diff --git a/utils/pps-tools/patches/001-time_t_64bit.patch b/utils/pps-tools/patches/001-time_t_64bit.patch
new file mode 100644 (file)
index 0000000..aacd8be
--- /dev/null
@@ -0,0 +1,31 @@
+--- 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++;
diff --git a/utils/procs/Makefile b/utils/procs/Makefile
new file mode 100644 (file)
index 0000000..bb8c639
--- /dev/null
@@ -0,0 +1,55 @@
+# 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))
diff --git a/utils/procs/files/etc/procs/procs.toml b/utils/procs/files/etc/procs/procs.toml
new file mode 100644 (file)
index 0000000..ee25012
--- /dev/null
@@ -0,0 +1,138 @@
+[[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
+
index a69f5320d604ca6a3ca6d43f7d97a43d0eed9f50..f787d0e8a8489e43adc95cc8996316b29ea9668d 100644 (file)
@@ -4,7 +4,7 @@
 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>
@@ -103,6 +103,17 @@ define Package/prometheus-node-exporter-lua-hostapd_ubus_stations/install
        $(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)
@@ -158,6 +169,17 @@ define Package/prometheus-node-exporter-lua-textfile/install
        $(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)
@@ -229,11 +251,13 @@ $(eval $(call BuildPackage,prometheus-node-exporter-lua-bmx7))
 $(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))
diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/hwmon.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/hwmon.lua
new file mode 100644 (file)
index 0000000..3e00f05
--- /dev/null
@@ -0,0 +1,58 @@
+#!/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 }
diff --git a/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/thermal.lua b/utils/prometheus-node-exporter-lua/files/usr/lib/lua/prometheus-collectors/thermal.lua
new file mode 100644 (file)
index 0000000..3996ea5
--- /dev/null
@@ -0,0 +1,46 @@
+-- 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 }
diff --git a/utils/prometheus-node-exporter-ucode/Makefile b/utils/prometheus-node-exporter-ucode/Makefile
new file mode 100644 (file)
index 0000000..3d712c1
--- /dev/null
@@ -0,0 +1,74 @@
+# 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))
diff --git a/utils/prometheus-node-exporter-ucode/files/base/conntrack.uc b/utils/prometheus-node-exporter-ucode/files/base/conntrack.uc
new file mode 100644 (file)
index 0000000..b3ee3f3
--- /dev/null
@@ -0,0 +1,4 @@
+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"));
diff --git a/utils/prometheus-node-exporter-ucode/files/base/cpu.uc b/utils/prometheus-node-exporter-ucode/files/base/cpu.uc
new file mode 100644 (file)
index 0000000..574655d
--- /dev/null
@@ -0,0 +1,44 @@
+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]);
+}
diff --git a/utils/prometheus-node-exporter-ucode/files/base/entropy.uc b/utils/prometheus-node-exporter-ucode/files/base/entropy.uc
new file mode 100644 (file)
index 0000000..2df4426
--- /dev/null
@@ -0,0 +1,4 @@
+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"));
diff --git a/utils/prometheus-node-exporter-ucode/files/base/filefd.uc b/utils/prometheus-node-exporter-ucode/files/base/filefd.uc
new file mode 100644 (file)
index 0000000..359cffd
--- /dev/null
@@ -0,0 +1,7 @@
+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]);
diff --git a/utils/prometheus-node-exporter-ucode/files/base/loadavg.uc b/utils/prometheus-node-exporter-ucode/files/base/loadavg.uc
new file mode 100644 (file)
index 0000000..ba67daf
--- /dev/null
@@ -0,0 +1,8 @@
+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]);
diff --git a/utils/prometheus-node-exporter-ucode/files/base/meminfo.uc b/utils/prometheus-node-exporter-ucode/files/base/meminfo.uc
new file mode 100644 (file)
index 0000000..3cecb12
--- /dev/null
@@ -0,0 +1,24 @@
+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]);
+}
diff --git a/utils/prometheus-node-exporter-ucode/files/base/netclass.uc b/utils/prometheus-node-exporter-ucode/files/base/netclass.uc
new file mode 100644 (file)
index 0000000..10b3cfd
--- /dev/null
@@ -0,0 +1,48 @@
+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);
+}
diff --git a/utils/prometheus-node-exporter-ucode/files/base/netdev.uc b/utils/prometheus-node-exporter-ucode/files/base/netdev.uc
new file mode 100644 (file)
index 0000000..f8fc68d
--- /dev/null
@@ -0,0 +1,40 @@
+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]);
+}
diff --git a/utils/prometheus-node-exporter-ucode/files/base/selinux.uc b/utils/prometheus-node-exporter-ucode/files/base/selinux.uc
new file mode 100644 (file)
index 0000000..11840a8
--- /dev/null
@@ -0,0 +1,10 @@
+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);
diff --git a/utils/prometheus-node-exporter-ucode/files/base/time.uc b/utils/prometheus-node-exporter-ucode/files/base/time.uc
new file mode 100644 (file)
index 0000000..7d13ea8
--- /dev/null
@@ -0,0 +1 @@
+gauge("node_time_seconds")(null, time());
diff --git a/utils/prometheus-node-exporter-ucode/files/base/uname.uc b/utils/prometheus-node-exporter-ucode/files/base/uname.uc
new file mode 100644 (file)
index 0000000..50cb352
--- /dev/null
@@ -0,0 +1,8 @@
+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);
diff --git a/utils/prometheus-node-exporter-ucode/files/config b/utils/prometheus-node-exporter-ucode/files/config
new file mode 100644 (file)
index 0000000..8741f4a
--- /dev/null
@@ -0,0 +1,7 @@
+config prometheus-node-exporter-ucode 'main'
+       option listen_interface 'loopback'
+       option listen_port '9101'
+       option http_keepalive '70'
+
+config collector 'wifi'
+       option stations '1'
diff --git a/utils/prometheus-node-exporter-ucode/files/extra/dnsmasq.uc b/utils/prometheus-node-exporter-ucode/files/extra/dnsmasq.uc
new file mode 100644 (file)
index 0000000..3644b20
--- /dev/null
@@ -0,0 +1,6 @@
+const x = ubus.call("dnsmasq", "metrics");
+if (!x)
+       return false;
+
+for (let i in x)
+       gauge(`dnsmasq_${i}_total`)(null, x[i]);
diff --git a/utils/prometheus-node-exporter-ucode/files/extra/ltq-dsl.uc b/utils/prometheus-node-exporter-ucode/files/extra/ltq-dsl.uc
new file mode 100644 (file)
index 0000000..1644497
--- /dev/null
@@ -0,0 +1,72 @@
+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);
diff --git a/utils/prometheus-node-exporter-ucode/files/extra/netstat.uc b/utils/prometheus-node-exporter-ucode/files/extra/netstat.uc
new file mode 100644 (file)
index 0000000..7449305
--- /dev/null
@@ -0,0 +1,30 @@
+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;
diff --git a/utils/prometheus-node-exporter-ucode/files/extra/openwrt.uc b/utils/prometheus-node-exporter-ucode/files/extra/openwrt.uc
new file mode 100644 (file)
index 0000000..10c15a1
--- /dev/null
@@ -0,0 +1,14 @@
+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);
diff --git a/utils/prometheus-node-exporter-ucode/files/extra/snmp6.uc b/utils/prometheus-node-exporter-ucode/files/extra/snmp6.uc
new file mode 100644 (file)
index 0000000..d440a88
--- /dev/null
@@ -0,0 +1,23 @@
+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);
diff --git a/utils/prometheus-node-exporter-ucode/files/extra/uci_dhcp_host.uc b/utils/prometheus-node-exporter-ucode/files/extra/uci_dhcp_host.uc
new file mode 100644 (file)
index 0000000..0d55724
--- /dev/null
@@ -0,0 +1,14 @@
+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);
+});
diff --git a/utils/prometheus-node-exporter-ucode/files/extra/wifi.uc b/utils/prometheus-node-exporter-ucode/files/extra/wifi.uc
new file mode 100644 (file)
index 0000000..f5f58ef
--- /dev/null
@@ -0,0 +1,118 @@
+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"]);
+               }
+       }
+}
diff --git a/utils/prometheus-node-exporter-ucode/files/extra/wireguard.uc b/utils/prometheus-node-exporter-ucode/files/extra/wireguard.uc
new file mode 100644 (file)
index 0000000..12ae56a
--- /dev/null
@@ -0,0 +1,49 @@
+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"]);
+       }
+}
diff --git a/utils/prometheus-node-exporter-ucode/files/init b/utils/prometheus-node-exporter-ucode/files/init
new file mode 100644 (file)
index 0000000..1735236
--- /dev/null
@@ -0,0 +1,73 @@
+#!/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"
+}
diff --git a/utils/prometheus-node-exporter-ucode/files/metrics.uc b/utils/prometheus-node-exporter-ucode/files/metrics.uc
new file mode 100644 (file)
index 0000000..3dce77a
--- /dev/null
@@ -0,0 +1,227 @@
+{%
+'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)),
+       });
+}
+%}
diff --git a/utils/prometheus-node-exporter-ucode/files/run.sh b/utils/prometheus-node-exporter-ucode/files/run.sh
new file mode 100755 (executable)
index 0000000..a7cefef
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /usr/bin/ucode -T /usr/share/ucode/node-exporter/metrics.uc $*
diff --git a/utils/prometheus-node-exporter-ucode/test.sh b/utils/prometheus-node-exporter-ucode/test.sh
new file mode 100755 (executable)
index 0000000..e72942b
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+prometheus-node-exporter-ucode time
index 4f99c320d4907493c78413f7d4ce564accd3e9c2..5e9851b06d748f244bca7d715b2d1bb665380b74 100644 (file)
@@ -9,10 +9,10 @@
 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
@@ -392,7 +392,7 @@ CONFIGURE_ARGS +=                   \
        --disable-docs                  \
        --disable-fuse                  \
        --disable-gcrypt                \
-       --with-git-submodules=ignore    \
+       --disable-download              \
        --disable-glusterfs             \
        --disable-gnutls                \
        --disable-guest-agent-msi       \
index 434b3d15ab4f5b3eebacc0b0cf94a413f1914217..e893c1788f47b30f944accf49bcb8539ebc97832 100644 (file)
@@ -11,9 +11,9 @@ OpenWrt base build system decide flavor of fortify_source to use
 
 --- 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"
 +  ;;
index e09447bd1ef81a096f5fd9b95ef7ba35d0d38af8..f8bfa67c2abc7dfeec5d25e310ff4b8cd4bbc5bb 100644 (file)
@@ -32,9 +32,9 @@ Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
  #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
index 9c36a3914ec592fa77fa7438a605b5cb619e4a10..3df92e30ddedc0e815d11a052cbe2bcc068f3755 100644 (file)
@@ -1,6 +1,6 @@
 --- 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')
  
@@ -11,7 +11,7 @@
  # 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')
diff --git a/utils/quectel-timesync/Makefile b/utils/quectel-timesync/Makefile
new file mode 100644 (file)
index 0000000..f624683
--- /dev/null
@@ -0,0 +1,51 @@
+# 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))
index 05156391ca413709e2af4f0075b2962bf9011f91..89963c085366db9c08b261c7637d75ba54b8ac08 100644 (file)
@@ -1,12 +1,12 @@
 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
index 56658540f99f2fe6f2eab9add65dd44c39c2003b..bad9f95e2492b7f538dab2225b0a9be0e2dfaac5 100644 (file)
@@ -17,6 +17,7 @@ PKG_LICENSE:=MIT Unlicense
 PKG_LICENSE_FILES:=LICENSE-MIT UNLICENSE
 
 PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
 
 RUST_PKG_FEATURES:=pcre2
 
diff --git a/utils/rpcd-mod-wireguard/Makefile b/utils/rpcd-mod-wireguard/Makefile
new file mode 100644 (file)
index 0000000..9fb7d7e
--- /dev/null
@@ -0,0 +1,31 @@
+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))
diff --git a/utils/rpcd-mod-wireguard/src/CMakeLists.txt b/utils/rpcd-mod-wireguard/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..97e06aa
--- /dev/null
@@ -0,0 +1,10 @@
+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)
diff --git a/utils/rpcd-mod-wireguard/src/api.c b/utils/rpcd-mod-wireguard/src/api.c
new file mode 100644 (file)
index 0000000..e80ed53
--- /dev/null
@@ -0,0 +1,245 @@
+// 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
+};
diff --git a/utils/rpcd-mod-wireguard/src/wireguard.c b/utils/rpcd-mod-wireguard/src/wireguard.c
new file mode 100644 (file)
index 0000000..4941549
--- /dev/null
@@ -0,0 +1,1755 @@
+// 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);
+}
diff --git a/utils/rpcd-mod-wireguard/src/wireguard.h b/utils/rpcd-mod-wireguard/src/wireguard.h
new file mode 100644 (file)
index 0000000..328fcb4
--- /dev/null
@@ -0,0 +1,105 @@
+/* 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
index 52daf82b1fec096ad22ec9c73dce38ae768c0374..305c56d7888e9d5f8af6a7d87bdea28cc73dacb6 100644 (file)
@@ -4,8 +4,8 @@
 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
@@ -13,13 +13,12 @@ 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
index c685bce71b89ce4eb9f9156bca6596f74bb85812..b6d0713a96c9567a54fb5090c03a48f25fe768c0 100644 (file)
@@ -7,57 +7,65 @@
 #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;
 }
index 0edf09f17c6213cfc5a300eac2eb54376493c4c7..11a4cbf22bfca4de4fde12a254bcc259cb1c1e78 100644 (file)
@@ -6,12 +6,12 @@
 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
index b4ec4c303b4a0218359dd0f7565edfbc62579989..c9dd59cfeb17ca2dcd354182c3df3f9de3f37977 100644 (file)
@@ -1,8 +1,8 @@
 --- 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 \
@@ -11,5 +11,5 @@
 +      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))
diff --git a/utils/stress-ng/patches/002-core-stress-Add-musl-gcc-detection-and-HAVE_COMPILER.patch b/utils/stress-ng/patches/002-core-stress-Add-musl-gcc-detection-and-HAVE_COMPILER.patch
new file mode 100644 (file)
index 0000000..1b16110
--- /dev/null
@@ -0,0 +1,531 @@
+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
diff --git a/utils/stress-ng/patches/002-disable-compiler-test.patch b/utils/stress-ng/patches/002-disable-compiler-test.patch
deleted file mode 100644 (file)
index 886b3a6..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
---- 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
diff --git a/utils/stress-ng/test.sh b/utils/stress-ng/test.sh
new file mode 100644 (file)
index 0000000..0b70f7c
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh -e
+
+stress-ng --version | grep "$2"
index e8b744a463227240a43e6f601ee1b643c2287186..71d7880c482d77fe4e02f771f14e64746fb03f66 100644 (file)
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
 
 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)
index 3ec81e593658600c50e6c35c4cc4734883607af3..7bcb90daea5e69e95525d3e2fd24782e400f6c62 100644 (file)
@@ -14,7 +14,7 @@ config_cb() {
                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)
index 4660fa78696a7ac80b106f286c9f2a4ace742b4c..89af1cbe65d041b70417e08cbefd32ae741ff58f 100644 (file)
@@ -9,13 +9,13 @@ include $(TOPDIR)/rules.mk
 
 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
 
index ea4045f2e1929df2684926cea6a9d0781d5a2ecf..efcd3f2ccf783492126032b3004eff202d5c1485 100644 (file)
@@ -8,6 +8,7 @@ start_service() {
        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"
index db43e08e6b5f7d7038a56c92c46d43bcc057a149..faed81050f4cc88ae9e3916d308441c8d0043585 100644 (file)
@@ -7,12 +7,12 @@
 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
@@ -36,15 +36,17 @@ TARGET_CFLAGS:=$(filter-out -O%,$(TARGET_CFLAGS)) -O3
 
 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
index 2a9f88c79ef6eca2f863a030269a4603809bb34a..d6064660df5d46dc4cbc14184c35466e89e51759 100644 (file)
@@ -1,18 +1,27 @@
---- 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)
diff --git a/utils/tesseract/patches/020-musl.patch b/utils/tesseract/patches/020-musl.patch
deleted file mode 100644 (file)
index 821a51d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- 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
index 6400b4807a1de13834272ca1b3357fcc3db787cc..b4283c09baf69c82ee4af9c8aa930795ec0159b2 100644 (file)
@@ -1,12 +1,12 @@
 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
index 6fc713a5db0ed8abd4543d5b1522ba0dca1fce5b..e894bc6eeb3ea38a2bc88cbad78776db346d33b9 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 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
@@ -20,10 +20,19 @@ PKG_LICENSE:=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
@@ -31,7 +40,7 @@ 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
 
diff --git a/utils/zsh/patches/001-50658-test-Enable-to-switch-between-C-UTF-8-locales-.patch b/utils/zsh/patches/001-50658-test-Enable-to-switch-between-C-UTF-8-locales-.patch
new file mode 100644 (file)
index 0000000..79e352a
--- /dev/null
@@ -0,0 +1,71 @@
+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
diff --git a/utils/zsh/patches/002-51723-migrate-pcre-module-to-pcre2.patch b/utils/zsh/patches/002-51723-migrate-pcre-module-to-pcre2.patch
new file mode 100644 (file)
index 0000000..6e0b7f1
--- /dev/null
@@ -0,0 +1,540 @@
+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 \
diff --git a/utils/zsh/patches/003-51728-assign-pcre-named-capture-groups-to-a-hash.patch b/utils/zsh/patches/003-51728-assign-pcre-named-capture-groups-to-a-hash.patch
new file mode 100644 (file)
index 0000000..4b59218
--- /dev/null
@@ -0,0 +1,180 @@
+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
++>)
diff --git a/utils/zsh/patches/004-51738-support-pcre-s-alternative-DFA-matching-algori.patch b/utils/zsh/patches/004-51738-support-pcre-s-alternative-DFA-matching-algori.patch
new file mode 100644 (file)
index 0000000..8e06745
--- /dev/null
@@ -0,0 +1,156 @@
+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
diff --git a/utils/zsh/patches/005-51877-do-not-build-pcre-module-if-pcre2-config-is-no.patch b/utils/zsh/patches/005-51877-do-not-build-pcre-module-if-pcre2-config-is-no.patch
new file mode 100644 (file)
index 0000000..81632e7
--- /dev/null
@@ -0,0 +1,111 @@
+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